1 /*
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 #include "aidl.h"
18 
19 #include <android-base/format.h>
20 #include <android-base/stringprintf.h>
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 
24 #include <map>
25 #include <memory>
26 #include <set>
27 #include <string>
28 #include <vector>
29 
30 #include "aidl_checkapi.h"
31 #include "aidl_dumpapi.h"
32 #include "aidl_language.h"
33 #include "aidl_to_cpp.h"
34 #include "aidl_to_java.h"
35 #include "aidl_to_ndk.h"
36 #include "comments.h"
37 #include "logging.h"
38 #include "options.h"
39 #include "tests/fake_io_delegate.h"
40 
41 using android::aidl::internals::parse_preprocessed_file;
42 using android::aidl::test::FakeIoDelegate;
43 using android::base::StringPrintf;
44 using std::map;
45 using std::set;
46 using std::string;
47 using std::unique_ptr;
48 using std::vector;
49 using testing::HasSubstr;
50 using testing::TestParamInfo;
51 using testing::internal::CaptureStderr;
52 using testing::internal::GetCapturedStderr;
53 
54 namespace android {
55 namespace aidl {
56 namespace {
57 
58 const char kExpectedDepFileContents[] =
59 R"(place/for/output/p/IFoo.java : \
60   p/IFoo.aidl
61 
62 p/IFoo.aidl :
63 )";
64 
65 const char kExpectedNinjaDepFileContents[] =
66 R"(place/for/output/p/IFoo.java : \
67   p/IFoo.aidl
68 )";
69 
70 const char kExpectedParcelableDeclarationDepFileContents[] =
71     R"( : \
72   p/Foo.aidl
73 
74 p/Foo.aidl :
75 )";
76 
77 const char kExpectedStructuredParcelableDepFileContents[] =
78     R"(place/for/output/p/Foo.java : \
79   p/Foo.aidl
80 
81 p/Foo.aidl :
82 )";
83 
84 }  // namespace
85 
86 class AidlTest : public ::testing::TestWithParam<Options::Language> {
87  protected:
Parse(const string & path,const string & contents,AidlTypenames & typenames_,Options::Language lang,AidlError * error=nullptr,const vector<string> additional_arguments={})88   AidlDefinedType* Parse(const string& path, const string& contents, AidlTypenames& typenames_,
89                          Options::Language lang, AidlError* error = nullptr,
90                          const vector<string> additional_arguments = {}) {
91     io_delegate_.SetFileContents(path, contents);
92     vector<string> args;
93     args.emplace_back("aidl");
94     args.emplace_back("--lang=" + to_string(lang));
95     for (const string& s : additional_arguments) {
96       args.emplace_back(s);
97     }
98     for (const string& f : preprocessed_files_) {
99       args.emplace_back("--preprocessed=" + f);
100     }
101     for (const string& i : import_paths_) {
102       args.emplace_back("--include=" + i);
103     }
104     args.emplace_back(path);
105     Options options = Options::From(args);
106     vector<string> imported_files;
107     ImportResolver import_resolver{io_delegate_, path, import_paths_, {}};
108     AidlError actual_error = ::android::aidl::internals::load_and_validate_aidl(
109         path, options, io_delegate_, &typenames_, &imported_files);
110 
111     if (error != nullptr) {
112       *error = actual_error;
113     }
114 
115     if (actual_error != AidlError::OK) {
116       return nullptr;
117     }
118 
119     const auto& defined_types = typenames_.MainDocument().DefinedTypes();
120     EXPECT_EQ(1ul, defined_types.size());
121 
122     return defined_types.front().get();
123   }
124 
GetLanguage()125   Options::Language GetLanguage() { return GetParam(); }
126 
127   FakeIoDelegate io_delegate_;
128   vector<string> preprocessed_files_;
129   set<string> import_paths_;
130   AidlTypenames typenames_;
131 };
132 
133 // Instantiate the AidlTest parameterized suite, calling all of the TEST_P
134 // tests with each of the supported languages as a parameter.
135 INSTANTIATE_TEST_SUITE_P(AidlTestSuite, AidlTest,
136                          testing::Values(Options::Language::CPP, Options::Language::JAVA,
137                                          Options::Language::NDK, Options::Language::RUST),
__anon758595f20202(const testing::TestParamInfo<Options::Language>& info) 138                          [](const testing::TestParamInfo<Options::Language>& info) {
139                            return to_string(info.param);
140                          });
141 
TEST_P(AidlTest,AcceptMissingPackage)142 TEST_P(AidlTest, AcceptMissingPackage) {
143   EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", typenames_, GetLanguage()));
144 }
145 
TEST_P(AidlTest,EndsInSingleLineComment)146 TEST_P(AidlTest, EndsInSingleLineComment) {
147   EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { } // foo", typenames_, GetLanguage()));
148 }
149 
TEST_P(AidlTest,InterfaceRequiresCorrectPath)150 TEST_P(AidlTest, InterfaceRequiresCorrectPath) {
151   const string expected_stderr =
152       "ERROR: a/Foo.aidl:1.11-21: IBar should be declared in a file called a/IBar.aidl\n";
153   const std::string file_contents = "package a; interface IBar {}";
154   CaptureStderr();
155   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
156   EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
157 }
158 
TEST_P(AidlTest,ParcelableRequiresCorrectPath)159 TEST_P(AidlTest, ParcelableRequiresCorrectPath) {
160   const string expected_stderr =
161       "ERROR: a/Foo.aidl:1.11-21: Bar should be declared in a file called a/Bar.aidl\n";
162   const std::string file_contents = "package a; interface Bar {}";
163   CaptureStderr();
164   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
165   EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
166 }
167 
TEST_P(AidlTest,UnstructuredParcelableRequiresCorrectPath)168 TEST_P(AidlTest, UnstructuredParcelableRequiresCorrectPath) {
169   const string expected_stderr =
170       "ERROR: a/Foo.aidl:1.22-26: Bar should be declared in a file called a/Bar.aidl\n";
171   const std::string file_contents = "package a; parcelable Bar cpp_header \"anything.h\";";
172   CaptureStderr();
173   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
174   EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
175 }
176 
TEST_P(AidlTest,EnumRequiresCorrectPath)177 TEST_P(AidlTest, EnumRequiresCorrectPath) {
178   const string expected_stderr =
179       "ERROR: a/Foo.aidl:1.16-20: Bar should be declared in a file called a/Bar.aidl\n";
180   const std::string file_contents = "package a; enum Bar { A, }";
181   CaptureStderr();
182   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
183   EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
184 }
185 
TEST_P(AidlTest,RejectsArraysOfBinders)186 TEST_P(AidlTest, RejectsArraysOfBinders) {
187   import_paths_.emplace("");
188   io_delegate_.SetFileContents("bar/IBar.aidl",
189                                "package bar; interface IBar {}");
190   const string path = "foo/IFoo.aidl";
191   const string contents =
192       "package foo;\n"
193       "import bar.IBar;\n"
194       "interface IFoo { void f(in IBar[] input); }";
195   const string expected_stderr = "ERROR: foo/IFoo.aidl:3.27-32: Binder type cannot be an array\n";
196   CaptureStderr();
197   EXPECT_EQ(nullptr, Parse(path, contents, typenames_, GetLanguage()));
198   EXPECT_EQ(expected_stderr, GetCapturedStderr());
199 }
200 
TEST_P(AidlTest,SupportOnlyOutParameters)201 TEST_P(AidlTest, SupportOnlyOutParameters) {
202   const string interface_list = "package a; interface IBar { void f(out List<String> bar); }";
203   EXPECT_NE(nullptr, Parse("a/IBar.aidl", interface_list, typenames_, GetLanguage()));
204 }
205 
TEST_P(AidlTest,RejectOutParametersForIBinder)206 TEST_P(AidlTest, RejectOutParametersForIBinder) {
207   const string interface_ibinder = "package a; interface IBaz { void f(out IBinder bar); }";
208   const string expected_ibinder_stderr =
209       "ERROR: a/IBaz.aidl:1.47-51: 'bar' can't be an out parameter because IBinder can only be an "
210       "in parameter.\n";
211   CaptureStderr();
212   EXPECT_EQ(nullptr, Parse("a/IBaz.aidl", interface_ibinder, typenames_, GetLanguage()));
213   EXPECT_EQ(expected_ibinder_stderr, GetCapturedStderr());
214 }
215 
TEST_P(AidlTest,RejectsOutParametersInOnewayInterface)216 TEST_P(AidlTest, RejectsOutParametersInOnewayInterface) {
217   const string oneway_interface = "package a; oneway interface IBar { void f(out int[] bar); }";
218   const string expected_stderr =
219       "ERROR: a/IBar.aidl:1.40-42: oneway method 'f' cannot have out parameters\n";
220   CaptureStderr();
221   EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, GetLanguage()));
222   EXPECT_EQ(expected_stderr, GetCapturedStderr());
223 }
224 
TEST_P(AidlTest,RejectsOutParametersInOnewayMethod)225 TEST_P(AidlTest, RejectsOutParametersInOnewayMethod) {
226   const string oneway_method = "package a; interface IBar { oneway void f(out int[] bar); }";
227   const string expected_stderr =
228       "ERROR: a/IBar.aidl:1.40-42: oneway method 'f' cannot have out parameters\n";
229   CaptureStderr();
230   EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, typenames_, GetLanguage()));
231   EXPECT_EQ(expected_stderr, GetCapturedStderr());
232 }
233 
TEST_P(AidlTest,RejectsOnewayNonVoidReturn)234 TEST_P(AidlTest, RejectsOnewayNonVoidReturn) {
235   const string oneway_method = "package a; interface IFoo { oneway int f(); }";
236   const string expected_stderr =
237       "ERROR: a/IFoo.aidl:1.39-41: oneway method 'f' cannot return a value\n";
238   CaptureStderr();
239   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
240   EXPECT_EQ(expected_stderr, GetCapturedStderr());
241 }
242 
TEST_P(AidlTest,RejectsNullablePrimitive)243 TEST_P(AidlTest, RejectsNullablePrimitive) {
244   const string oneway_method = "package a; interface IFoo { @nullable int f(); }";
245   const string expected_stderr =
246       "ERROR: a/IFoo.aidl:1.38-42: Primitive type cannot get nullable annotation\n";
247   CaptureStderr();
248   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
249   EXPECT_EQ(expected_stderr, GetCapturedStderr());
250 }
251 
TEST_P(AidlTest,AcceptNullableList)252 TEST_P(AidlTest, AcceptNullableList) {
253   const string oneway_method = "package a; interface IFoo { @nullable List<String> f(); }";
254   const string expected_stderr = "";
255   CaptureStderr();
256   EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
257   EXPECT_EQ(expected_stderr, GetCapturedStderr());
258 }
259 
TEST_P(AidlTest,RejectsDuplicatedArgumentNames)260 TEST_P(AidlTest, RejectsDuplicatedArgumentNames) {
261   const string method = "package a; interface IFoo { void f(int a, int a); }";
262   const string expected_stderr =
263       "ERROR: a/IFoo.aidl:1.33-35: method 'f' has duplicate argument name 'a'\n";
264   CaptureStderr();
265   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage()));
266   EXPECT_EQ(expected_stderr, GetCapturedStderr());
267 }
268 
TEST_P(AidlTest,RejectsDuplicatedFieldNames)269 TEST_P(AidlTest, RejectsDuplicatedFieldNames) {
270   const string method = "package a; parcelable Foo { int a; String a; }";
271   const string expected_stderr = "ERROR: a/Foo.aidl:1.42-44: 'Foo' has duplicate field name 'a'\n";
272   CaptureStderr();
273   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
274   EXPECT_EQ(expected_stderr, GetCapturedStderr());
275 }
276 
TEST_P(AidlTest,RejectsRepeatedAnnotations)277 TEST_P(AidlTest, RejectsRepeatedAnnotations) {
278   const string method = R"(@Hide @Hide parcelable Foo {})";
279   const string expected_stderr =
280       "ERROR: Foo.aidl:1.23-27: 'Hide' is repeated, but not allowed. Previous location: "
281       "Foo.aidl:1.1-6\n";
282   CaptureStderr();
283   EXPECT_EQ(nullptr, Parse("Foo.aidl", method, typenames_, GetLanguage()));
284   EXPECT_EQ(expected_stderr, GetCapturedStderr());
285 }
286 
TEST_P(AidlTest,AcceptsEmptyParcelable)287 TEST_P(AidlTest, AcceptsEmptyParcelable) {
288   CaptureStderr();
289   EXPECT_NE(nullptr, Parse("Foo.aidl", "parcelable Foo {}", typenames_, GetLanguage()));
290   EXPECT_EQ("", GetCapturedStderr());
291 }
292 
TEST_P(AidlTest,RejectsDuplicatedAnnotationParams)293 TEST_P(AidlTest, RejectsDuplicatedAnnotationParams) {
294   const string method = "package a; interface IFoo { @UnsupportedAppUsage(foo=1, foo=2)void f(); }";
295   const string expected_stderr = "ERROR: a/IFoo.aidl:1.56-62: Trying to redefine parameter foo.\n";
296   CaptureStderr();
297   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage()));
298   EXPECT_EQ(expected_stderr, GetCapturedStderr());
299 }
300 
TEST_P(AidlTest,RejectUnsupportedInterfaceAnnotations)301 TEST_P(AidlTest, RejectUnsupportedInterfaceAnnotations) {
302   AidlError error;
303   const string method = "package a; @nullable interface IFoo { int f(); }";
304   CaptureStderr();
305   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
306   EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable is not available."));
307   EXPECT_EQ(AidlError::BAD_TYPE, error);
308 }
309 
TEST_P(AidlTest,RejectUnsupportedTypeAnnotations)310 TEST_P(AidlTest, RejectUnsupportedTypeAnnotations) {
311   AidlError error;
312   const string method = "package a; interface IFoo { @JavaOnlyStableParcelable int f(); }";
313   CaptureStderr();
314   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
315   EXPECT_THAT(GetCapturedStderr(), HasSubstr("@JavaOnlyStableParcelable is not available."));
316   EXPECT_EQ(AidlError::BAD_TYPE, error);
317 }
318 
TEST_P(AidlTest,RejectUnsupportedParcelableAnnotations)319 TEST_P(AidlTest, RejectUnsupportedParcelableAnnotations) {
320   AidlError error;
321   const string method = "package a; @nullable parcelable IFoo cpp_header \"IFoo.h\";";
322   CaptureStderr();
323   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
324   EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable is not available."));
325   EXPECT_EQ(AidlError::BAD_TYPE, error);
326 }
327 
TEST_P(AidlTest,RejectUnsupportedParcelableDefineAnnotations)328 TEST_P(AidlTest, RejectUnsupportedParcelableDefineAnnotations) {
329   AidlError error;
330   const string method = "package a; @nullable parcelable IFoo { String a; String b; }";
331   CaptureStderr();
332   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
333   EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable is not available."));
334   EXPECT_EQ(AidlError::BAD_TYPE, error);
335 }
336 
TEST_P(AidlTest,ParsesNonNullableAnnotation)337 TEST_P(AidlTest, ParsesNonNullableAnnotation) {
338   auto parse_result =
339       Parse("a/IFoo.aidl", "package a; interface IFoo { String f(); }", typenames_, GetLanguage());
340   ASSERT_NE(nullptr, parse_result);
341   const AidlInterface* interface = parse_result->AsInterface();
342   ASSERT_NE(nullptr, interface);
343   ASSERT_FALSE(interface->GetMethods().empty());
344   EXPECT_FALSE(interface->GetMethods()[0]->GetType().IsNullable());
345 }
346 
TEST_P(AidlTest,ParsesNullableAnnotation)347 TEST_P(AidlTest, ParsesNullableAnnotation) {
348   auto parse_result = Parse("a/IFoo.aidl", "package a; interface IFoo { @nullable String f(); }",
349                             typenames_, GetLanguage());
350   ASSERT_NE(nullptr, parse_result);
351   const AidlInterface* interface = parse_result->AsInterface();
352   ASSERT_NE(nullptr, interface);
353   ASSERT_FALSE(interface->GetMethods().empty());
354   EXPECT_TRUE(interface->GetMethods()[0]->GetType().IsNullable());
355 }
356 
TEST_P(AidlTest,ParsesNonUtf8Annotations)357 TEST_P(AidlTest, ParsesNonUtf8Annotations) {
358   auto parse_result =
359       Parse("a/IFoo.aidl", "package a; interface IFoo { String f(); }", typenames_, GetLanguage());
360   ASSERT_NE(nullptr, parse_result);
361   const AidlInterface* interface = parse_result->AsInterface();
362   ASSERT_NE(nullptr, interface);
363   ASSERT_FALSE(interface->GetMethods().empty());
364   EXPECT_FALSE(interface->GetMethods()[0]->GetType().IsUtf8InCpp());
365 }
366 
TEST_P(AidlTest,ParsesUtf8Annotations)367 TEST_P(AidlTest, ParsesUtf8Annotations) {
368   auto parse_result = Parse("a/IFoo.aidl", "package a; interface IFoo { @utf8InCpp String f(); }",
369                             typenames_, GetLanguage());
370   ASSERT_NE(nullptr, parse_result);
371   const AidlInterface* interface = parse_result->AsInterface();
372   ASSERT_NE(nullptr, interface);
373   ASSERT_FALSE(interface->GetMethods().empty());
374   EXPECT_TRUE(interface->GetMethods()[0]->GetType().IsUtf8InCpp());
375 }
376 
TEST_P(AidlTest,VintfRequiresStructuredAndStability)377 TEST_P(AidlTest, VintfRequiresStructuredAndStability) {
378   AidlError error;
379   const string expected_stderr =
380       "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface 'stability: "
381       "\"vintf\"'\n"
382       "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface "
383       "--structured\n";
384   CaptureStderr();
385   ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
386                            GetLanguage(), &error));
387   EXPECT_EQ(expected_stderr, GetCapturedStderr());
388   ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
389 }
390 
TEST_P(AidlTest,VintfRequiresStructured)391 TEST_P(AidlTest, VintfRequiresStructured) {
392   AidlError error;
393   const string expected_stderr =
394       "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface "
395       "--structured\n";
396   CaptureStderr();
397   ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
398                            GetLanguage(), &error, {"--stability", "vintf"}));
399   EXPECT_EQ(expected_stderr, GetCapturedStderr());
400   ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
401 }
402 
TEST_P(AidlTest,VintfRequiresSpecifiedStability)403 TEST_P(AidlTest, VintfRequiresSpecifiedStability) {
404   AidlError error;
405   const string expected_stderr =
406       "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface 'stability: "
407       "\"vintf\"'\n";
408   CaptureStderr();
409   ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
410                            GetLanguage(), &error, {"--structured"}));
411   EXPECT_EQ(expected_stderr, GetCapturedStderr());
412   ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
413 }
414 
TEST_P(AidlTest,ParsesStabilityAnnotations)415 TEST_P(AidlTest, ParsesStabilityAnnotations) {
416   AidlError error;
417   auto parse_result = Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
418                             GetLanguage(), &error, {"--structured", "--stability", "vintf"});
419   ASSERT_EQ(AidlError::OK, error);
420   ASSERT_NE(nullptr, parse_result);
421   const AidlInterface* interface = parse_result->AsInterface();
422   ASSERT_NE(nullptr, interface);
423   ASSERT_TRUE(interface->IsVintfStability());
424 }
425 
TEST_F(AidlTest,ParsesJavaOnlyStableParcelable)426 TEST_F(AidlTest, ParsesJavaOnlyStableParcelable) {
427   Options java_options = Options::From("aidl -o out --structured a/Foo.aidl");
428   Options cpp_options = Options::From("aidl --lang=cpp -o out -h out/include a/Foo.aidl");
429   Options cpp_structured_options =
430       Options::From("aidl --lang=cpp --structured -o out -h out/include a/Foo.aidl");
431   Options rust_options = Options::From("aidl --lang=rust -o out --structured a/Foo.aidl");
432   io_delegate_.SetFileContents(
433       "a/Foo.aidl",
434       StringPrintf("package a; @JavaOnlyStableParcelable parcelable Foo cpp_header \"Foo.h\" ;"));
435 
436   EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
437   EXPECT_EQ(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
438   const string expected_stderr =
439       "ERROR: a/Foo.aidl:1.48-52: Cannot declared parcelable in a --structured interface. "
440       "Parcelable must be defined in AIDL directly.\n";
441   CaptureStderr();
442   EXPECT_NE(0, ::android::aidl::compile_aidl(cpp_structured_options, io_delegate_));
443   EXPECT_EQ(expected_stderr, GetCapturedStderr());
444 
445   CaptureStderr();
446   EXPECT_NE(0, ::android::aidl::compile_aidl(rust_options, io_delegate_));
447   EXPECT_EQ(expected_stderr, GetCapturedStderr());
448 }
449 
TEST_F(AidlTest,ParcelableSupportJavaDeriveToString)450 TEST_F(AidlTest, ParcelableSupportJavaDeriveToString) {
451   io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
452     @JavaDerive(toString=true) parcelable Foo { int a; float b; })");
453   Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
454   EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
455 
456   string java_out;
457   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
458   EXPECT_THAT(java_out, testing::HasSubstr("public String toString() {"));
459 
460   // Other backends shouldn't be bothered
461   Options cpp_options = Options::From("aidl --lang=cpp -o out -h out a/Foo.aidl");
462   EXPECT_EQ(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
463 
464   Options ndk_options = Options::From("aidl --lang=ndk -o out -h out a/Foo.aidl");
465   EXPECT_EQ(0, ::android::aidl::compile_aidl(ndk_options, io_delegate_));
466 }
467 
TEST_F(AidlTest,UnionSupportJavaDeriveToString)468 TEST_F(AidlTest, UnionSupportJavaDeriveToString) {
469   io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
470     @JavaDerive(toString=true) union Foo { int a; int[] b; })");
471   CaptureStderr();
472   Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
473   EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
474   EXPECT_EQ("", GetCapturedStderr());
475 
476   const string expected_to_string_method = R"--(
477   @Override
478   public String toString() {
479     switch (_tag) {
480     case a: return "a.Foo.a(" + (getA()) + ")";
481     case b: return "a.Foo.b(" + (java.util.Arrays.toString(getB())) + ")";
482     }
483     throw new IllegalStateException("unknown field: " + _tag);
484   }
485 )--";
486 
487   string java_out;
488   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
489   EXPECT_THAT(java_out, testing::HasSubstr(expected_to_string_method));
490 }
491 
TEST_F(AidlTest,ParcelableSupportJavaDeriveEquals)492 TEST_F(AidlTest, ParcelableSupportJavaDeriveEquals) {
493   io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
494     @JavaDerive(equals=true) parcelable Foo { int a; float b; })");
495   CaptureStderr();
496   Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
497   EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
498   EXPECT_EQ("", GetCapturedStderr());
499 
500   const std::string expected = R"--(
501   @Override
502   public boolean equals(Object other) {
503     if (this == other) return true;
504     if (other == null) return false;
505     if (!(other instanceof Foo)) return false;
506     Foo that = (Foo)other;
507     if (!java.util.Objects.deepEquals(a, that.a)) return false;
508     if (!java.util.Objects.deepEquals(b, that.b)) return false;
509     return true;
510   }
511 
512   @Override
513   public int hashCode() {
514     return java.util.Arrays.deepHashCode(java.util.Arrays.asList(a, b).toArray());
515   }
516 )--";
517 
518   string java_out;
519   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
520   EXPECT_THAT(java_out, testing::HasSubstr(expected));
521 }
522 
TEST_F(AidlTest,UnionSupportJavaDeriveEquals)523 TEST_F(AidlTest, UnionSupportJavaDeriveEquals) {
524   io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
525     @JavaDerive(equals=true) union Foo { int a; int[] b; })");
526   CaptureStderr();
527   Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
528   EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
529   EXPECT_EQ("", GetCapturedStderr());
530 
531   const std::string expected = R"--(
532   @Override
533   public boolean equals(Object other) {
534     if (this == other) return true;
535     if (other == null) return false;
536     if (!(other instanceof Foo)) return false;
537     Foo that = (Foo)other;
538     if (_tag != that._tag) return false;
539     if (!java.util.Objects.deepEquals(_value, that._value)) return false;
540     return true;
541   }
542 
543   @Override
544   public int hashCode() {
545     return java.util.Arrays.deepHashCode(java.util.Arrays.asList(_tag, _value).toArray());
546   }
547 )--";
548 
549   string java_out;
550   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
551   EXPECT_THAT(java_out, testing::HasSubstr(expected));
552 }
553 
TEST_F(AidlTest,RejectsJavaDeriveAnnotation)554 TEST_F(AidlTest, RejectsJavaDeriveAnnotation) {
555   {
556     io_delegate_.SetFileContents("a/Foo.aidl",
557                                  "package a; @JavaDerive(blah=true) parcelable Foo{}");
558     Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
559     CaptureStderr();
560     EXPECT_NE(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
561     const std::string expected_stderr =
562         "ERROR: a/Foo.aidl:1.11-34: Parameter blah not supported for annotation JavaDerive.";
563     EXPECT_THAT(GetCapturedStderr(),
564                 HasSubstr("Parameter blah not supported for annotation JavaDerive."));
565   }
566 
567   {
568     io_delegate_.SetFileContents("a/IFoo.aidl", "package a; @JavaDerive interface IFoo{}");
569     Options java_options = Options::From("aidl --lang=java -o out a/IFoo.aidl");
570     CaptureStderr();
571     EXPECT_NE(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
572     EXPECT_THAT(GetCapturedStderr(), HasSubstr("@JavaDerive is not available."));
573   }
574 
575   {
576     io_delegate_.SetFileContents("a/IFoo.aidl", "package a; @JavaDerive enum IFoo { A=1, }");
577     Options java_options = Options::From("aidl --lang=java -o out a/IFoo.aidl");
578     CaptureStderr();
579     EXPECT_NE(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
580     EXPECT_THAT(GetCapturedStderr(), HasSubstr("@JavaDerive is not available."));
581   }
582 }
583 
TEST_P(AidlTest,ParseDescriptorAnnotation)584 TEST_P(AidlTest, ParseDescriptorAnnotation) {
585   AidlError error;
586   auto parse_result = Parse("IFoo.aidl", R"(@Descriptor(value="IBar") interface IFoo{})",
587                             typenames_, GetLanguage(), &error, {"--structured"});
588   ASSERT_EQ(AidlError::OK, error);
589   ASSERT_NE(nullptr, parse_result);
590   const AidlInterface* interface = parse_result->AsInterface();
591   ASSERT_NE(nullptr, interface);
592   ASSERT_EQ("IBar", interface->GetDescriptor());
593 }
594 
TEST_P(AidlTest,AcceptsOnewayMethod)595 TEST_P(AidlTest, AcceptsOnewayMethod) {
596   const string oneway_method = "package a; interface IFoo { oneway void f(int a); }";
597   EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
598 }
599 
TEST_P(AidlTest,AcceptsOnewayInterface)600 TEST_P(AidlTest, AcceptsOnewayInterface) {
601   const string oneway_interface = "package a; oneway interface IBar { void f(int a); }";
602   EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, GetLanguage()));
603 }
604 
TEST_P(AidlTest,AcceptsAnnotatedOnewayMethod)605 TEST_P(AidlTest, AcceptsAnnotatedOnewayMethod) {
606   const string oneway_method =
607       "package a; interface IFoo { @UnsupportedAppUsage oneway void f(int a); }";
608   EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
609 }
610 
TEST_P(AidlTest,AnnotationsInMultiplePlaces)611 TEST_P(AidlTest, AnnotationsInMultiplePlaces) {
612   const string oneway_method =
613       "package a; interface IFoo { @UnsupportedAppUsage oneway @Hide void f(int a); }";
614   const AidlDefinedType* defined = Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage());
615   ASSERT_NE(nullptr, defined);
616   const AidlInterface* iface = defined->AsInterface();
617   ASSERT_NE(nullptr, iface);
618 
619   const auto& methods = iface->GetMethods();
620   ASSERT_EQ(1u, methods.size());
621   const auto& method = methods[0];
622   const AidlTypeSpecifier& ret_type = method->GetType();
623 
624   // TODO(b/151102494): these annotations should be on the method
625   ASSERT_NE(nullptr, ret_type.UnsupportedAppUsage());
626   ASSERT_TRUE(ret_type.IsHide());
627 }
628 
TEST_P(AidlTest,WritesComments)629 TEST_P(AidlTest, WritesComments) {
630   string foo_interface =
631       R"(package a;
632         /* foo */
633         interface IFoo {
634           /* i */
635           int i();
636           // j
637           @nullable String j();
638           // k1
639           /* k2 */
640           @UnsupportedAppUsage oneway void k(int a);
641         })";
642 
643   CaptureStderr();
644   auto parse_result = Parse("a/IFoo.aidl", foo_interface, typenames_, GetLanguage());
645   EXPECT_NE(nullptr, parse_result);
646   EXPECT_EQ("", GetCapturedStderr());
647 
648   EXPECT_EQ((Comments{{"/* foo */"}}), parse_result->GetComments());
649 
650   const AidlInterface* interface = parse_result->AsInterface();
651   EXPECT_EQ((Comments{{"/* i */"}}), interface->GetMethods()[0]->GetComments());
652   EXPECT_EQ((Comments{{"// j\n"}}), interface->GetMethods()[1]->GetComments());
653   EXPECT_EQ((Comments{{"// k1\n"}, {"/* k2 */"}}), interface->GetMethods()[2]->GetComments());
654 }
655 
TEST_P(AidlTest,CppHeaderCanBeIdentifierAsWell)656 TEST_P(AidlTest, CppHeaderCanBeIdentifierAsWell) {
657   io_delegate_.SetFileContents("p/cpp_header.aidl",
658                                R"(package p;
659          parcelable cpp_header cpp_header "bar/header";)");
660   import_paths_.emplace("");
661   const string input_path = "p/IFoo.aidl";
662   const string input = R"(package p;
663                           import p.cpp_header;
664                           interface IFoo {
665                             // get bar
666                             cpp_header get();
667                           })";
668 
669   auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
670   EXPECT_NE(nullptr, parse_result);
671   const AidlInterface* interface = parse_result->AsInterface();
672   EXPECT_EQ((Comments{{"// get bar\n"}}), interface->GetMethods()[0]->GetComments());
673 }
674 
TEST_F(AidlTest,ParsesPreprocessedFile)675 TEST_F(AidlTest, ParsesPreprocessedFile) {
676   string simple_content = "parcelable a.Foo;\ninterface b.IBar;";
677   io_delegate_.SetFileContents("path", simple_content);
678   EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").is_resolved);
679   EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &typenames_));
680   EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").is_resolved);
681   EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").is_resolved);
682 }
683 
TEST_F(AidlTest,ParsesPreprocessedFileWithWhitespace)684 TEST_F(AidlTest, ParsesPreprocessedFileWithWhitespace) {
685   string simple_content = "parcelable    a.Foo;\n  interface b.IBar  ;\t";
686   io_delegate_.SetFileContents("path", simple_content);
687 
688   EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").is_resolved);
689   EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &typenames_));
690   EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").is_resolved);
691   EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").is_resolved);
692 }
693 
TEST_P(AidlTest,PreferImportToPreprocessed)694 TEST_P(AidlTest, PreferImportToPreprocessed) {
695   io_delegate_.SetFileContents("preprocessed", "interface another.IBar;");
696   io_delegate_.SetFileContents("one/IBar.aidl", "package one; "
697                                                 "interface IBar {}");
698   preprocessed_files_.push_back("preprocessed");
699   import_paths_.emplace("");
700   auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
701                             typenames_, GetLanguage());
702   EXPECT_NE(nullptr, parse_result);
703 
704   // We expect to know about both kinds of IBar
705   EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
706   EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
707   // But if we request just "IBar" we should get our imported one.
708   AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", false, nullptr, {});
709   ambiguous_type.Resolve(typenames_);
710   EXPECT_EQ("one.IBar", ambiguous_type.GetName());
711 }
712 
713 // Special case of PreferImportToPreprocessed. Imported type should be preferred
714 // even when the preprocessed file already has the same type.
TEST_P(AidlTest,B147918827)715 TEST_P(AidlTest, B147918827) {
716   io_delegate_.SetFileContents("preprocessed", "interface another.IBar;\ninterface one.IBar;");
717   io_delegate_.SetFileContents("one/IBar.aidl",
718                                "package one; "
719                                "interface IBar {}");
720   preprocessed_files_.push_back("preprocessed");
721   import_paths_.emplace("");
722   auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
723                             typenames_, GetLanguage());
724   EXPECT_NE(nullptr, parse_result);
725 
726   // We expect to know about both kinds of IBar
727   EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
728   EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
729   // But if we request just "IBar" we should get our imported one.
730   AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", false, nullptr, {});
731   ambiguous_type.Resolve(typenames_);
732   EXPECT_EQ("one.IBar", ambiguous_type.GetName());
733 }
734 
TEST_F(AidlTest,WritePreprocessedFile)735 TEST_F(AidlTest, WritePreprocessedFile) {
736   io_delegate_.SetFileContents("p/Outer.aidl",
737                                "package p; parcelable Outer.Inner;");
738   io_delegate_.SetFileContents("one/IBar.aidl", "package one; import p.Outer;"
739                                                 "interface IBar {}");
740 
741   vector<string> args {
742     "aidl",
743     "--preprocess",
744     "preprocessed",
745     "p/Outer.aidl",
746     "one/IBar.aidl"};
747   Options options = Options::From(args);
748   EXPECT_TRUE(::android::aidl::preprocess_aidl(options, io_delegate_));
749 
750   string output;
751   EXPECT_TRUE(io_delegate_.GetWrittenContents("preprocessed", &output));
752   EXPECT_EQ("parcelable p.Outer.Inner;\ninterface one.IBar;\n", output);
753 }
754 
TEST_P(AidlTest,SupportDeprecated)755 TEST_P(AidlTest, SupportDeprecated) {
756   struct TestCase {
757     std::string output_file;
758     std::string annotation;
759   };
760 
761   auto CheckDeprecated = [&](const std::string& filename, const std::string& contents,
762                              std::vector<std::pair<Options::Language, TestCase>> expectations) {
763     io_delegate_.SetFileContents(filename, contents);
764 
765     auto options = Options::From("aidl --lang=" + to_string(GetLanguage()) + " " + filename +
766                                  " --out=out --header_out=out");
767     EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
768     for (const auto& [lang, test_case] : expectations) {
769       if (lang != GetLanguage()) continue;
770       string output;
771       EXPECT_TRUE(io_delegate_.GetWrittenContents(test_case.output_file, &output));
772       EXPECT_THAT(output, HasSubstr(test_case.annotation));
773     }
774   };
775 
776   // Emit escaped string for notes
777   CheckDeprecated(
778       "IFoo.aidl",
779       R"(interface IFoo {
780            /**
781             * @note asdf
782             * @deprecated a really long deprecation message
783             *
784             *    which is really long
785             * @param foo bar
786             */
787            List<String> foo();
788         })",
789       {
790           {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
791           {Options::Language::CPP,
792            {"out/IFoo.h",
793             R"(__attribute__((deprecated("a really long deprecation message which is really long"))))"}},
794           {Options::Language::NDK,
795            {"out/aidl/IFoo.h",
796             R"(__attribute__((deprecated("a really long deprecation message which is really long"))))"}},
797           {Options::Language::RUST,
798            {"out/IFoo.rs",
799             R"(#[deprecated = "a really long deprecation message which is really long"])"}},
800       });
801 
802   // In AIDL @deprecated can be in block comments as well as javadoc style
803   CheckDeprecated(
804       "IFoo.aidl",
805       "interface IFoo {\n"
806       "  /* @deprecated use bar() */\n"
807       "  List<String> foo();\n"
808       "}",
809       {
810           {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
811           {Options::Language::JAVA, {"out/IFoo.java", "/** @deprecated use bar() */"}},
812           {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated(\"use bar()\")))"}},
813           {Options::Language::NDK,
814            {"out/aidl/IFoo.h", "__attribute__((deprecated(\"use bar()\")))"}},
815           {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated = \"use bar()\"]"}},
816       });
817 
818   // but not in line comments
819   auto parsed = Parse("IFoo.aidl", "// @deprecated\ninterface IFoo {}", typenames_, GetLanguage());
820   EXPECT_FALSE(parsed->IsDeprecated());
821 
822   // parcelable
823   CheckDeprecated("Foo.aidl",
824                   "parcelable Foo {\n"
825                   "  /** @deprecated use bar*/\n"
826                   "  int foo = 0;\n"
827                   "}",
828                   {
829                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
830                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
831                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
832                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
833                   });
834 
835   // interface constants
836   CheckDeprecated("IFoo.aidl",
837                   "interface IFoo {\n"
838                   "  /** @deprecated use bar*/\n"
839                   "  const int FOO = 0;\n"
840                   "}",
841                   {
842                       {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
843                       {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
844                       {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
845                       {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
846                   });
847 
848   // union fields
849   CheckDeprecated("Foo.aidl",
850                   "union Foo {\n"
851                   "  int bar = 0;\n"
852                   "  /** @deprecated use bar*/\n"
853                   "  int foo;\n"
854                   "}",
855                   {
856                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
857                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
858                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
859                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
860                   });
861 
862   CheckDeprecated("Foo.aidl",
863                   "/** @deprecated use Bar */\n"
864                   "parcelable Foo {}",
865                   {
866                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
867                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
868                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
869                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
870                   });
871 
872   CheckDeprecated("Foo.aidl",
873                   "/** @deprecated use Bar */\n"
874                   "union Foo { int foo = 0; }",
875                   {
876                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
877                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
878                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
879                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
880                   });
881 
882   CheckDeprecated("IFoo.aidl",
883                   "/** @deprecated use IBar */\n"
884                   "interface IFoo {}",
885                   {
886                       {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
887                       {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
888                       {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
889                       {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
890                   });
891 
892   CheckDeprecated("Foo.aidl",
893                   "/** @deprecated use IBar */\n"
894                   "enum Foo { FOO }",
895                   {
896                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
897                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
898                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
899                       // TODO(b/177860423) support "deprecated" in Rust enum
900                       // {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
901                   });
902 }
903 
TEST_P(AidlTest,RequireOuterClass)904 TEST_P(AidlTest, RequireOuterClass) {
905   const string expected_stderr = "ERROR: p/IFoo.aidl:1.54-60: Failed to resolve 'Inner'\n";
906   io_delegate_.SetFileContents("p/Outer.aidl",
907                                "package p; parcelable Outer.Inner;");
908   import_paths_.emplace("");
909   CaptureStderr();
910   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
911                            "package p; import p.Outer; interface IFoo { void f(in Inner c); }",
912                            typenames_, GetLanguage()));
913   EXPECT_EQ(expected_stderr, GetCapturedStderr());
914 }
915 
TEST_P(AidlTest,ParseCompoundParcelableFromPreprocess)916 TEST_P(AidlTest, ParseCompoundParcelableFromPreprocess) {
917   io_delegate_.SetFileContents("preprocessed",
918                                "parcelable p.Outer.Inner;");
919   preprocessed_files_.push_back("preprocessed");
920   auto parse_result = Parse("p/IFoo.aidl", "package p; interface IFoo { void f(in Inner c); }",
921                             typenames_, GetLanguage());
922   // TODO(wiley): This should actually return nullptr because we require
923   //              the outer class name.  However, for legacy reasons,
924   //              this behavior must be maintained.  b/17415692
925   EXPECT_NE(nullptr, parse_result);
926 }
927 
TEST_F(AidlTest,FailOnParcelable)928 TEST_F(AidlTest, FailOnParcelable) {
929   const string expected_foo_stderr =
930       "ERROR: p/IFoo.aidl:1.22-27: Refusing to generate code with unstructured parcelables. "
931       "Declared parcelables should be in their own file and/or cannot be used with --structured "
932       "interfaces.\n";
933   io_delegate_.SetFileContents("p/IFoo.aidl", "package p; parcelable IFoo;");
934 
935   // By default, we shouldn't fail on parcelable.
936   Options options1 = Options::From("aidl p/IFoo.aidl");
937   CaptureStderr();
938   EXPECT_EQ(0, ::android::aidl::compile_aidl(options1, io_delegate_));
939   EXPECT_EQ("", GetCapturedStderr());
940 
941   // -b considers this an error
942   Options options2 = Options::From("aidl -b p/IFoo.aidl");
943   CaptureStderr();
944   EXPECT_NE(0, ::android::aidl::compile_aidl(options2, io_delegate_));
945   EXPECT_EQ(expected_foo_stderr, GetCapturedStderr());
946 
947   const string expected_bar_stderr =
948       "ERROR: p/IBar.aidl:1.22-26: Refusing to generate code with unstructured parcelables. "
949       "Declared parcelables should be in their own file and/or cannot be used with --structured "
950       "interfaces.\n";
951   io_delegate_.SetFileContents("p/IBar.aidl", "package p; parcelable Foo; interface IBar{}");
952 
953   // With '-b' option, a parcelable and an interface should fail.
954   Options options3 = Options::From("aidl p/IBar.aidl");
955   CaptureStderr();
956   EXPECT_EQ(0, ::android::aidl::compile_aidl(options3, io_delegate_));
957   EXPECT_EQ("", GetCapturedStderr());
958   Options options4 = Options::From("aidl -b p/IBar.aidl");
959   CaptureStderr();
960   EXPECT_NE(0, ::android::aidl::compile_aidl(options4, io_delegate_));
961   EXPECT_EQ(expected_bar_stderr, GetCapturedStderr());
962 }
963 
TEST_P(AidlTest,StructuredFailOnUnstructuredParcelable)964 TEST_P(AidlTest, StructuredFailOnUnstructuredParcelable) {
965   const string expected_stderr =
966       "ERROR: ./o/WhoKnowsWhat.aidl:1.22-35: o.WhoKnowsWhat is not structured, but this is a "
967       "structured interface.\n";
968   io_delegate_.SetFileContents("o/WhoKnowsWhat.aidl", "package o; parcelable WhoKnowsWhat;");
969   import_paths_.emplace("");
970   AidlError error;
971   CaptureStderr();
972   EXPECT_EQ(
973       nullptr,
974       Parse("p/IFoo.aidl",
975             "package p; import o.WhoKnowsWhat; interface IFoo { void f(in WhoKnowsWhat thisIs); }",
976             typenames_, GetLanguage(), &error, {"--structured"}));
977   EXPECT_EQ(expected_stderr, GetCapturedStderr());
978   EXPECT_EQ(AidlError::NOT_STRUCTURED, error);
979 }
980 
TEST_P(AidlTest,FailOnDuplicateConstantNames)981 TEST_P(AidlTest, FailOnDuplicateConstantNames) {
982   AidlError error;
983   const string expected_stderr =
984       "ERROR: p/IFoo.aidl:4.34-45: Found duplicate constant name 'DUPLICATED'\n";
985   CaptureStderr();
986   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
987                            R"(package p;
988                       interface IFoo {
989                         const String DUPLICATED = "d";
990                         const int DUPLICATED = 1;
991                       }
992                    )",
993                            typenames_, GetLanguage(), &error));
994   EXPECT_EQ(expected_stderr, GetCapturedStderr());
995   EXPECT_EQ(AidlError::BAD_TYPE, error);
996 }
997 
TEST_P(AidlTest,FailOnTooBigConstant)998 TEST_P(AidlTest, FailOnTooBigConstant) {
999   AidlError error;
1000   const string expected_stderr =
1001       "ERROR: p/IFoo.aidl:3.48-52: Invalid type specifier for an int32 literal: byte\n";
1002   CaptureStderr();
1003   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1004                            R"(package p;
1005                       interface IFoo {
1006                         const byte type2small = 256;
1007                       }
1008                    )",
1009                            typenames_, GetLanguage(), &error));
1010   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1011   EXPECT_EQ(AidlError::BAD_TYPE, error);
1012 }
1013 
TEST_F(AidlTest,BoolConstantsEvaluatesToIntegers)1014 TEST_F(AidlTest, BoolConstantsEvaluatesToIntegers) {
1015   io_delegate_.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { const int y = true; }");
1016   CaptureStderr();
1017   auto options = Options::From("aidl --lang java -o out a/Foo.aidl");
1018   EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
1019   EXPECT_EQ("", GetCapturedStderr());
1020   string code;
1021   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
1022   EXPECT_THAT(code, testing::HasSubstr("public static final int y = 1;"));
1023 }
1024 
TEST_F(AidlTest,AidlConstantValue_EvaluatedValue)1025 TEST_F(AidlTest, AidlConstantValue_EvaluatedValue) {
1026   using Ptr = unique_ptr<AidlConstantValue>;
1027   const AidlLocation& loc = AIDL_LOCATION_HERE;
1028 
1029   EXPECT_EQ('c', Ptr(AidlConstantValue::Character(loc, "'c'"))->EvaluatedValue<char16_t>());
1030   EXPECT_EQ("abc", Ptr(AidlConstantValue::String(loc, "\"abc\""))->EvaluatedValue<string>());
1031   EXPECT_FLOAT_EQ(1.0f, Ptr(AidlConstantValue::Floating(loc, "1.0f"))->EvaluatedValue<float>());
1032   EXPECT_EQ(true, Ptr(AidlConstantValue::Boolean(loc, true))->EvaluatedValue<bool>());
1033 
1034   AidlBinaryConstExpression one_plus_one(loc, Ptr(AidlConstantValue::Integral(loc, "1")), "+",
1035                                          Ptr(AidlConstantValue::Integral(loc, "1")));
1036   EXPECT_EQ(2, one_plus_one.EvaluatedValue<int32_t>());
1037 
1038   auto values = unique_ptr<vector<Ptr>>{new vector<Ptr>};
1039   values->emplace_back(AidlConstantValue::String(loc, "\"hello\""));
1040   values->emplace_back(AidlConstantValue::String(loc, "\"world\""));
1041   vector<string> expected{"hello", "world"};
1042   EXPECT_EQ(
1043       expected,
1044       Ptr(AidlConstantValue::Array(loc, std::move(values)))->EvaluatedValue<vector<string>>());
1045 }
1046 
TEST_F(AidlTest,AidlConstantCharacterDefault)1047 TEST_F(AidlTest, AidlConstantCharacterDefault) {
1048   AidlTypeSpecifier char_type(AIDL_LOCATION_HERE, "char", false, nullptr, {});
1049   auto default_value = unique_ptr<AidlConstantValue>(AidlConstantValue::Default(char_type));
1050   EXPECT_EQ("'\\0'", default_value->ValueString(char_type, cpp::ConstantValueDecorator));
1051   EXPECT_EQ("'\\0'", default_value->ValueString(char_type, ndk::ConstantValueDecorator));
1052   EXPECT_EQ("'\\0'", default_value->ValueString(char_type, java::ConstantValueDecorator));
1053 }
1054 
TEST_P(AidlTest,FailOnManyDefinedTypes)1055 TEST_P(AidlTest, FailOnManyDefinedTypes) {
1056   AidlError error;
1057   const string expected_stderr =
1058       "ERROR: p/IFoo.aidl:3.33-38: You must declare only one type per file.\n";
1059   CaptureStderr();
1060   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1061                            R"(package p;
1062                       interface IFoo {}
1063                       parcelable IBar {}
1064                       parcelable StructuredParcelable {}
1065                       interface IBaz {}
1066                   )",
1067                            typenames_, GetLanguage(), &error));
1068   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1069   // Parse success is important for clear error handling even if the cases aren't
1070   // actually supported in code generation.
1071   EXPECT_EQ(AidlError::BAD_TYPE, error);
1072 }
1073 
TEST_P(AidlTest,FailOnNoDefinedTypes)1074 TEST_P(AidlTest, FailOnNoDefinedTypes) {
1075   AidlError error;
1076   const string expected_stderr = "ERROR: p/IFoo.aidl:1.11-11: syntax error, unexpected $end\n";
1077   CaptureStderr();
1078   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p;)", typenames_, GetLanguage(), &error));
1079   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1080   EXPECT_EQ(AidlError::PARSE_ERROR, error);
1081 }
1082 
TEST_P(AidlTest,FailOnEmptyListWithComma)1083 TEST_P(AidlTest, FailOnEmptyListWithComma) {
1084   AidlError error;
1085   const string expected_stderr =
1086       "ERROR: p/Foo.aidl:1.45-47: syntax error, unexpected ',', expecting '}'\n";
1087   CaptureStderr();
1088   EXPECT_EQ(nullptr, Parse("p/Foo.aidl", R"(package p; parcelable Foo { uint64_t[] a = { , }; })",
1089                            typenames_, GetLanguage(), &error));
1090   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1091   EXPECT_EQ(AidlError::PARSE_ERROR, error);
1092 }
1093 
TEST_P(AidlTest,FailOnMalformedConstHexValue)1094 TEST_P(AidlTest, FailOnMalformedConstHexValue) {
1095   AidlError error;
1096   const string expected_stderr =
1097       "ERROR: p/IFoo.aidl:3.50-71: Could not parse hexvalue: 0xffffffffffffffffff\n";
1098   CaptureStderr();
1099   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1100                            R"(package p;
1101                       interface IFoo {
1102                         const int BAD_HEX_VALUE = 0xffffffffffffffffff;
1103                       }
1104                    )",
1105                            typenames_, GetLanguage(), &error));
1106   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1107   EXPECT_EQ(AidlError::PARSE_ERROR, error);
1108 }
1109 
TEST_P(AidlTest,FailOnMalformedQualifiedNameAsIdentifier)1110 TEST_P(AidlTest, FailOnMalformedQualifiedNameAsIdentifier) {
1111   AidlError error;
1112   const string expected_stderr =
1113       "ERROR: p/IFoo.aidl:1.25-26: syntax error, unexpected ';', expecting identifier or "
1114       "cpp_header (which can also be used as an identifier)\n";
1115   CaptureStderr();
1116   // Notice the trailing dot(.) in the name, which isn't a correct name
1117   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p; parcelable A.; )", typenames_,
1118                            GetLanguage(), &error));
1119   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1120   EXPECT_EQ(AidlError::PARSE_ERROR, error);
1121 }
1122 
TEST_P(AidlTest,FailOnMalformedQualifiedNameAsPackage)1123 TEST_P(AidlTest, FailOnMalformedQualifiedNameAsPackage) {
1124   AidlError error;
1125   const string expected_stderr =
1126       "ERROR: p/IFoo.aidl:1.11-12: syntax error, unexpected ';', expecting identifier or "
1127       "cpp_header (which can also be used as an identifier)\n";
1128   CaptureStderr();
1129   // Notice the trailing dot(.) in the package name
1130   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p.; parcelable A; )", typenames_,
1131                            GetLanguage(), &error));
1132   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1133   EXPECT_EQ(AidlError::PARSE_ERROR, error);
1134 }
1135 
TEST_P(AidlTest,ParsePositiveConstHexValue)1136 TEST_P(AidlTest, ParsePositiveConstHexValue) {
1137   AidlError error;
1138   auto parse_result = Parse("p/IFoo.aidl",
1139                             R"(package p;
1140               interface IFoo {
1141                 const int POSITIVE_HEX_VALUE = 0xf5;
1142               }
1143            )",
1144                             typenames_, GetLanguage(), &error);
1145   EXPECT_NE(nullptr, parse_result);
1146   const AidlInterface* interface = parse_result->AsInterface();
1147   ASSERT_NE(nullptr, interface);
1148   const auto& cpp_constants = interface->GetConstantDeclarations();
1149   EXPECT_EQ((size_t)1, cpp_constants.size());
1150   EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_constants[0]->GetName());
1151   EXPECT_TRUE(cpp_constants[0]->CheckValid(typenames_));
1152   EXPECT_EQ("245", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
1153 }
1154 
TEST_P(AidlTest,ParseNegativeConstHexValue)1155 TEST_P(AidlTest, ParseNegativeConstHexValue) {
1156   AidlError error;
1157   auto parse_result = Parse("p/IFoo.aidl",
1158                             R"(package p;
1159               interface IFoo {
1160                 const int NEGATIVE_HEX_VALUE = 0xffffffff;
1161               }
1162            )",
1163                             typenames_, GetLanguage(), &error);
1164   ASSERT_NE(nullptr, parse_result);
1165   const AidlInterface* interface = parse_result->AsInterface();
1166   ASSERT_NE(nullptr, interface);
1167   const auto& cpp_constants = interface->GetConstantDeclarations();
1168   EXPECT_EQ((size_t)1, cpp_constants.size());
1169   EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_constants[0]->GetName());
1170   EXPECT_EQ(true, cpp_constants[0]->CheckValid(typenames_));
1171   EXPECT_EQ("-1", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
1172 }
1173 
TEST_P(AidlTest,UnderstandsNestedParcelables)1174 TEST_P(AidlTest, UnderstandsNestedParcelables) {
1175   io_delegate_.SetFileContents(
1176       "p/Outer.aidl",
1177       "package p; parcelable Outer.Inner cpp_header \"baz/header\";");
1178   import_paths_.emplace("");
1179   const string input_path = "p/IFoo.aidl";
1180   const string input = "package p; import p.Outer; interface IFoo"
1181                        " { Outer.Inner get(); }";
1182 
1183   auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1184   EXPECT_NE(nullptr, parse_result);
1185 
1186   EXPECT_TRUE(typenames_.ResolveTypename("p.Outer.Inner").is_resolved);
1187   // C++ uses "::" instead of "." to refer to a inner class.
1188   AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.Outer.Inner", false, nullptr, {});
1189   EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
1190 }
1191 
TEST_P(AidlTest,UnderstandsNativeParcelables)1192 TEST_P(AidlTest, UnderstandsNativeParcelables) {
1193   io_delegate_.SetFileContents(
1194       "p/Bar.aidl",
1195       "package p; parcelable Bar cpp_header \"baz/header\";");
1196   import_paths_.emplace("");
1197   const string input_path = "p/IFoo.aidl";
1198   const string input = "package p; import p.Bar; interface IFoo { }";
1199   auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1200   EXPECT_NE(nullptr, parse_result);
1201   EXPECT_TRUE(typenames_.ResolveTypename("p.Bar").is_resolved);
1202   AidlTypeSpecifier native_type(AIDL_LOCATION_HERE, "p.Bar", false, nullptr, {});
1203   native_type.Resolve(typenames_);
1204 
1205   EXPECT_EQ("p.Bar", java::InstantiableJavaSignatureOf(native_type, typenames_));
1206   // C++ understands C++ specific stuff
1207   EXPECT_EQ("::p::Bar", cpp::CppNameOf(native_type, typenames_));
1208   set<string> headers;
1209   cpp::AddHeaders(native_type, typenames_, &headers);
1210   EXPECT_EQ(1u, headers.size());
1211   EXPECT_EQ(1u, headers.count("baz/header"));
1212 }
1213 
TEST_F(AidlTest,WritesCorrectDependencyFile)1214 TEST_F(AidlTest, WritesCorrectDependencyFile) {
1215   // While the in tree build system always gives us an output file name,
1216   // other android tools take advantage of our ability to infer the intended
1217   // file name.  This test makes sure we handle this correctly.
1218   vector<string> args = {
1219     "aidl",
1220     "-d dep/file/path",
1221     "-o place/for/output",
1222     "p/IFoo.aidl"};
1223   Options options = Options::From(args);
1224   io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
1225   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1226   string actual_dep_file_contents;
1227   EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
1228   EXPECT_EQ(actual_dep_file_contents, kExpectedDepFileContents);
1229 }
1230 
TEST_F(AidlTest,WritesCorrectDependencyFileNinja)1231 TEST_F(AidlTest, WritesCorrectDependencyFileNinja) {
1232   // While the in tree build system always gives us an output file name,
1233   // other android tools take advantage of our ability to infer the intended
1234   // file name.  This test makes sure we handle this correctly.
1235   vector<string> args = {
1236     "aidl",
1237     "-d dep/file/path",
1238     "--ninja",
1239     "-o place/for/output",
1240     "p/IFoo.aidl"};
1241   Options options = Options::From(args);
1242   io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
1243   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1244   string actual_dep_file_contents;
1245   EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
1246   EXPECT_EQ(actual_dep_file_contents, kExpectedNinjaDepFileContents);
1247 }
1248 
TEST_F(AidlTest,WritesTrivialDependencyFileForParcelableDeclaration)1249 TEST_F(AidlTest, WritesTrivialDependencyFileForParcelableDeclaration) {
1250   // The SDK uses aidl to decide whether a .aidl file is a parcelable.  It does
1251   // this by calling aidl with every .aidl file it finds, then parsing the
1252   // generated dependency files.  Those that reference .java output files are
1253   // for interfaces and those that do not are parcelables.  However, for both
1254   // parcelables and interfaces, we *must* generate a non-empty dependency file.
1255   vector<string> args = {
1256     "aidl",
1257     "-o place/for/output",
1258     "-d dep/file/path",
1259     "p/Foo.aidl"};
1260   Options options = Options::From(args);
1261   io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
1262   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1263   string actual_dep_file_contents;
1264   EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
1265   EXPECT_EQ(actual_dep_file_contents, kExpectedParcelableDeclarationDepFileContents);
1266 }
1267 
TEST_F(AidlTest,WritesDependencyFileForStructuredParcelable)1268 TEST_F(AidlTest, WritesDependencyFileForStructuredParcelable) {
1269   vector<string> args = {
1270     "aidl",
1271     "--structured",
1272     "-o place/for/output",
1273     "-d dep/file/path",
1274     "p/Foo.aidl"};
1275   Options options = Options::From(args);
1276   io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo {int a;}");
1277   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1278   string actual_dep_file_contents;
1279   EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
1280   EXPECT_EQ(actual_dep_file_contents, kExpectedStructuredParcelableDepFileContents);
1281 }
1282 
TEST_F(AidlTest,NoJavaOutputForParcelableDeclaration)1283 TEST_F(AidlTest, NoJavaOutputForParcelableDeclaration) {
1284  vector<string> args = {
1285     "aidl",
1286     "--lang=java",
1287     "-o place/for/output",
1288     "p/Foo.aidl"};
1289   Options options = Options::From(args);
1290   io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
1291   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1292   string output_file_contents;
1293   EXPECT_FALSE(io_delegate_.GetWrittenContents(options.OutputFile(), &output_file_contents));
1294 }
1295 
TEST_P(AidlTest,RejectsListArray)1296 TEST_P(AidlTest, RejectsListArray) {
1297   const string expected_stderr = "ERROR: a/Foo.aidl:2.1-7: List[] is not supported.\n";
1298   const string list_array_parcelable =
1299       "package a; parcelable Foo {\n"
1300       "  List[] lists; }";
1301   CaptureStderr();
1302   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", list_array_parcelable, typenames_, GetLanguage()));
1303   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1304 }
1305 
TEST_P(AidlTest,RejectsPrimitiveListInStableAidl)1306 TEST_P(AidlTest, RejectsPrimitiveListInStableAidl) {
1307   AidlError error;
1308   string expected_stderr =
1309       "ERROR: a/IFoo.aidl:2.7-11: "
1310       "Encountered an untyped List or Map. The use of untyped List/Map is "
1311       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
1312       "the receiving side. Consider switching to an array or a generic List/Map.\n";
1313   if (GetLanguage() != Options::Language::JAVA) {
1314     expected_stderr =
1315         "ERROR: a/IFoo.aidl:2.1-7: "
1316         "Currently, only the Java backend supports non-generic List.\n";
1317   }
1318 
1319   const string primitive_interface =
1320       "package a; interface IFoo {\n"
1321       "  List foo(); }";
1322   CaptureStderr();
1323   AidlTypenames tn1;
1324   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", primitive_interface, tn1, GetLanguage(), &error,
1325                            {"--structured"}));
1326   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1327 
1328   string primitive_parcelable =
1329       "package a; parcelable IFoo {\n"
1330       "  List foo;}";
1331   CaptureStderr();
1332   AidlTypenames tn2;
1333   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", primitive_parcelable, tn2, GetLanguage(), &error,
1334                            {"--structured"}));
1335   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1336 }
1337 
TEST_P(AidlTest,ExtensionTest)1338 TEST_P(AidlTest, ExtensionTest) {
1339   CaptureStderr();
1340   string extendable_parcelable =
1341       "package a; parcelable Data {\n"
1342       "  ParcelableHolder extension;\n"
1343       "  ParcelableHolder extension2;\n"
1344       "}";
1345   if (GetLanguage() == Options::Language::RUST) {
1346     EXPECT_EQ(nullptr, Parse("a/Data.aidl", extendable_parcelable, typenames_, GetLanguage()));
1347     EXPECT_EQ(
1348         "ERROR: a/Data.aidl:2.1-19: The Rust backend does not support ParcelableHolder "
1349         "yet.\n",
1350         GetCapturedStderr());
1351   } else {
1352     EXPECT_NE(nullptr, Parse("a/Data.aidl", extendable_parcelable, typenames_, GetLanguage()));
1353     EXPECT_EQ("", GetCapturedStderr());
1354   }
1355 }
TEST_P(AidlTest,ParcelableHolderAsReturnType)1356 TEST_P(AidlTest, ParcelableHolderAsReturnType) {
1357   CaptureStderr();
1358   string parcelableholder_return_interface =
1359       "package a; interface IFoo {\n"
1360       "  ParcelableHolder foo();\n"
1361       "}";
1362   EXPECT_EQ(nullptr,
1363             Parse("a/IFoo.aidl", parcelableholder_return_interface, typenames_, GetLanguage()));
1364 
1365   if (GetLanguage() == Options::Language::RUST) {
1366     EXPECT_EQ(
1367         "ERROR: a/IFoo.aidl:2.19-23: ParcelableHolder cannot be a return type\n"
1368         "ERROR: a/IFoo.aidl:2.1-19: The Rust backend does not support ParcelableHolder "
1369         "yet.\n",
1370         GetCapturedStderr());
1371     return;
1372   }
1373   EXPECT_EQ("ERROR: a/IFoo.aidl:2.19-23: ParcelableHolder cannot be a return type\n",
1374             GetCapturedStderr());
1375 }
1376 
TEST_P(AidlTest,ParcelableHolderAsArgumentType)1377 TEST_P(AidlTest, ParcelableHolderAsArgumentType) {
1378   CaptureStderr();
1379   string extendable_parcelable_arg_interface =
1380       "package a; interface IFoo {\n"
1381       "  void foo(in ParcelableHolder ph);\n"
1382       "}";
1383   EXPECT_EQ(nullptr,
1384             Parse("a/IFoo.aidl", extendable_parcelable_arg_interface, typenames_, GetLanguage()));
1385 
1386   if (GetLanguage() == Options::Language::RUST) {
1387     EXPECT_EQ(
1388         "ERROR: a/IFoo.aidl:2.31-34: ParcelableHolder cannot be an argument type\n"
1389         "ERROR: a/IFoo.aidl:2.14-31: The Rust backend does not support ParcelableHolder "
1390         "yet.\n",
1391         GetCapturedStderr());
1392     return;
1393   }
1394   EXPECT_EQ("ERROR: a/IFoo.aidl:2.31-34: ParcelableHolder cannot be an argument type\n",
1395             GetCapturedStderr());
1396 }
1397 
TEST_P(AidlTest,RejectNullableParcelableHolderField)1398 TEST_P(AidlTest, RejectNullableParcelableHolderField) {
1399   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { @nullable ParcelableHolder ext; }");
1400   Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
1401   const string expected_stderr = "ERROR: Foo.aidl:1.27-44: ParcelableHolder cannot be nullable.\n";
1402   CaptureStderr();
1403   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1404   if (GetLanguage() == Options::Language::RUST) {
1405     EXPECT_EQ(
1406         "ERROR: Foo.aidl:1.27-44: ParcelableHolder cannot be nullable.\n"
1407         "ERROR: Foo.aidl:1.27-44: The Rust backend does not support ParcelableHolder "
1408         "yet.\n",
1409         GetCapturedStderr());
1410     return;
1411   }
1412   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1413 }
1414 
TEST_P(AidlTest,ParcelablesWithConstants)1415 TEST_P(AidlTest, ParcelablesWithConstants) {
1416   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { const int BIT = 0x1 << 3; }");
1417   Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
1418   CaptureStderr();
1419   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1420   EXPECT_EQ("", GetCapturedStderr());
1421 }
1422 
TEST_P(AidlTest,UnionWithConstants)1423 TEST_P(AidlTest, UnionWithConstants) {
1424   io_delegate_.SetFileContents("Foo.aidl", "union Foo { const int BIT = 0x1 << 3; int n; }");
1425   Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
1426   CaptureStderr();
1427   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1428   EXPECT_EQ("", GetCapturedStderr());
1429 }
1430 
TEST_F(AidlTest,ConstantsWithAnnotations)1431 TEST_F(AidlTest, ConstantsWithAnnotations) {
1432   io_delegate_.SetFileContents("IFoo.aidl",
1433                                "interface IFoo {\n"
1434                                " @JavaPassthrough(annotation=\"@Foo\")\n"
1435                                " const @JavaPassthrough(annotation=\"@Bar\") int FOO = 0;\n"
1436                                "}");
1437   Options options = Options::From("aidl IFoo.aidl --lang=java -o out");
1438   CaptureStderr();
1439   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1440   EXPECT_EQ("", GetCapturedStderr());
1441   string code;
1442   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/IFoo.java", &code));
1443   EXPECT_THAT(code, HasSubstr("@Foo\n"));
1444   EXPECT_THAT(code, HasSubstr("@Bar\n"));
1445 }
1446 
TEST_F(AidlTest,ApiDump)1447 TEST_F(AidlTest, ApiDump) {
1448   io_delegate_.SetFileContents(
1449       "foo/bar/IFoo.aidl",
1450       "package foo.bar;\n"
1451       "import foo.bar.Data;\n"
1452       "// commented /* @hide */\n"
1453       "interface IFoo {\n"
1454       "    /* @hide applied \n"
1455       "       @deprecated use foo2 */\n"
1456       "    int foo(out int[] a, String b, boolean c, inout List<String> d);\n"
1457       "    int foo2(@utf8InCpp String x, inout List<String> y);\n"
1458       "    IFoo foo3(IFoo foo);\n"
1459       "    Data getData();\n"
1460       "    // @hide not applied\n"
1461       "    /** blahblah\n"
1462       "        @deprecated\n"
1463       "          reason why... */\n"
1464       "    const int A = 1;\n"
1465       "    // @deprecated tags in line comments are ignored\n"
1466       "    const String STR = \"Hello\";\n"
1467       "}\n");
1468   io_delegate_.SetFileContents("foo/bar/Data.aidl",
1469                                "package foo.bar;\n"
1470                                "import foo.bar.IFoo;\n"
1471                                "/* @hide*/\n"
1472                                "parcelable Data {\n"
1473                                "   // @hide\n"
1474                                "   int x = 10;\n"
1475                                "   // @hide\n"
1476                                "   int y;\n"
1477                                "   /*@hide2*/\n"
1478                                "   IFoo foo;\n"
1479                                "   // Ignore @hide property in line comment\n"
1480                                "   @nullable String[] c;\n"
1481                                "}\n");
1482   io_delegate_.SetFileContents("api.aidl", "");
1483   vector<string> args = {"aidl", "--dumpapi", "--out=dump", "--include=.",
1484                          "foo/bar/IFoo.aidl", "foo/bar/Data.aidl"};
1485   Options options = Options::From(args);
1486   bool result = dump_api(options, io_delegate_);
1487   ASSERT_TRUE(result);
1488   string actual;
1489   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
1490   EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
1491 interface IFoo {
1492   /**
1493    * @hide
1494    * @deprecated use foo2
1495    */
1496   int foo(out int[] a, String b, boolean c, inout List<String> d);
1497   int foo2(@utf8InCpp String x, inout List<String> y);
1498   foo.bar.IFoo foo3(foo.bar.IFoo foo);
1499   foo.bar.Data getData();
1500   /**
1501    * @deprecated reason why...
1502    */
1503   const int A = 1;
1504   const String STR = "Hello";
1505 }
1506 )"),
1507             actual);
1508 
1509   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Data.aidl", &actual));
1510   EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
1511 /* @hide */
1512 parcelable Data {
1513   int x = 10;
1514   int y;
1515   foo.bar.IFoo foo;
1516   @nullable String[] c;
1517 }
1518 )"),
1519             actual);
1520 }
1521 
TEST_F(AidlTest,ApiDumpWithManualIds)1522 TEST_F(AidlTest, ApiDumpWithManualIds) {
1523   io_delegate_.SetFileContents(
1524       "foo/bar/IFoo.aidl",
1525       "package foo.bar;\n"
1526       "interface IFoo {\n"
1527       "    int foo() = 1;\n"
1528       "    int bar() = 2;\n"
1529       "    int baz() = 10;\n"
1530       "}\n");
1531 
1532   vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
1533   Options options = Options::From(args);
1534   bool result = dump_api(options, io_delegate_);
1535   ASSERT_TRUE(result);
1536   string actual;
1537   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
1538   EXPECT_EQ(actual, string(kPreamble).append(R"(package foo.bar;
1539 interface IFoo {
1540   int foo() = 1;
1541   int bar() = 2;
1542   int baz() = 10;
1543 }
1544 )"));
1545 }
1546 
TEST_F(AidlTest,ApiDumpWithManualIdsOnlyOnSomeMethods)1547 TEST_F(AidlTest, ApiDumpWithManualIdsOnlyOnSomeMethods) {
1548   const string expected_stderr =
1549       "ERROR: foo/bar/IFoo.aidl:4.8-12: You must either assign id's to all methods or to none of "
1550       "them.\n";
1551   io_delegate_.SetFileContents(
1552       "foo/bar/IFoo.aidl",
1553       "package foo.bar;\n"
1554       "interface IFoo {\n"
1555       "    int foo() = 1;\n"
1556       "    int bar();\n"
1557       "    int baz() = 10;\n"
1558       "}\n");
1559 
1560   vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
1561   Options options = Options::From(args);
1562   CaptureStderr();
1563   EXPECT_FALSE(dump_api(options, io_delegate_));
1564   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1565 }
1566 
TEST_F(AidlTest,ApiDumpConstWithAnnotation)1567 TEST_F(AidlTest, ApiDumpConstWithAnnotation) {
1568   io_delegate_.SetFileContents("foo/bar/IFoo.aidl",
1569                                "package foo.bar;\n"
1570                                "interface IFoo {\n"
1571                                "    @utf8InCpp String foo();\n"
1572                                "    const @utf8InCpp String bar = \"bar\";\n"
1573                                "}\n");
1574 
1575   vector<string> args = {"aidl", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
1576   Options options = Options::From(args);
1577   CaptureStderr();
1578   EXPECT_TRUE(dump_api(options, io_delegate_));
1579   EXPECT_EQ("", GetCapturedStderr());
1580   string actual;
1581   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
1582   EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
1583 interface IFoo {
1584   @utf8InCpp String foo();
1585   const @utf8InCpp String bar = "bar";
1586 }
1587 )"),
1588             actual);
1589 }
1590 
TEST_F(AidlTest,ApiDumpWithEnums)1591 TEST_F(AidlTest, ApiDumpWithEnums) {
1592   io_delegate_.SetFileContents("foo/bar/Enum.aidl",
1593                                "package foo.bar;\n"
1594                                "enum Enum {\n"
1595                                "    FOO,\n"
1596                                "    BAR = FOO + 1,\n"
1597                                "}\n");
1598 
1599   vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Enum.aidl"};
1600   Options options = Options::From(args);
1601   CaptureStderr();
1602   EXPECT_TRUE(dump_api(options, io_delegate_));
1603   EXPECT_EQ("", GetCapturedStderr());
1604   string actual;
1605   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Enum.aidl", &actual));
1606   EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
1607                                      "enum Enum {\n"
1608                                      "  FOO = 0,\n"
1609                                      "  BAR = 1,\n"
1610                                      "}\n"),
1611             actual);
1612 }
1613 
TEST_F(AidlTest,ApiDumpWithEnumDefaultValues)1614 TEST_F(AidlTest, ApiDumpWithEnumDefaultValues) {
1615   io_delegate_.SetFileContents("foo/bar/Enum.aidl",
1616                                "package foo.bar;\n"
1617                                "enum Enum {\n"
1618                                "    FOO,\n"
1619                                "}\n");
1620   io_delegate_.SetFileContents("foo/bar/Foo.aidl",
1621                                "package foo.bar;\n"
1622                                "import foo.bar.Enum;\n"
1623                                "parcelable Foo {\n"
1624                                "    Enum e = Enum.FOO;\n"
1625                                "}\n");
1626 
1627   vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Foo.aidl"};
1628   Options options = Options::From(args);
1629   CaptureStderr();
1630   EXPECT_TRUE(dump_api(options, io_delegate_));
1631   EXPECT_EQ("", GetCapturedStderr());
1632   string actual;
1633   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
1634   EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
1635                                      "parcelable Foo {\n"
1636                                      "  foo.bar.Enum e = foo.bar.Enum.FOO;\n"
1637                                      "}\n"),
1638             actual);
1639 }
1640 
TEST_F(AidlTest,ApiDumpWithGenerics)1641 TEST_F(AidlTest, ApiDumpWithGenerics) {
1642   io_delegate_.SetFileContents("foo/bar/Foo.aidl",
1643                                "package foo.bar;\n"
1644                                "parcelable Foo<T, U> {\n"
1645                                "}\n");
1646 
1647   vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Foo.aidl"};
1648   Options options = Options::From(args);
1649   CaptureStderr();
1650   EXPECT_TRUE(dump_api(options, io_delegate_));
1651   EXPECT_EQ("", GetCapturedStderr());
1652   string actual;
1653   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
1654   EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
1655                                      "parcelable Foo<T, U> {\n"
1656                                      "}\n"),
1657             actual);
1658 }
1659 
TEST_F(AidlTest,CheckNumGenericTypeSecifier)1660 TEST_F(AidlTest, CheckNumGenericTypeSecifier) {
1661   const string expected_list_stderr =
1662       "ERROR: p/IFoo.aidl:1.37-41: List can only have one type parameter, but got: "
1663       "'List<String,String>'\n";
1664   const string expected_map_stderr =
1665       "ERROR: p/IFoo.aidl:1.37-40: Map must have 0 or 2 type parameters, but got 'Map<String>'\n";
1666   Options options = Options::From("aidl p/IFoo.aidl IFoo.java");
1667   io_delegate_.SetFileContents(options.InputFiles().front(),
1668                                "package p; interface IFoo {"
1669                                "void foo(List<String, String> a);}");
1670   CaptureStderr();
1671   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1672   EXPECT_EQ(expected_list_stderr, GetCapturedStderr());
1673 
1674   io_delegate_.SetFileContents(options.InputFiles().front(),
1675                                "package p; interface IFoo {"
1676                                "void foo(Map<String> a);}");
1677   CaptureStderr();
1678   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1679   EXPECT_EQ(expected_map_stderr, GetCapturedStderr());
1680 }
1681 
TEST_F(AidlTest,CheckTypeParameterInMapType)1682 TEST_F(AidlTest, CheckTypeParameterInMapType) {
1683   const string expected_stderr =
1684       "ERROR: p/IFoo.aidl:1.28-31: The type of key in map must be String, but it is 'p.Bar'\n";
1685   Options options = Options::From("aidl -I p p/IFoo.aidl");
1686   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar { String s; }");
1687 
1688   io_delegate_.SetFileContents("p/IFoo.aidl",
1689                                "package p; interface IFoo {"
1690                                "Map<String, Bar> foo();}");
1691   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1692 
1693   io_delegate_.SetFileContents("p/IFoo.aidl",
1694                                "package p; interface IFoo {"
1695                                "Map<Bar, Bar> foo();}");
1696   CaptureStderr();
1697   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1698   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1699 
1700   io_delegate_.SetFileContents("p/IFoo.aidl",
1701                                "package p; interface IFoo {"
1702                                "Map<String, String> foo();}");
1703   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1704 
1705   io_delegate_.SetFileContents("p/IFoo.aidl",
1706                                "package p; interface IFoo {"
1707                                "Map<String, ParcelFileDescriptor> foo();}");
1708   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1709 }
1710 
TEST_F(AidlTest,WrongGenericType)1711 TEST_F(AidlTest, WrongGenericType) {
1712   const string expected_stderr = "ERROR: p/IFoo.aidl:1.28-34: String is not a generic type.\n";
1713   Options options = Options::From("aidl p/IFoo.aidl IFoo.java");
1714   io_delegate_.SetFileContents(options.InputFiles().front(),
1715                                "package p; interface IFoo {"
1716                                "String<String> foo(); }");
1717   CaptureStderr();
1718   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1719   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1720 }
1721 
TEST_F(AidlTest,UserDefinedUnstructuredGenericParcelableType)1722 TEST_F(AidlTest, UserDefinedUnstructuredGenericParcelableType) {
1723   Options optionsForParcelable = Options::From("aidl -I p p/Bar.aidl");
1724   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, T>;");
1725   CaptureStderr();
1726   EXPECT_NE(0, ::android::aidl::compile_aidl(optionsForParcelable, io_delegate_));
1727   EXPECT_EQ("ERROR: p/Bar.aidl:1.22-26: Every type parameter should be unique.\n",
1728             GetCapturedStderr());
1729 
1730   Options options = Options::From("aidl -I p p/IFoo.aidl");
1731   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar;");
1732   io_delegate_.SetFileContents("p/IFoo.aidl",
1733                                "package p; interface IFoo {"
1734                                "Bar<String, String> foo();}");
1735   CaptureStderr();
1736   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1737   EXPECT_EQ("ERROR: p/IFoo.aidl:1.28-31: p.Bar is not a generic type.\n", GetCapturedStderr());
1738   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T>;");
1739   CaptureStderr();
1740   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1741   EXPECT_EQ("ERROR: p/IFoo.aidl:1.28-31: p.Bar must have 1 type parameters, but got 2\n",
1742             GetCapturedStderr());
1743   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, V>;");
1744   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1745   io_delegate_.SetFileContents("p/IFoo.aidl",
1746                                "package p; interface IFoo {"
1747                                "Bar<String, ParcelFileDescriptor> foo();}");
1748   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1749 
1750   io_delegate_.SetFileContents("p/IFoo.aidl",
1751                                "package p; interface IFoo {"
1752                                "Bar<int, long> foo();}");
1753 
1754   io_delegate_.SetFileContents("p/IFoo.aidl",
1755                                "package p; interface IFoo {"
1756                                "Bar<int[], long[]> foo();}");
1757 
1758   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1759 }
1760 
TEST_F(AidlTest,FailOnMultipleTypesInSingleFile)1761 TEST_F(AidlTest, FailOnMultipleTypesInSingleFile) {
1762   std::vector<std::string> rawOptions{"aidl --lang=java -o out foo/bar/Foo.aidl",
1763                                       "aidl --lang=cpp -o out -h out/include foo/bar/Foo.aidl",
1764                                       "aidl --lang=rust -o out foo/bar/Foo.aidl"};
1765   for (const auto& rawOption : rawOptions) {
1766     string expected_stderr =
1767         "ERROR: foo/bar/Foo.aidl:3.1-10: You must declare only one type per file.\n";
1768     Options options = Options::From(rawOption);
1769     io_delegate_.SetFileContents(options.InputFiles().front(),
1770                                  "package foo.bar;\n"
1771                                  "interface IFoo1 { int foo(); }\n"
1772                                  "interface IFoo2 { int foo(); }\n"
1773                                  "parcelable Data1 { int a; int b;}\n"
1774                                  "parcelable Data2 { int a; int b;}\n");
1775     CaptureStderr();
1776     EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1777     EXPECT_EQ(expected_stderr, GetCapturedStderr());
1778 
1779     io_delegate_.SetFileContents(options.InputFiles().front(),
1780                                  "package foo.bar;\n"
1781                                  "interface IFoo1 { int foo(); }\n"
1782                                  "interface IFoo2 { int foo(); }\n");
1783     CaptureStderr();
1784     EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1785     EXPECT_EQ(expected_stderr, GetCapturedStderr());
1786 
1787     expected_stderr = "ERROR: foo/bar/Foo.aidl:3.11-17: You must declare only one type per file.\n";
1788     io_delegate_.SetFileContents(options.InputFiles().front(),
1789                                  "package foo.bar;\n"
1790                                  "parcelable Data1 { int a; int b;}\n"
1791                                  "parcelable Data2 { int a; int b;}\n");
1792     CaptureStderr();
1793     EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1794     EXPECT_EQ(expected_stderr, GetCapturedStderr());
1795   }
1796 }
1797 
TEST_P(AidlTest,FailParseOnEmptyFile)1798 TEST_P(AidlTest, FailParseOnEmptyFile) {
1799   const string contents = "";
1800   const string expected_stderr = "ERROR: a/IFoo.aidl:1.1-1: syntax error, unexpected $end\n";
1801   CaptureStderr();
1802   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", contents, typenames_, GetLanguage()));
1803   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1804 }
1805 
TEST_F(AidlTest,MultipleInputFiles)1806 TEST_F(AidlTest, MultipleInputFiles) {
1807   Options options = Options::From(
1808       "aidl --lang=java -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
1809 
1810   io_delegate_.SetFileContents(options.InputFiles().at(0),
1811       "package foo.bar;\n"
1812       "import foo.bar.Data;\n"
1813       "interface IFoo { Data getData(); }\n");
1814 
1815   io_delegate_.SetFileContents(options.InputFiles().at(1),
1816         "package foo.bar;\n"
1817         "import foo.bar.IFoo;\n"
1818         "parcelable Data { IFoo foo; }\n");
1819 
1820   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1821 
1822   string content;
1823   for (const auto file : {
1824     "out/foo/bar/IFoo.java", "out/foo/bar/Data.java"}) {
1825     content.clear();
1826     EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
1827     EXPECT_FALSE(content.empty());
1828   }
1829 }
1830 
TEST_F(AidlTest,MultipleInputFilesCpp)1831 TEST_F(AidlTest, MultipleInputFilesCpp) {
1832   Options options = Options::From("aidl --lang=cpp -o out -h out/include "
1833       "-I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
1834 
1835   io_delegate_.SetFileContents(options.InputFiles().at(0),
1836       "package foo.bar;\n"
1837       "import foo.bar.Data;\n"
1838       "interface IFoo { Data getData(); }\n");
1839 
1840   io_delegate_.SetFileContents(options.InputFiles().at(1),
1841         "package foo.bar;\n"
1842         "import foo.bar.IFoo;\n"
1843         "parcelable Data { IFoo foo; }\n");
1844 
1845   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1846 
1847   string content;
1848   for (const auto file : {
1849     "out/foo/bar/IFoo.cpp", "out/foo/bar/Data.cpp",
1850     "out/include/foo/bar/IFoo.h", "out/include/foo/bar/Data.h",
1851     "out/include/foo/bar/BpFoo.h", "out/include/foo/bar/BpData.h",
1852     "out/include/foo/bar/BnFoo.h", "out/include/foo/bar/BnData.h"}) {
1853     content.clear();
1854     EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
1855     EXPECT_FALSE(content.empty());
1856   }
1857 }
1858 
TEST_F(AidlTest,MultipleInputFilesRust)1859 TEST_F(AidlTest, MultipleInputFilesRust) {
1860   Options options =
1861       Options::From("aidl --lang=rust -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
1862 
1863   io_delegate_.SetFileContents(options.InputFiles().at(0),
1864                                "package foo.bar;\n"
1865                                "import foo.bar.Data;\n"
1866                                "interface IFoo { Data getData(); }\n");
1867 
1868   io_delegate_.SetFileContents(options.InputFiles().at(1),
1869                                "package foo.bar;\n"
1870                                "import foo.bar.IFoo;\n"
1871                                "parcelable Data { IFoo foo; }\n");
1872 
1873   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1874 
1875   string content;
1876   for (const auto file : {"out/foo/bar/IFoo.rs", "out/foo/bar/Data.rs"}) {
1877     content.clear();
1878     EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
1879     EXPECT_FALSE(content.empty());
1880   }
1881 }
1882 
TEST_F(AidlTest,ConflictWithMetaTransactionGetVersion)1883 TEST_F(AidlTest, ConflictWithMetaTransactionGetVersion) {
1884   const string expected_stderr =
1885       "ERROR: p/IFoo.aidl:1.31-51:  method getInterfaceVersion() is reserved for internal use.\n";
1886   Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
1887   // int getInterfaceVersion() is one of the meta transactions
1888   io_delegate_.SetFileContents(options.InputFiles().front(),
1889                                "package p; interface IFoo {"
1890                                "int getInterfaceVersion(); }");
1891   CaptureStderr();
1892   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1893   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1894 }
1895 
TEST_F(AidlTest,ConflictWithSimilarMetaTransaction)1896 TEST_F(AidlTest, ConflictWithSimilarMetaTransaction) {
1897   // boolean getInterfaceVersion() is not a meta transaction, but should be
1898   // prevented because return type is not part of a method signature
1899   const string expected_stderr =
1900       "ERROR: p/IFoo.aidl:1.35-55:  method getInterfaceVersion() is reserved for internal use.\n";
1901   Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
1902   io_delegate_.SetFileContents(options.InputFiles().front(),
1903                                "package p; interface IFoo {"
1904                                "boolean getInterfaceVersion(); }");
1905   CaptureStderr();
1906   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1907   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1908 }
1909 
TEST_F(AidlTest,ConflictWithMetaTransactionGetName)1910 TEST_F(AidlTest, ConflictWithMetaTransactionGetName) {
1911   // this is another reserved name
1912   const string expected_stderr =
1913       "ERROR: p/IFoo.aidl:1.34-53:  method getTransactionName(int) is reserved for internal use.\n";
1914   Options options = Options::From("aidl --lang=java -o place/for/output p/IFoo.aidl");
1915   io_delegate_.SetFileContents(options.InputFiles().front(),
1916                                "package p; interface IFoo {"
1917                                "String getTransactionName(int code); }");
1918   CaptureStderr();
1919   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
1920   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1921 
1922   // this is not a meta interface method as it differs type arguments
1923   io_delegate_.SetFileContents(options.InputFiles().front(),
1924                                "package p; interface IFoo {"
1925                                "String getTransactionName(); }");
1926   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
1927 }
1928 
TEST_F(AidlTest,CheckApiForEquality)1929 TEST_F(AidlTest, CheckApiForEquality) {
1930   CaptureStderr();
1931   Options options = Options::From("aidl --checkapi=equal old new");
1932 
1933   io_delegate_.SetFileContents("old/p/IFoo.aidl",
1934                                "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
1935   io_delegate_.SetFileContents("new/p/IFoo.aidl",
1936                                "package p; interface IFoo{ @utf8InCpp String foo();}");
1937 
1938   EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
1939   EXPECT_THAT(GetCapturedStderr(), HasSubstr("+  @utf8InCpp String foo();"));
1940 }
1941 
TEST_F(AidlTest,DifferentOrderAnnotationsInCheckAPI)1942 TEST_F(AidlTest, DifferentOrderAnnotationsInCheckAPI) {
1943   Options options = Options::From("aidl --checkapi old new");
1944   io_delegate_.SetFileContents("old/p/IFoo.aidl",
1945                                "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
1946   io_delegate_.SetFileContents("new/p/IFoo.aidl",
1947                                "package p; interface IFoo{ @nullable @utf8InCpp String foo();}");
1948 
1949   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
1950 }
1951 
TEST_F(AidlTest,SuccessOnIdenticalApiDumps)1952 TEST_F(AidlTest, SuccessOnIdenticalApiDumps) {
1953   Options options = Options::From("aidl --checkapi old new");
1954   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
1955   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
1956 
1957   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
1958 }
1959 
TEST_F(AidlTest,CheckApi_EnumFieldsWithDefaultValues)1960 TEST_F(AidlTest, CheckApi_EnumFieldsWithDefaultValues) {
1961   Options options = Options::From("aidl --checkapi old new");
1962   const string foo_definition = "package p; parcelable Foo{ p.Enum e = p.Enum.FOO; }";
1963   const string enum_definition = "package p; enum Enum { FOO }";
1964   io_delegate_.SetFileContents("old/p/Foo.aidl", foo_definition);
1965   io_delegate_.SetFileContents("old/p/Enum.aidl", enum_definition);
1966   io_delegate_.SetFileContents("new/p/Foo.aidl", foo_definition);
1967   io_delegate_.SetFileContents("new/p/Enum.aidl", enum_definition);
1968 
1969   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
1970 }
1971 
TEST_F(AidlTest,CheckApiEqual_EnumFieldsWithDefaultValues)1972 TEST_F(AidlTest, CheckApiEqual_EnumFieldsWithDefaultValues) {
1973   Options options = Options::From("aidl --checkapi=equal old new");
1974   const string foo_definition = "package p; parcelable Foo{ p.Enum e = p.Enum.FOO; }";
1975   const string enum_definition = "package p; enum Enum { FOO }";
1976   io_delegate_.SetFileContents("old/p/Foo.aidl", foo_definition);
1977   io_delegate_.SetFileContents("old/p/Enum.aidl", enum_definition);
1978   io_delegate_.SetFileContents("new/p/Foo.aidl", foo_definition);
1979   io_delegate_.SetFileContents("new/p/Enum.aidl", enum_definition);
1980   CaptureStderr();
1981   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
1982   EXPECT_EQ("", GetCapturedStderr());
1983 }
1984 
1985 class AidlTestCompatibleChanges : public AidlTest {
1986  protected:
1987   Options options_ = Options::From("aidl --checkapi old new");
1988 };
1989 
TEST_F(AidlTestCompatibleChanges,NewType)1990 TEST_F(AidlTestCompatibleChanges, NewType) {
1991   io_delegate_.SetFileContents("old/p/IFoo.aidl",
1992                                "package p;"
1993                                "interface IFoo {"
1994                                "  void foo(int a);"
1995                                "}");
1996   io_delegate_.SetFileContents("new/p/IFoo.aidl",
1997                                "package p;"
1998                                "interface IFoo {"
1999                                "  void foo(int a);"
2000                                "}");
2001   io_delegate_.SetFileContents("new/p/IBar.aidl",
2002                                "package p;"
2003                                "interface IBar {"
2004                                "  void bar();"
2005                                "}");
2006   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2007 }
2008 
TEST_F(AidlTestCompatibleChanges,NewMethod)2009 TEST_F(AidlTestCompatibleChanges, NewMethod) {
2010   io_delegate_.SetFileContents("old/p/IFoo.aidl",
2011                                "package p;"
2012                                "interface IFoo {"
2013                                "  void foo(int a);"
2014                                "}");
2015   io_delegate_.SetFileContents("new/p/IFoo.aidl",
2016                                "package p;"
2017                                "interface IFoo {"
2018                                "  void foo(int a);"
2019                                "  void bar();"
2020                                "  void baz(in List<IFoo> arg);"
2021                                "}");
2022   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2023 }
2024 
TEST_F(AidlTestCompatibleChanges,NewField)2025 TEST_F(AidlTestCompatibleChanges, NewField) {
2026   io_delegate_.SetFileContents("old/p/Data.aidl",
2027                                "package p;"
2028                                "parcelable Data {"
2029                                "  int foo;"
2030                                "}");
2031   io_delegate_.SetFileContents("new/p/Data.aidl",
2032                                "package p;"
2033                                "parcelable Data {"
2034                                "  int foo;"
2035                                "  int bar = 0;"
2036                                "  @nullable List<Data> list;"
2037                                "}");
2038   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2039 }
2040 
TEST_F(AidlTestCompatibleChanges,NewField2)2041 TEST_F(AidlTestCompatibleChanges, NewField2) {
2042   io_delegate_.SetFileContents("old/p/Data.aidl",
2043                                "package p;"
2044                                "parcelable Data {"
2045                                "}");
2046   io_delegate_.SetFileContents("new/p/Data.aidl",
2047                                "package p;"
2048                                "parcelable Data {"
2049                                "  int foo = 0;"
2050                                "}");
2051   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2052 }
2053 
TEST_F(AidlTestCompatibleChanges,NewEnumerator)2054 TEST_F(AidlTestCompatibleChanges, NewEnumerator) {
2055   io_delegate_.SetFileContents("old/p/Enum.aidl",
2056                                "package p;"
2057                                "enum Enum {"
2058                                "  FOO = 1,"
2059                                "}");
2060   io_delegate_.SetFileContents("new/p/Enum.aidl",
2061                                "package p;"
2062                                "enum Enum {"
2063                                "  FOO = 1,"
2064                                "  BAR = 2,"
2065                                "}");
2066   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2067 }
2068 
TEST_F(AidlTestCompatibleChanges,ReorderedEnumerator)2069 TEST_F(AidlTestCompatibleChanges, ReorderedEnumerator) {
2070   io_delegate_.SetFileContents("old/p/Enum.aidl",
2071                                "package p;"
2072                                "enum Enum {"
2073                                "  FOO = 1,"
2074                                "  BAR = 2,"
2075                                "}");
2076   io_delegate_.SetFileContents("new/p/Enum.aidl",
2077                                "package p;"
2078                                "enum Enum {"
2079                                "  BAR = 2,"
2080                                "  FOO = 1,"
2081                                "}");
2082   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2083 }
2084 
TEST_F(AidlTestCompatibleChanges,NewUnionField)2085 TEST_F(AidlTestCompatibleChanges, NewUnionField) {
2086   io_delegate_.SetFileContents("old/p/Union.aidl",
2087                                "package p;"
2088                                "union Union {"
2089                                "  String foo;"
2090                                "}");
2091   io_delegate_.SetFileContents("new/p/Union.aidl",
2092                                "package p;"
2093                                "union Union {"
2094                                "  String foo;"
2095                                "  int num;"
2096                                "}");
2097   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2098 }
2099 
TEST_F(AidlTestCompatibleChanges,NewPackage)2100 TEST_F(AidlTestCompatibleChanges, NewPackage) {
2101   io_delegate_.SetFileContents("old/p/IFoo.aidl",
2102                                "package p;"
2103                                "interface IFoo {"
2104                                "  void foo(int a);"
2105                                "}");
2106   io_delegate_.SetFileContents("old/p/Data.aidl",
2107                                "package p;"
2108                                "parcelable Data {"
2109                                "  int foo;"
2110                                "}");
2111   io_delegate_.SetFileContents("new/p/IFoo.aidl",
2112                                "package p;"
2113                                "interface IFoo {"
2114                                "  void foo(int a);"
2115                                "}");
2116   io_delegate_.SetFileContents("new/p/Data.aidl",
2117                                "package p;"
2118                                "parcelable Data {"
2119                                "  int foo;"
2120                                "}");
2121   io_delegate_.SetFileContents("new/q/IFoo.aidl",
2122                                "package q;"
2123                                "interface IFoo {"
2124                                "  void foo(int a);"
2125                                "}");
2126   io_delegate_.SetFileContents("new/q/Data.aidl",
2127                                "package q;"
2128                                "parcelable Data {"
2129                                "  int foo;"
2130                                "}");
2131   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2132 }
2133 
TEST_F(AidlTestCompatibleChanges,ArgNameChange)2134 TEST_F(AidlTestCompatibleChanges, ArgNameChange) {
2135   io_delegate_.SetFileContents("old/p/IFoo.aidl",
2136                                "package p;"
2137                                "interface IFoo {"
2138                                "  void foo(int a);"
2139                                "}");
2140   io_delegate_.SetFileContents("new/p/IFoo.aidl",
2141                                "package p;"
2142                                "interface IFoo {"
2143                                "  void foo(int b);"
2144                                "}");
2145   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2146 }
2147 
TEST_F(AidlTestCompatibleChanges,AddedConstValue)2148 TEST_F(AidlTestCompatibleChanges, AddedConstValue) {
2149   io_delegate_.SetFileContents("old/p/I.aidl",
2150                                "package p; interface I {"
2151                                "const int A = 1; }");
2152   io_delegate_.SetFileContents("new/p/I.aidl",
2153                                "package p ; interface I {"
2154                                "const int A = 1; const int B = 2;}");
2155   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2156 }
2157 
TEST_F(AidlTestCompatibleChanges,ChangedConstValueOrder)2158 TEST_F(AidlTestCompatibleChanges, ChangedConstValueOrder) {
2159   io_delegate_.SetFileContents("old/p/I.aidl",
2160                                "package p; interface I {"
2161                                "const int A = 1; const int B = 2;}");
2162   io_delegate_.SetFileContents("new/p/I.aidl",
2163                                "package p ; interface I {"
2164                                "const int B = 2; const int A = 1;}");
2165   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2166 }
2167 
TEST_F(AidlTestCompatibleChanges,ReorderedAnnatations)2168 TEST_F(AidlTestCompatibleChanges, ReorderedAnnatations) {
2169   io_delegate_.SetFileContents("old/p/Foo.aidl",
2170                                "package p;"
2171                                "@JavaPassthrough(annotation=\"Alice\")"
2172                                "@JavaPassthrough(annotation=\"Bob\")"
2173                                "parcelable Foo {}");
2174   io_delegate_.SetFileContents("new/p/Foo.aidl",
2175                                "package p;"
2176                                "@JavaPassthrough(annotation=\"Bob\")"
2177                                "@JavaPassthrough(annotation=\"Alice\")"
2178                                "parcelable Foo {}");
2179   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2180 }
2181 
TEST_F(AidlTestCompatibleChanges,OkayToDeprecate)2182 TEST_F(AidlTestCompatibleChanges, OkayToDeprecate) {
2183   io_delegate_.SetFileContents("old/p/Foo.aidl",
2184                                "package p;"
2185                                "parcelable Foo {}");
2186   io_delegate_.SetFileContents("new/p/Foo.aidl",
2187                                "package p;"
2188                                "@JavaPassthrough(annotation=\"@Deprecated\")"
2189                                "parcelable Foo {}");
2190   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2191 }
2192 
TEST_F(AidlTestCompatibleChanges,NewFieldOfNewType)2193 TEST_F(AidlTestCompatibleChanges, NewFieldOfNewType) {
2194   io_delegate_.SetFileContents("old/p/Data.aidl",
2195                                "package p;"
2196                                "parcelable Data {"
2197                                "  int num;"
2198                                "}");
2199   io_delegate_.SetFileContents(
2200       "new/p/Data.aidl",
2201       "package p;"
2202       "parcelable Data {"
2203       "  int num;"
2204       "  p.Enum e;"  // this is considered as valid since 0(enum default) is valid for "Enum" type
2205       "}");
2206   io_delegate_.SetFileContents("new/p/Enum.aidl",
2207                                "package p;"
2208                                "enum Enum {"
2209                                "  FOO = 0,"
2210                                "  BAR = 1,"
2211                                "}");
2212   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2213 }
2214 
TEST_F(AidlTestCompatibleChanges,CompatibleExplicitDefaults)2215 TEST_F(AidlTestCompatibleChanges, CompatibleExplicitDefaults) {
2216   io_delegate_.SetFileContents("old/p/Data.aidl",
2217                                "package p;\n"
2218                                "parcelable Data {\n"
2219                                "  p.Enum e;\n"
2220                                "}");
2221   io_delegate_.SetFileContents("old/p/Enum.aidl",
2222                                "package p;\n"
2223                                "enum Enum {\n"
2224                                "  FOO = 0,\n"
2225                                "  BAR = 1,\n"
2226                                "}");
2227   io_delegate_.SetFileContents("new/p/Data.aidl",
2228                                "package p;\n"
2229                                "parcelable Data {\n"
2230                                "  p.Enum e = p.Enum.FOO;\n"
2231                                "}");
2232   io_delegate_.SetFileContents("new/p/Enum.aidl",
2233                                "package p;\n"
2234                                "enum Enum {\n"
2235                                "  FOO = 0,\n"
2236                                "  BAR = 1,\n"
2237                                "}");
2238   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
2239 }
2240 
2241 class AidlTestIncompatibleChanges : public AidlTest {
2242  protected:
2243   Options options_ = Options::From("aidl --checkapi old new");
2244 };
2245 
TEST_F(AidlTestIncompatibleChanges,RemovedType)2246 TEST_F(AidlTestIncompatibleChanges, RemovedType) {
2247   const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
2248   io_delegate_.SetFileContents("old/p/IFoo.aidl",
2249                                "package p;"
2250                                "interface IFoo {"
2251                                "  void foo(in String[] str);"
2252                                "  void bar(@utf8InCpp String str);"
2253                                "}");
2254   CaptureStderr();
2255   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2256   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2257 }
2258 
TEST_F(AidlTestIncompatibleChanges,RemovedMethod)2259 TEST_F(AidlTestIncompatibleChanges, RemovedMethod) {
2260   const string expected_stderr =
2261       "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
2262   io_delegate_.SetFileContents("old/p/IFoo.aidl",
2263                                "package p;"
2264                                "interface IFoo {"
2265                                "  void foo(in String[] str);"
2266                                "  void bar(@utf8InCpp String str);"
2267                                "}");
2268   io_delegate_.SetFileContents("new/p/IFoo.aidl",
2269                                "package p;"
2270                                "interface IFoo {"
2271                                "  void foo(in String[] str);"
2272                                "}");
2273   CaptureStderr();
2274   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2275   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2276 }
2277 
TEST_F(AidlTestIncompatibleChanges,UntypedListInInterface)2278 TEST_F(AidlTestIncompatibleChanges, UntypedListInInterface) {
2279   const string expected_stderr =
2280       "ERROR: new/p/IFoo.aidl:1.61-65: "
2281       "Encountered an untyped List or Map. The use of untyped List/Map is "
2282       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
2283       "the receiving side. Consider switching to an array or a generic List/Map.\n"
2284       "ERROR: new/p/IFoo.aidl: Failed to read.\n";
2285   io_delegate_.SetFileContents("old/p/IFoo.aidl",
2286                                "package p;"
2287                                "interface IFoo {"
2288                                "  void foo(in String[] str);"
2289                                "}");
2290   io_delegate_.SetFileContents("new/p/IFoo.aidl",
2291                                "package p;"
2292                                "interface IFoo {"
2293                                "  void foo(in String[] str);"
2294                                "  void bar(in List arg);"
2295                                "}");
2296   CaptureStderr();
2297   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2298   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2299 }
2300 
TEST_F(AidlTestCompatibleChanges,UntypedListInParcelable)2301 TEST_F(AidlTestCompatibleChanges, UntypedListInParcelable) {
2302   const string expected_stderr =
2303       "ERROR: new/p/Data.aidl:1.54-59: "
2304       "Encountered an untyped List or Map. The use of untyped List/Map is "
2305       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
2306       "the receiving side. Consider switching to an array or a generic List/Map.\n"
2307       "ERROR: new/p/Data.aidl: Failed to read.\n";
2308   io_delegate_.SetFileContents("old/p/Data.aidl",
2309                                "package p;"
2310                                "parcelable Data {"
2311                                "  int foo;"
2312                                "}");
2313   io_delegate_.SetFileContents("new/p/Data.aidl",
2314                                "package p;"
2315                                "parcelable Data {"
2316                                "  int foo;"
2317                                "  @nullable List list;"
2318                                "}");
2319   CaptureStderr();
2320   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2321   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2322 }
2323 
TEST_F(AidlTestIncompatibleChanges,RemovedField)2324 TEST_F(AidlTestIncompatibleChanges, RemovedField) {
2325   const string expected_stderr =
2326       "ERROR: new/p/Data.aidl:1.21-26: Number of fields in p.Data is reduced from 2 to 1.\n";
2327   io_delegate_.SetFileContents("old/p/Data.aidl",
2328                                "package p;"
2329                                "parcelable Data {"
2330                                "  int foo;"
2331                                "  int bar;"
2332                                "}");
2333   io_delegate_.SetFileContents("new/p/Data.aidl",
2334                                "package p;"
2335                                "parcelable Data {"
2336                                "  int foo;"
2337                                "}");
2338   CaptureStderr();
2339   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2340   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2341 }
2342 
TEST_F(AidlTestIncompatibleChanges,NewFieldWithNoDefault)2343 TEST_F(AidlTestIncompatibleChanges, NewFieldWithNoDefault) {
2344   const string expected_stderr =
2345       "ERROR: new/p/Data.aidl:1.46-50: Field 'str' does not have a useful default in some "
2346       "backends. Please either provide a default value for this field or mark the field as "
2347       "@nullable. This value or a null value will be used automatically when an old version of "
2348       "this parcelable is sent to a process which understands a new version of this parcelable. In "
2349       "order to make sure your code continues to be backwards compatible, make sure the default or "
2350       "null value does not cause a semantic change to this parcelable.\n";
2351   io_delegate_.SetFileContents("old/p/Data.aidl",
2352                                "package p;"
2353                                "parcelable Data {"
2354                                "  int num;"
2355                                "}");
2356   io_delegate_.SetFileContents("new/p/Data.aidl",
2357                                "package p;"
2358                                "parcelable Data {"
2359                                "  int num;"
2360                                "  String str;"
2361                                "}");
2362   CaptureStderr();
2363   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2364   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2365 }
2366 
TEST_F(AidlTestIncompatibleChanges,NewFieldWithNonZeroEnum)2367 TEST_F(AidlTestIncompatibleChanges, NewFieldWithNonZeroEnum) {
2368   const string expected_stderr =
2369       "ERROR: new/p/Data.aidl:1.46-48: Field 'e' of enum 'Enum' can't be initialized as '0'. "
2370       "Please make sure 'Enum' has '0' as a valid value.\n";
2371   io_delegate_.SetFileContents("old/p/Data.aidl",
2372                                "package p;"
2373                                "parcelable Data {"
2374                                "  int num;"
2375                                "}");
2376   io_delegate_.SetFileContents("new/p/Data.aidl",
2377                                "package p;"
2378                                "parcelable Data {"
2379                                "  int num;"
2380                                "  p.Enum e;"
2381                                "}");
2382   io_delegate_.SetFileContents("new/p/Enum.aidl",
2383                                "package p;"
2384                                "enum Enum {"
2385                                "  FOO = 1,"
2386                                "  BAR = 2,"
2387                                "}");
2388   CaptureStderr();
2389   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2390   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2391 }
2392 
TEST_F(AidlTestIncompatibleChanges,RemovedEnumerator)2393 TEST_F(AidlTestIncompatibleChanges, RemovedEnumerator) {
2394   const string expected_stderr =
2395       "ERROR: new/p/Enum.aidl:1.15-20: Removed enumerator from p.Enum: FOO\n";
2396   io_delegate_.SetFileContents("old/p/Enum.aidl",
2397                                "package p;"
2398                                "enum Enum {"
2399                                "  FOO = 1,"
2400                                "  BAR = 2,"
2401                                "}");
2402   io_delegate_.SetFileContents("new/p/Enum.aidl",
2403                                "package p;"
2404                                "enum Enum {"
2405                                "  BAR = 2,"
2406                                "}");
2407   CaptureStderr();
2408   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2409   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2410 }
2411 
TEST_F(AidlTestIncompatibleChanges,RemovedUnionField)2412 TEST_F(AidlTestIncompatibleChanges, RemovedUnionField) {
2413   const string expected_stderr =
2414       "ERROR: new/p/Union.aidl:1.16-22: Number of fields in p.Union is reduced from 2 to 1.\n";
2415   io_delegate_.SetFileContents("old/p/Union.aidl",
2416                                "package p;"
2417                                "union Union {"
2418                                "  String str;"
2419                                "  int num;"
2420                                "}");
2421   io_delegate_.SetFileContents("new/p/Union.aidl",
2422                                "package p;"
2423                                "union Union {"
2424                                "  String str;"
2425                                "}");
2426   CaptureStderr();
2427   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2428   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2429 }
2430 
TEST_F(AidlTestIncompatibleChanges,RenamedMethod)2431 TEST_F(AidlTestIncompatibleChanges, RenamedMethod) {
2432   const string expected_stderr =
2433       "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
2434   io_delegate_.SetFileContents("old/p/IFoo.aidl",
2435                                "package p;"
2436                                "interface IFoo {"
2437                                "  void foo(in String[] str);"
2438                                "  void bar(@utf8InCpp String str);"
2439                                "}");
2440   io_delegate_.SetFileContents("new/p/IFoo.aidl",
2441                                "package p;"
2442                                "interface IFoo {"
2443                                "  void foo(in String[] str);"
2444                                "  void bar2(@utf8InCpp String str);"
2445                                "}");
2446   CaptureStderr();
2447   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2448   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2449 }
2450 
TEST_F(AidlTestIncompatibleChanges,RenamedType)2451 TEST_F(AidlTestIncompatibleChanges, RenamedType) {
2452   const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
2453   io_delegate_.SetFileContents("old/p/IFoo.aidl",
2454                                "package p;"
2455                                "interface IFoo {"
2456                                "  void foo(in String[] str);"
2457                                "  void bar(@utf8InCpp String str);"
2458                                "}");
2459   io_delegate_.SetFileContents("new/p/IFoo2.aidl",
2460                                "package p;"
2461                                "interface IFoo2 {"
2462                                "  void foo(in String[] str);"
2463                                "  void bar(@utf8InCpp String str);"
2464                                "}");
2465   CaptureStderr();
2466   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2467   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2468 }
2469 
TEST_F(AidlTestIncompatibleChanges,ChangedEnumerator)2470 TEST_F(AidlTestIncompatibleChanges, ChangedEnumerator) {
2471   const string expected_stderr =
2472       "ERROR: new/p/Enum.aidl:1.15-20: Changed enumerator value: p.Enum::FOO from 1 to 3.\n";
2473   io_delegate_.SetFileContents("old/p/Enum.aidl",
2474                                "package p;"
2475                                "enum Enum {"
2476                                "  FOO = 1,"
2477                                "  BAR = 2,"
2478                                "}");
2479   io_delegate_.SetFileContents("new/p/Enum.aidl",
2480                                "package p;"
2481                                "enum Enum {"
2482                                "  FOO = 3,"
2483                                "  BAR = 2,"
2484                                "}");
2485   CaptureStderr();
2486   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2487   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2488 }
2489 
TEST_F(AidlTestIncompatibleChanges,ReorderedMethod)2490 TEST_F(AidlTestIncompatibleChanges, ReorderedMethod) {
2491   const string expected_stderr =
2492       "ERROR: new/p/IFoo.aidl:1.67-71: Transaction ID changed: p.IFoo.foo(String[]) is changed "
2493       "from 0 to 1.\n"
2494       "ERROR: new/p/IFoo.aidl:1.33-37: Transaction ID changed: p.IFoo.bar(String) is changed from "
2495       "1 to 0.\n";
2496   io_delegate_.SetFileContents("old/p/IFoo.aidl",
2497                                "package p;"
2498                                "interface IFoo {"
2499                                "  void foo(in String[] str);"
2500                                "  void bar(@utf8InCpp String str);"
2501                                "}");
2502   io_delegate_.SetFileContents("new/p/IFoo.aidl",
2503                                "package p;"
2504                                "interface IFoo {"
2505                                "  void bar(@utf8InCpp String str);"
2506                                "  void foo(in String[] str);"
2507                                "}");
2508   CaptureStderr();
2509   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2510   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2511 }
2512 
TEST_F(AidlTestIncompatibleChanges,ReorderedField)2513 TEST_F(AidlTestIncompatibleChanges, ReorderedField) {
2514   const string expected_stderr =
2515       "ERROR: new/p/Data.aidl:1.33-37: Reordered bar from 1 to 0.\n"
2516       "ERROR: new/p/Data.aidl:1.43-47: Reordered foo from 0 to 1.\n";
2517   io_delegate_.SetFileContents("old/p/Data.aidl",
2518                                "package p;"
2519                                "parcelable Data {"
2520                                "  int foo;"
2521                                "  int bar;"
2522                                "}");
2523   io_delegate_.SetFileContents("new/p/Data.aidl",
2524                                "package p;"
2525                                "parcelable Data {"
2526                                "  int bar;"
2527                                "  int foo;"
2528                                "}");
2529   CaptureStderr();
2530   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2531   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2532 }
2533 
TEST_F(AidlTestIncompatibleChanges,ChangedDirectionSpecifier)2534 TEST_F(AidlTestIncompatibleChanges, ChangedDirectionSpecifier) {
2535   const string expected_stderr = "ERROR: new/p/IFoo.aidl:1.33-37: Direction changed: in to out.\n";
2536   io_delegate_.SetFileContents("old/p/IFoo.aidl",
2537                                "package p;"
2538                                "interface IFoo {"
2539                                "  void foo(in String[] str);"
2540                                "  void bar(@utf8InCpp String str);"
2541                                "}");
2542   io_delegate_.SetFileContents("new/p/IFoo.aidl",
2543                                "package p;"
2544                                "interface IFoo {"
2545                                "  void foo(out String[] str);"
2546                                "  void bar(@utf8InCpp String str);"
2547                                "}");
2548   CaptureStderr();
2549   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2550   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2551 }
2552 
TEST_F(AidlTestIncompatibleChanges,AddedAnnotation)2553 TEST_F(AidlTestIncompatibleChanges, AddedAnnotation) {
2554   const string expected_stderr =
2555       "ERROR: new/p/IFoo.aidl:1.51-58: Changed annotations: (empty) to @utf8InCpp\n";
2556   io_delegate_.SetFileContents("old/p/IFoo.aidl",
2557                                "package p;"
2558                                "interface IFoo {"
2559                                "  void foo(in String[] str);"
2560                                "  void bar(@utf8InCpp String str);"
2561                                "}");
2562   io_delegate_.SetFileContents("new/p/IFoo.aidl",
2563                                "package p;"
2564                                "interface IFoo {"
2565                                "  void foo(in @utf8InCpp String[] str);"
2566                                "  void bar(@utf8InCpp String str);"
2567                                "}");
2568   CaptureStderr();
2569   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2570   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2571 }
2572 
TEST_F(AidlTestIncompatibleChanges,RemovedAnnotation)2573 TEST_F(AidlTestIncompatibleChanges, RemovedAnnotation) {
2574   const string expected_stderr =
2575       "ERROR: new/p/IFoo.aidl:1.66-72: Changed annotations: @utf8InCpp to (empty)\n";
2576   io_delegate_.SetFileContents("old/p/IFoo.aidl",
2577                                "package p;"
2578                                "interface IFoo {"
2579                                "  void foo(in String[] str);"
2580                                "  void bar(@utf8InCpp String str);"
2581                                "}");
2582   io_delegate_.SetFileContents("new/p/IFoo.aidl",
2583                                "package p;"
2584                                "interface IFoo {"
2585                                "  void foo(in String[] str);"
2586                                "  void bar(String str);"
2587                                "}");
2588   CaptureStderr();
2589   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2590   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2591 }
2592 
TEST_F(AidlTestIncompatibleChanges,ChangedBackingTypeOfEnum)2593 TEST_F(AidlTestIncompatibleChanges, ChangedBackingTypeOfEnum) {
2594   const string expected_stderr =
2595       "ERROR: new/p/Foo.aidl:1.11-32: Type changed: byte to long.\n"
2596       "ERROR: new/p/Foo.aidl:1.36-40: Changed backing types.\n";
2597   io_delegate_.SetFileContents("old/p/Foo.aidl",
2598                                "package p;"
2599                                "@Backing(type=\"byte\")"
2600                                "enum Foo {"
2601                                " FOO, BAR,"
2602                                "}");
2603   io_delegate_.SetFileContents("new/p/Foo.aidl",
2604                                "package p;"
2605                                "@Backing(type=\"long\")"
2606                                "enum Foo {"
2607                                " FOO, BAR,"
2608                                "}");
2609   CaptureStderr();
2610   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2611   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2612 }
2613 
TEST_F(AidlTestIncompatibleChanges,ChangedAnnatationParams)2614 TEST_F(AidlTestIncompatibleChanges, ChangedAnnatationParams) {
2615   const string expected_stderr =
2616       "ERROR: new/p/Foo.aidl:1.55-59: Changed annotations: @JavaPassthrough(annotation=\"Alice\") "
2617       "to @JavaPassthrough(annotation=\"Bob\")\n";
2618   io_delegate_.SetFileContents("old/p/Foo.aidl",
2619                                "package p;"
2620                                "@JavaPassthrough(annotation=\"Alice\")"
2621                                "parcelable Foo {}");
2622   io_delegate_.SetFileContents("new/p/Foo.aidl",
2623                                "package p;"
2624                                "@JavaPassthrough(annotation=\"Bob\")"
2625                                "parcelable Foo {}");
2626 
2627   CaptureStderr();
2628   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2629   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2630 }
2631 
TEST_F(AidlTestIncompatibleChanges,AddedParcelableAnnotation)2632 TEST_F(AidlTestIncompatibleChanges, AddedParcelableAnnotation) {
2633   const string expected_stderr =
2634       "ERROR: new/p/Foo.aidl:1.32-36: Changed annotations: (empty) to @FixedSize\n";
2635   io_delegate_.SetFileContents("old/p/Foo.aidl",
2636                                "package p;"
2637                                "parcelable Foo {"
2638                                "  int A;"
2639                                "}");
2640   io_delegate_.SetFileContents("new/p/Foo.aidl",
2641                                "package p;"
2642                                "@FixedSize parcelable Foo {"
2643                                "  int A;"
2644                                "}");
2645   CaptureStderr();
2646   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2647   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2648 }
2649 
TEST_F(AidlTestIncompatibleChanges,RemovedParcelableAnnotation)2650 TEST_F(AidlTestIncompatibleChanges, RemovedParcelableAnnotation) {
2651   const string expected_stderr =
2652       "ERROR: new/p/Foo.aidl:1.21-25: Changed annotations: @FixedSize to (empty)\n";
2653   io_delegate_.SetFileContents("old/p/Foo.aidl",
2654                                "package p;"
2655                                "@FixedSize parcelable Foo {"
2656                                "  int A;"
2657                                "}");
2658   io_delegate_.SetFileContents("new/p/Foo.aidl",
2659                                "package p;"
2660                                "parcelable Foo {"
2661                                "  int A;"
2662                                "}");
2663   CaptureStderr();
2664   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2665   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2666 }
2667 
TEST_F(AidlTestIncompatibleChanges,RemovedPackage)2668 TEST_F(AidlTestIncompatibleChanges, RemovedPackage) {
2669   const string expected_stderr = "ERROR: old/q/IFoo.aidl:1.11-21: Removed type: q.IFoo\n";
2670   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{}");
2671   io_delegate_.SetFileContents("old/q/IFoo.aidl", "package q; interface IFoo{}");
2672   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{}");
2673   CaptureStderr();
2674   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2675   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2676 }
2677 
TEST_F(AidlTestIncompatibleChanges,ChangedDefaultValue)2678 TEST_F(AidlTestIncompatibleChanges, ChangedDefaultValue) {
2679   const string expected_stderr = "ERROR: new/p/D.aidl:1.30-32: Changed default value: 1 to 2.\n";
2680   io_delegate_.SetFileContents("old/p/D.aidl", "package p; parcelable D { int a = 1; }");
2681   io_delegate_.SetFileContents("new/p/D.aidl", "package p; parcelable D { int a = 2; }");
2682   CaptureStderr();
2683   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2684   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2685 }
2686 
TEST_F(AidlTestIncompatibleChanges,RemovedConstValue)2687 TEST_F(AidlTestIncompatibleChanges, RemovedConstValue) {
2688   const string expected_stderr =
2689       "ERROR: old/p/I.aidl:1.51-53: Removed constant declaration: p.I.B\n";
2690   io_delegate_.SetFileContents("old/p/I.aidl",
2691                                "package p; interface I {"
2692                                "const int A = 1; const int B = 2;}");
2693   io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 1; }");
2694   CaptureStderr();
2695   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2696   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2697 }
2698 
TEST_F(AidlTestIncompatibleChanges,ChangedConstValue)2699 TEST_F(AidlTestIncompatibleChanges, ChangedConstValue) {
2700   const string expected_stderr =
2701       "ERROR: new/p/I.aidl:1.11-21: Changed constant value: p.I.A from 1 to 2.\n";
2702   io_delegate_.SetFileContents("old/p/I.aidl", "package p; interface I { const int A = 1; }");
2703   io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 2; }");
2704   CaptureStderr();
2705   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2706   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2707 }
2708 
TEST_F(AidlTestIncompatibleChanges,FixedSizeAddedField)2709 TEST_F(AidlTestIncompatibleChanges, FixedSizeAddedField) {
2710   const string expected_stderr =
2711       "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is changed from 1 to 2. "
2712       "This is an incompatible change for FixedSize types.\n";
2713   io_delegate_.SetFileContents("old/p/Foo.aidl",
2714                                "package p; @FixedSize parcelable Foo { int A = 1; }");
2715   io_delegate_.SetFileContents("new/p/Foo.aidl",
2716                                "package p; @FixedSize parcelable Foo { int A = 1; int B = 2; }");
2717   CaptureStderr();
2718   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2719   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2720 }
2721 
TEST_F(AidlTestIncompatibleChanges,UidRangeParcelAddedField)2722 TEST_F(AidlTestIncompatibleChanges, UidRangeParcelAddedField) {
2723   const string expected_stderr =
2724       "ERROR: new/android/net/UidRangeParcel.aidl:1.32-47: Number of fields in "
2725       "android.net.UidRangeParcel is changed from 1 to 2. "
2726       "But it is forbidden because of legacy support.\n";
2727   io_delegate_.SetFileContents("old/android/net/UidRangeParcel.aidl",
2728                                "package android.net; parcelable UidRangeParcel { int A = 1; }");
2729   io_delegate_.SetFileContents(
2730       "new/android/net/UidRangeParcel.aidl",
2731       "package android.net; parcelable UidRangeParcel { int A = 1; int B = 2; }");
2732   CaptureStderr();
2733   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2734   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2735 }
2736 
TEST_F(AidlTestIncompatibleChanges,FixedSizeRemovedField)2737 TEST_F(AidlTestIncompatibleChanges, FixedSizeRemovedField) {
2738   const string expected_stderr =
2739       "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is reduced from 2 to 1.\n";
2740   io_delegate_.SetFileContents("old/p/Foo.aidl",
2741                                "package p; @FixedSize parcelable Foo { int A = 1; int B = 1; }");
2742   io_delegate_.SetFileContents("new/p/Foo.aidl",
2743                                "package p; @FixedSize parcelable Foo { int A = 1; }");
2744   CaptureStderr();
2745   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
2746   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2747 }
2748 
TEST_P(AidlTest,RejectNonFixedSizeFromFixedSize)2749 TEST_P(AidlTest, RejectNonFixedSizeFromFixedSize) {
2750   const string expected_stderr =
2751       "ERROR: Foo.aidl:1.36-38: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2752       "a.\n"
2753       "ERROR: Foo.aidl:1.44-46: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2754       "b.\n"
2755       "ERROR: Foo.aidl:1.55-57: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2756       "c.\n"
2757       "ERROR: Foo.aidl:1.80-82: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2758       "d.\n"
2759       "ERROR: Foo.aidl:1.92-94: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2760       "e.\n"
2761       "ERROR: Foo.aidl:1.109-111: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
2762       "f.\n";
2763 
2764   io_delegate_.SetFileContents("Foo.aidl",
2765                                "@FixedSize parcelable Foo { "
2766                                "  int[] a;"
2767                                "  Bar b;"
2768                                "  String c;"
2769                                "  ParcelFileDescriptor d;"
2770                                "  IBinder e;"
2771                                "  List<String> f;"
2772                                "  int isFixedSize;"
2773                                "}");
2774   io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { int a; }");
2775   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
2776 
2777   CaptureStderr();
2778   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
2779   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2780 }
2781 
TEST_P(AidlTest,AcceptFixedSizeFromFixedSize)2782 TEST_P(AidlTest, AcceptFixedSizeFromFixedSize) {
2783   const string expected_stderr = "";
2784 
2785   io_delegate_.SetFileContents("Foo.aidl", "@FixedSize parcelable Foo { int a; Bar b; }");
2786   io_delegate_.SetFileContents("Bar.aidl", "@FixedSize parcelable Bar { Val c; }");
2787   io_delegate_.SetFileContents("Val.aidl", "enum Val { A, B, }");
2788   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
2789 
2790   CaptureStderr();
2791   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2792   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2793 }
2794 
TEST_F(AidlTest,RejectAmbiguousImports)2795 TEST_F(AidlTest, RejectAmbiguousImports) {
2796   const string expected_stderr =
2797       "ERROR: p/IFoo.aidl: Duplicate files found for q.IBar from:\n"
2798       "dir1/q/IBar.aidl\n"
2799       "dir2/q/IBar.aidl\n"
2800       "ERROR: p/IFoo.aidl: Couldn't find import for class q.IBar\n";
2801   Options options = Options::From("aidl --lang=java -o out -I dir1 -I dir2 p/IFoo.aidl");
2802   io_delegate_.SetFileContents("p/IFoo.aidl", "package p; import q.IBar; interface IFoo{}");
2803   io_delegate_.SetFileContents("dir1/q/IBar.aidl", "package q; interface IBar{}");
2804   io_delegate_.SetFileContents("dir2/q/IBar.aidl", "package q; interface IBar{}");
2805 
2806   CaptureStderr();
2807   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
2808   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2809 }
2810 
TEST_F(AidlTest,HandleManualIdAssignments)2811 TEST_F(AidlTest, HandleManualIdAssignments) {
2812   const string expected_stderr =
2813       "ERROR: new/p/IFoo.aidl:1.32-36: Transaction ID changed: p.IFoo.foo() is changed from 10 to "
2814       "11.\n";
2815   Options options = Options::From("aidl --checkapi old new");
2816   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
2817   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
2818 
2819   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
2820 
2821   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 11;}");
2822   CaptureStderr();
2823   EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
2824   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2825 }
2826 
TEST_P(AidlTest,ParcelFileDescriptorIsBuiltinType)2827 TEST_P(AidlTest, ParcelFileDescriptorIsBuiltinType) {
2828   Options options =
2829       Options::From("aidl --lang=" + to_string(GetLanguage()) + " -h out -o out p/IFoo.aidl");
2830 
2831   // use without import
2832   io_delegate_.SetFileContents("p/IFoo.aidl",
2833                                "package p; interface IFoo{ void foo(in ParcelFileDescriptor fd);}");
2834   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2835 
2836   // capture output files
2837   map<string, string> outputs = io_delegate_.OutputFiles();
2838 
2839   // use without import but with full name
2840   io_delegate_.SetFileContents(
2841       "p/IFoo.aidl",
2842       "package p; interface IFoo{ void foo(in android.os.ParcelFileDescriptor fd);}");
2843   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2844   // output files should be the same
2845   EXPECT_EQ(outputs, io_delegate_.OutputFiles());
2846 
2847   // use with import (as before)
2848   io_delegate_.SetFileContents("p/IFoo.aidl",
2849                                "package p;"
2850                                "import android.os.ParcelFileDescriptor;"
2851                                "interface IFoo{"
2852                                "  void foo(in ParcelFileDescriptor fd);"
2853                                "}");
2854   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2855   // output files should be the same
2856   EXPECT_EQ(outputs, io_delegate_.OutputFiles());
2857 }
2858 
TEST_P(AidlTest,RejectsOutputParcelFileDescriptor)2859 TEST_P(AidlTest, RejectsOutputParcelFileDescriptor) {
2860   Options options = Options::From("aidl p/IFoo.aidl -I . --lang=" + to_string(GetLanguage()));
2861   CaptureStderr();
2862   io_delegate_.SetFileContents("p/IFoo.aidl",
2863                                "package p;"
2864                                "interface IFoo{"
2865                                "  void foo(out ParcelFileDescriptor fd);"
2866                                "}");
2867   EXPECT_EQ(1, ::android::aidl::compile_aidl(options, io_delegate_));
2868   EXPECT_THAT(GetCapturedStderr(), HasSubstr("can't be an out parameter"));
2869 }
2870 
TEST_P(AidlTest,RejectsArgumentDirectionNotSpecified)2871 TEST_P(AidlTest, RejectsArgumentDirectionNotSpecified) {
2872   Options options = Options::From("aidl p/IFoo.aidl -I . --lang=" + to_string(GetLanguage()));
2873   CaptureStderr();
2874   io_delegate_.SetFileContents("p/IFoo.aidl",
2875                                "package p;"
2876                                "interface IFoo{"
2877                                "  void foo(ParcelFileDescriptor fd);"
2878                                "}");
2879   EXPECT_EQ(1, ::android::aidl::compile_aidl(options, io_delegate_));
2880   EXPECT_THAT(GetCapturedStderr(),
2881               HasSubstr("ParcelFileDescriptor can be an in or inout parameter."));
2882 }
2883 
TEST_F(AidlTest,ManualIds)2884 TEST_F(AidlTest, ManualIds) {
2885   Options options = Options::From("aidl --lang=java -o out IFoo.aidl");
2886   io_delegate_.SetFileContents("IFoo.aidl",
2887                                "interface IFoo {\n"
2888                                "  void foo() = 0;\n"
2889                                "  void bar() = 1;\n"
2890                                "}");
2891   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2892 }
2893 
TEST_F(AidlTest,ManualIdsWithMetaTransactions)2894 TEST_F(AidlTest, ManualIdsWithMetaTransactions) {
2895   Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
2896   io_delegate_.SetFileContents("IFoo.aidl",
2897                                "interface IFoo {\n"
2898                                "  void foo() = 0;\n"
2899                                "  void bar() = 1;\n"
2900                                "}");
2901   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2902 }
2903 
TEST_F(AidlTest,FailOnDuplicatedIds)2904 TEST_F(AidlTest, FailOnDuplicatedIds) {
2905   const string expected_stderr =
2906       "ERROR: IFoo.aidl:3.7-11: Found duplicate method id (3) for method bar\n";
2907   Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
2908   io_delegate_.SetFileContents("IFoo.aidl",
2909                                "interface IFoo {\n"
2910                                "  void foo() = 3;\n"
2911                                "  void bar() = 3;\n"
2912                                "}");
2913   CaptureStderr();
2914   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
2915   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2916 }
2917 
TEST_F(AidlTest,FailOnOutOfRangeIds)2918 TEST_F(AidlTest, FailOnOutOfRangeIds) {
2919   // 16777115 is kLastMetaMethodId + 1
2920   const string expected_stderr =
2921       "ERROR: IFoo.aidl:3.7-11: Found out of bounds id (16777115) for method bar. "
2922       "Value for id must be between 0 and 16777114 inclusive.\n";
2923   Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
2924   io_delegate_.SetFileContents("IFoo.aidl",
2925                                "interface IFoo {\n"
2926                                "  void foo() = 3;\n"
2927                                "  void bar() = 16777115;\n"
2928                                "}");
2929   CaptureStderr();
2930   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
2931   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2932 }
2933 
TEST_F(AidlTest,FailOnPartiallyAssignedIds)2934 TEST_F(AidlTest, FailOnPartiallyAssignedIds) {
2935   const string expected_stderr =
2936       "ERROR: IFoo.aidl:3.7-11: You must either assign id's to all methods or to none of them.\n";
2937   Options options = Options::From("aidl --lang=java --version 10 -o out IFoo.aidl");
2938   io_delegate_.SetFileContents("IFoo.aidl",
2939                                "interface IFoo {\n"
2940                                "  void foo() = 3;\n"
2941                                "  void bar();\n"
2942                                "}");
2943   CaptureStderr();
2944   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
2945   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2946 }
2947 
TEST_F(AidlTest,AllowDuplicatedImportPaths)2948 TEST_F(AidlTest, AllowDuplicatedImportPaths) {
2949   Options options = Options::From("aidl --lang=java -I dir -I dir IFoo.aidl");
2950   io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
2951   io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
2952   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2953 }
2954 
TEST_F(AidlTest,FailOnAmbiguousImports)2955 TEST_F(AidlTest, FailOnAmbiguousImports) {
2956   const string expected_stderr =
2957       "ERROR: IFoo.aidl: Duplicate files found for IBar from:\n"
2958       "dir/IBar.aidl\n"
2959       "dir2/IBar.aidl\n"
2960       "ERROR: IFoo.aidl: Couldn't find import for class IBar\n";
2961 
2962   Options options = Options::From("aidl --lang=java -I dir -I dir2 IFoo.aidl");
2963   io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
2964   io_delegate_.SetFileContents("dir2/IBar.aidl", "interface IBar{}");
2965   io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
2966   CaptureStderr();
2967   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
2968   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2969 }
2970 
TEST_F(AidlTest,UnusedImportDoesNotContributeInclude)2971 TEST_F(AidlTest, UnusedImportDoesNotContributeInclude) {
2972   io_delegate_.SetFileContents("a/b/IFoo.aidl",
2973                                "package a.b;\n"
2974                                "import a.b.IBar;\n"
2975                                "import a.b.IQux;\n"
2976                                "interface IFoo { IQux foo(); }\n");
2977   io_delegate_.SetFileContents("a/b/IBar.aidl", "package a.b; interface IBar { void foo(); }");
2978   io_delegate_.SetFileContents("a/b/IQux.aidl", "package a.b; interface IQux { void foo(); }");
2979 
2980   Options options = Options::From("aidl --lang=ndk a/b/IFoo.aidl -I . -o out -h out/include");
2981   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
2982 
2983   string output;
2984   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/include/aidl/a/b/IFoo.h", &output));
2985   // IBar was imported but wasn't used. include is not expected.
2986   EXPECT_THAT(output, Not(testing::HasSubstr("#include <aidl/a/b/IBar.h>")));
2987   // IBar was imported and used. include is expected.
2988   EXPECT_THAT(output, (testing::HasSubstr("#include <aidl/a/b/IQux.h>")));
2989 }
2990 
TEST_F(AidlTest,ParseJavaPassthroughAnnotation)2991 TEST_F(AidlTest, ParseJavaPassthroughAnnotation) {
2992   io_delegate_.SetFileContents("a/IFoo.aidl", R"--(package a;
2993     import a.MyEnum;
2994     @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
2995     @JavaPassthrough(annotation="@com.android.AliceTwo")
2996     interface IFoo {
2997         @JavaPassthrough(annotation="@com.android.Bob")
2998         void foo(@JavaPassthrough(annotation="@com.android.Cat") int x, MyEnum y);
2999         const @JavaPassthrough(annotation="@com.android.David") int A = 3;
3000     })--");
3001   // JavaPassthrough should work with other types as well (e.g. enum)
3002   io_delegate_.SetFileContents("a/MyEnum.aidl", R"--(package a;
3003     @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
3004     @JavaPassthrough(annotation="@com.android.AliceTwo")
3005     @Backing(type="byte")
3006     enum MyEnum {
3007       a, b, c
3008     })--");
3009 
3010   Options java_options = Options::From("aidl -I . --lang=java -o out a/IFoo.aidl a/MyEnum.aidl");
3011   EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
3012 
3013   string java_out;
3014   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/IFoo.java", &java_out));
3015   // type-decl-level annotations with newline at the end
3016   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
3017   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
3018   // member-decl-level annotations with newline at the end
3019   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Bob\n"));
3020   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.David\n"));
3021   // inline annotations with space at the end
3022   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Cat "));
3023 
3024   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/MyEnum.java", &java_out));
3025   // type-decl-level annotations with newline at the end
3026   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
3027   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
3028 
3029   // Other backends shouldn't be bothered
3030   Options cpp_options =
3031       Options::From("aidl -I . --lang=cpp -o out -h out a/IFoo.aidl a/MyEnum.aidl");
3032   EXPECT_EQ(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
3033 
3034   Options ndk_options =
3035       Options::From("aidl -I . --lang=ndk -o out -h out a/IFoo.aidl a/MyEnum.aidl");
3036   EXPECT_EQ(0, ::android::aidl::compile_aidl(ndk_options, io_delegate_));
3037 
3038   Options rust_options = Options::From("aidl -I . --lang=rust -o out a/IFoo.aidl a/MyEnum.aidl");
3039   EXPECT_EQ(0, ::android::aidl::compile_aidl(rust_options, io_delegate_));
3040 }
3041 
TEST_F(AidlTest,ParseRustDerive)3042 TEST_F(AidlTest, ParseRustDerive) {
3043   io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
3044     @RustDerive(Clone=true, Copy=false)
3045     parcelable Foo {
3046         int a;
3047     })");
3048 
3049   Options rust_options = Options::From("aidl --lang=rust -o out a/Foo.aidl");
3050   EXPECT_EQ(0, ::android::aidl::compile_aidl(rust_options, io_delegate_));
3051 
3052   string rust_out;
3053   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.rs", &rust_out));
3054   EXPECT_THAT(rust_out, testing::HasSubstr("#[derive(Debug, Clone)]"));
3055 
3056   // Other backends shouldn't be bothered
3057   Options cpp_options = Options::From("aidl --lang=cpp -o out -h out a/Foo.aidl");
3058   EXPECT_EQ(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
3059 
3060   Options ndk_options = Options::From("aidl --lang=ndk -o out -h out a/Foo.aidl");
3061   EXPECT_EQ(0, ::android::aidl::compile_aidl(ndk_options, io_delegate_));
3062 
3063   Options java_options = Options::From("aidl --lang=java -o out a/Foo.aidl");
3064   EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
3065 }
3066 
3067 class AidlOutputPathTest : public AidlTest {
3068  protected:
SetUp()3069   void SetUp() override {
3070     AidlTest::SetUp();
3071     io_delegate_.SetFileContents("sub/dir/foo/bar/IFoo.aidl", "package foo.bar; interface IFoo {}");
3072   }
3073 
Test(const Options & options,const std::string expected_output_path)3074   void Test(const Options& options, const std::string expected_output_path) {
3075     EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3076     // check the existence
3077     EXPECT_TRUE(io_delegate_.GetWrittenContents(expected_output_path, nullptr));
3078   }
3079 };
3080 
TEST_F(AidlOutputPathTest,OutDirWithNoOutputFile)3081 TEST_F(AidlOutputPathTest, OutDirWithNoOutputFile) {
3082   // <out_dir> / <package_name> / <type_name>.java
3083   Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl"), "out/foo/bar/IFoo.java");
3084 }
3085 
TEST_F(AidlOutputPathTest,OutDirWithOutputFile)3086 TEST_F(AidlOutputPathTest, OutDirWithOutputFile) {
3087   // when output file is explicitly set, it is always respected. -o option is
3088   // ignored.
3089   Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"), "output/IFoo.java");
3090 }
3091 
TEST_F(AidlOutputPathTest,NoOutDirWithOutputFile)3092 TEST_F(AidlOutputPathTest, NoOutDirWithOutputFile) {
3093   Test(Options::From("aidl -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"), "output/IFoo.java");
3094 }
3095 
TEST_F(AidlOutputPathTest,NoOutDirWithNoOutputFile)3096 TEST_F(AidlOutputPathTest, NoOutDirWithNoOutputFile) {
3097   // output is the same as the input file except for the suffix
3098   Test(Options::From("aidl sub/dir/foo/bar/IFoo.aidl"), "sub/dir/foo/bar/IFoo.java");
3099 }
3100 
TEST_P(AidlTest,FailOnOutOfBoundsInt32MaxConstInt)3101 TEST_P(AidlTest, FailOnOutOfBoundsInt32MaxConstInt) {
3102   AidlError error;
3103   const string expected_stderr =
3104       "ERROR: p/IFoo.aidl:3.58-69: Invalid type specifier for an int64 literal: int\n";
3105   CaptureStderr();
3106   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3107                            R"(package p;
3108                               interface IFoo {
3109                                 const int int32_max_oob = 2147483650;
3110                               }
3111                              )",
3112                            typenames_, GetLanguage(), &error));
3113   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3114   EXPECT_EQ(AidlError::BAD_TYPE, error);
3115 }
3116 
TEST_P(AidlTest,FailOnOutOfBoundsInt32MinConstInt)3117 TEST_P(AidlTest, FailOnOutOfBoundsInt32MinConstInt) {
3118   AidlError error;
3119   const string expected_stderr =
3120       "ERROR: p/IFoo.aidl:3.58-60: Invalid type specifier for an int64 literal: int\n";
3121   CaptureStderr();
3122   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3123                            R"(package p;
3124                               interface IFoo {
3125                                 const int int32_min_oob = -2147483650;
3126                               }
3127                              )",
3128                            typenames_, GetLanguage(), &error));
3129   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3130   EXPECT_EQ(AidlError::BAD_TYPE, error);
3131 }
3132 
TEST_P(AidlTest,FailOnOutOfBoundsInt64MaxConstInt)3133 TEST_P(AidlTest, FailOnOutOfBoundsInt64MaxConstInt) {
3134   AidlError error;
3135   const string expected_stderr =
3136       "ERROR: p/IFoo.aidl:3.59-86: Could not parse integer: 21474836509999999999999999\n";
3137   CaptureStderr();
3138   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3139                            R"(package p;
3140                               interface IFoo {
3141                                 const long int64_max_oob = 21474836509999999999999999;
3142                               }
3143                              )",
3144                            typenames_, GetLanguage(), &error));
3145   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3146   EXPECT_EQ(AidlError::PARSE_ERROR, error);
3147 }
3148 
TEST_P(AidlTest,FailOnOutOfBoundsInt64MinConstInt)3149 TEST_P(AidlTest, FailOnOutOfBoundsInt64MinConstInt) {
3150   AidlError error;
3151   const string expected_stderr =
3152       "ERROR: p/IFoo.aidl:3.61-87: Could not parse integer: 21474836509999999999999999\n";
3153   CaptureStderr();
3154   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
3155                            R"(package p;
3156                               interface IFoo {
3157                                 const long int64_min_oob = -21474836509999999999999999;
3158                               }
3159                              )",
3160                            typenames_, GetLanguage(), &error));
3161   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3162   EXPECT_EQ(AidlError::PARSE_ERROR, error);
3163 }
3164 
TEST_P(AidlTest,FailOnOutOfBoundsAutofilledEnum)3165 TEST_P(AidlTest, FailOnOutOfBoundsAutofilledEnum) {
3166   AidlError error;
3167   const string expected_stderr =
3168       "ERROR: p/TestEnum.aidl:5.1-36: Invalid type specifier for an int32 literal: byte\n"
3169       "ERROR: p/TestEnum.aidl:5.1-36: Enumerator type differs from enum backing type.\n";
3170   CaptureStderr();
3171   EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
3172                            R"(package p;
3173                               @Backing(type="byte")
3174                               enum TestEnum {
3175                                 FOO = 127,
3176                                 BAR,
3177                               }
3178                              )",
3179                            typenames_, GetLanguage(), &error));
3180   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3181   EXPECT_EQ(AidlError::BAD_TYPE, error);
3182 }
3183 
TEST_P(AidlTest,UnsupportedBackingAnnotationParam)3184 TEST_P(AidlTest, UnsupportedBackingAnnotationParam) {
3185   AidlError error;
3186   const string expected_stderr =
3187       "ERROR: p/TestEnum.aidl:2.1-51: Parameter foo not supported for annotation Backing. It must "
3188       "be one of: type\n";
3189   CaptureStderr();
3190   EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
3191                            R"(package p;
3192                               @Backing(foo="byte")
3193                               enum TestEnum {
3194                                 FOO = 1,
3195                                 BAR,
3196                               }
3197                              )",
3198                            typenames_, GetLanguage(), &error));
3199   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3200   EXPECT_EQ(AidlError::BAD_TYPE, error);
3201 }
3202 
TEST_P(AidlTest,BackingAnnotationRequireTypeParameter)3203 TEST_P(AidlTest, BackingAnnotationRequireTypeParameter) {
3204   const string expected_stderr = "ERROR: Enum.aidl:1.1-9: Missing 'type' on @Backing.\n";
3205   CaptureStderr();
3206   EXPECT_EQ(nullptr, Parse("Enum.aidl", "@Backing enum Enum { FOO }", typenames_, GetLanguage()));
3207   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3208 }
3209 
TEST_F(AidlTest,SupportJavaOnlyImmutableAnnotation)3210 TEST_F(AidlTest, SupportJavaOnlyImmutableAnnotation) {
3211   io_delegate_.SetFileContents("Foo.aidl",
3212                                "@JavaOnlyImmutable parcelable Foo { int a; Bar b; List<Bar> c; "
3213                                "Map<String, Baz> d; Bar[] e; }");
3214   io_delegate_.SetFileContents("Bar.aidl", "@JavaOnlyImmutable parcelable Bar { String a; }");
3215   io_delegate_.SetFileContents("Baz.aidl",
3216                                "@JavaOnlyImmutable @JavaOnlyStableParcelable parcelable Baz;");
3217   Options options = Options::From("aidl --lang=java -I . Foo.aidl");
3218   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3219 }
3220 
TEST_F(AidlTest,RejectMutableParcelableFromJavaOnlyImmutableParcelable)3221 TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableParcelable) {
3222   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { Bar bar; }");
3223   io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
3224   string expected_error =
3225       "ERROR: Foo.aidl:1.40-44: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
3226       "named 'bar'.\n";
3227   CaptureStderr();
3228   Options options = Options::From("aidl --lang=java Foo.aidl -I .");
3229   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3230   EXPECT_EQ(expected_error, GetCapturedStderr());
3231 }
3232 
TEST_F(AidlTest,JavaOnlyImmutableParcelableWithEnumFields)3233 TEST_F(AidlTest, JavaOnlyImmutableParcelableWithEnumFields) {
3234   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { Bar bar; }");
3235   io_delegate_.SetFileContents("Bar.aidl", "enum Bar { FOO }");
3236   CaptureStderr();
3237   Options options = Options::From("aidl --lang=java Foo.aidl -I .");
3238   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3239   EXPECT_EQ("", GetCapturedStderr());
3240 }
3241 
TEST_F(AidlTest,RejectMutableParcelableFromJavaOnlyImmutableUnion)3242 TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableUnion) {
3243   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable union Foo { Bar bar; }");
3244   io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
3245   string expected_error =
3246       "ERROR: Foo.aidl:1.35-39: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
3247       "named 'bar'.\n";
3248   CaptureStderr();
3249   Options options = Options::From("aidl --lang=java Foo.aidl -I .");
3250   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3251   EXPECT_EQ(expected_error, GetCapturedStderr());
3252 }
3253 
TEST_F(AidlTest,ImmutableParcelableCannotBeInOut)3254 TEST_F(AidlTest, ImmutableParcelableCannotBeInOut) {
3255   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
3256   io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(inout Foo foo); }");
3257   string expected_error =
3258       "ERROR: IBar.aidl:1.35-39: 'foo' can't be an inout parameter because @JavaOnlyImmutable can "
3259       "only be an in parameter.\n";
3260   CaptureStderr();
3261   Options options = Options::From("aidl --lang=java IBar.aidl -I .");
3262   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3263   EXPECT_EQ(expected_error, GetCapturedStderr());
3264 }
3265 
TEST_F(AidlTest,ImmutableParcelableCannotBeOut)3266 TEST_F(AidlTest, ImmutableParcelableCannotBeOut) {
3267   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
3268   io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(out Foo foo); }");
3269   string expected_error =
3270       "ERROR: IBar.aidl:1.33-37: 'foo' can't be an out parameter because @JavaOnlyImmutable can "
3271       "only be an in parameter.\n";
3272   CaptureStderr();
3273   Options options = Options::From("aidl --lang=java IBar.aidl -I .");
3274   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3275   EXPECT_EQ(expected_error, GetCapturedStderr());
3276 }
3277 
TEST_F(AidlTest,ImmutableParcelableFieldNameRestriction)3278 TEST_F(AidlTest, ImmutableParcelableFieldNameRestriction) {
3279   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; int A; }");
3280   Options options = Options::From("aidl --lang=java Foo.aidl");
3281   const string expected_stderr =
3282       "ERROR: Foo.aidl:1.47-49: 'Foo' has duplicate field name 'A' after capitalizing the first "
3283       "letter\n";
3284   CaptureStderr();
3285   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3286   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3287 }
3288 
TEST_P(AidlTest,UnionInUnion)3289 TEST_P(AidlTest, UnionInUnion) {
3290   import_paths_.insert(".");
3291   io_delegate_.SetFileContents("Bar.aidl", "union Bar { int n = 42; long l; }");
3292   CaptureStderr();
3293   EXPECT_NE(nullptr, Parse("Foo.aidl", "union Foo { Bar b; int n; }", typenames_, GetLanguage()));
3294   EXPECT_THAT("", GetCapturedStderr());
3295 }
3296 
TEST_P(AidlTest,UnionRejectsEmptyDecl)3297 TEST_P(AidlTest, UnionRejectsEmptyDecl) {
3298   const string method = "package a; union Foo {}";
3299   const string expected_stderr = "ERROR: a/Foo.aidl:1.17-21: The union 'Foo' has no fields.\n";
3300   CaptureStderr();
3301   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
3302   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
3303 }
3304 
TEST_P(AidlTest,UnionRejectsParcelableHolder)3305 TEST_P(AidlTest, UnionRejectsParcelableHolder) {
3306   const string method = "package a; union Foo { ParcelableHolder x; }";
3307   const string expected_stderr =
3308       "ERROR: a/Foo.aidl:1.40-42: A union can't have a member of ParcelableHolder 'x'\n";
3309   CaptureStderr();
3310   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
3311   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
3312 }
3313 
TEST_P(AidlTest,UnionRejectsFirstEnumWithNoDefaults)3314 TEST_P(AidlTest, UnionRejectsFirstEnumWithNoDefaults) {
3315   import_paths_.insert(".");
3316   io_delegate_.SetFileContents("a/Enum.aidl", "package a; enum Enum { FOO, BAR }");
3317   const string expected_err = "The union's first member should have a useful default value.";
3318   CaptureStderr();
3319   EXPECT_EQ(nullptr,
3320             Parse("a/Foo.aidl", "package a; union Foo { a.Enum e; }", typenames_, GetLanguage()));
3321   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_err));
3322 }
3323 
TEST_P(AidlTest,GenericStructuredParcelable)3324 TEST_P(AidlTest, GenericStructuredParcelable) {
3325   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T, U> { int a; int A; }");
3326   Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
3327   const string expected_stderr = "";
3328   CaptureStderr();
3329   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3330   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3331 }
3332 
TEST_F(AidlTest,GenericStructuredParcelableWithStringConstants_Cpp)3333 TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Cpp) {
3334   io_delegate_.SetFileContents("Foo.aidl",
3335                                "parcelable Foo<T, U> { int a; const String s = \"\"; }");
3336   Options options =
3337       Options::From("aidl Foo.aidl --lang=" + to_string(Options::Language::CPP) + " -o out -h out");
3338   const string expected_stderr = "";
3339   CaptureStderr();
3340   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3341   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3342 
3343   string code;
3344   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
3345   EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
3346 const ::android::String16& Foo<T,U>::s() {
3347   static const ::android::String16 value(::android::String16(""));
3348   return value;
3349 })--"));
3350 }
3351 
TEST_F(AidlTest,GenericStructuredParcelableWithStringConstants_Ndk)3352 TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Ndk) {
3353   io_delegate_.SetFileContents("Foo.aidl",
3354                                "parcelable Foo<T, U> { int a; const String s = \"\"; }");
3355   Options options =
3356       Options::From("aidl Foo.aidl --lang=" + to_string(Options::Language::NDK) + " -o out -h out");
3357   const string expected_stderr = "";
3358   CaptureStderr();
3359   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3360   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3361 
3362   string code;
3363   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
3364   EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
3365 const char* Foo<T, U>::s = "";
3366 )--"));
3367 }
3368 
TEST_F(AidlTest,NestedTypeArgs)3369 TEST_F(AidlTest, NestedTypeArgs) {
3370   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<A> { }");
3371   io_delegate_.SetFileContents("a/Baz.aidl", "package a; parcelable Baz<A, B> { }");
3372 
3373   io_delegate_.SetFileContents("a/Foo.aidl",
3374                                "package a; import a.Bar; import a.Baz; parcelable Foo { "
3375                                "Baz<Bar<Bar<String[]>>[], Bar<String>> barss; }");
3376   Options options = Options::From("aidl a/Foo.aidl -I . -o out --lang=java");
3377   const string expected_stderr = "";
3378   CaptureStderr();
3379   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3380   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3381 
3382   string code;
3383   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
3384   EXPECT_THAT(code,
3385               testing::HasSubstr(
3386                   "a.Baz<a.Bar<a.Bar<java.lang.String[]>>[],a.Bar<java.lang.String>> barss;"));
3387 }
3388 
TEST_F(AidlTest,DoubleArrayError)3389 TEST_F(AidlTest, DoubleArrayError) {
3390   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[][] a; }");
3391 
3392   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3393   const string expected_stderr =
3394       "ERROR: a/Bar.aidl:1.28-37: Can only have one dimensional arrays.\n";
3395   CaptureStderr();
3396   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3397   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3398 }
3399 
TEST_F(AidlTest,DoubleGenericError)3400 TEST_F(AidlTest, DoubleGenericError) {
3401   io_delegate_.SetFileContents("a/Bar.aidl",
3402                                "package a; parcelable Bar { List<String><String> a; }");
3403 
3404   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3405   const string expected_stderr =
3406       "ERROR: a/Bar.aidl:1.28-33: Can only specify one set of type parameters.\n";
3407   CaptureStderr();
3408   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3409   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3410 }
3411 
TEST_F(AidlTest,ArrayBeforeGenericError)3412 TEST_F(AidlTest, ArrayBeforeGenericError) {
3413   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { List[]<String> a; }");
3414 
3415   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3416   CaptureStderr();
3417   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3418   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("syntax error, unexpected '<'"));
3419 }
3420 
TEST_F(AidlTest,NullableArraysAreNotSupported)3421 TEST_F(AidlTest, NullableArraysAreNotSupported) {
3422   io_delegate_.SetFileContents("a/Bar.aidl",
3423                                "package a; parcelable Bar { String @nullable [] a; }");
3424 
3425   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3426   CaptureStderr();
3427   EXPECT_EQ(1, ::android::aidl::compile_aidl(options, io_delegate_));
3428   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("Annotations for arrays are not supported."));
3429 }
3430 
TEST_F(AidlTest,ListOfNullablesAreNotSupported)3431 TEST_F(AidlTest, ListOfNullablesAreNotSupported) {
3432   io_delegate_.SetFileContents("a/Bar.aidl",
3433                                "package a; parcelable Bar { List<@nullable String> a; }");
3434 
3435   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
3436   CaptureStderr();
3437   EXPECT_EQ(1, ::android::aidl::compile_aidl(options, io_delegate_));
3438   EXPECT_THAT(GetCapturedStderr(),
3439               testing::HasSubstr("Annotations for type arguments are not supported."));
3440 }
3441 
3442 struct GenericAidlTest : ::testing::Test {
3443   FakeIoDelegate io_delegate_;
Compileandroid::aidl::GenericAidlTest3444   void Compile(string cmd) {
3445     io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { Bar<Baz<Qux>> x; }");
3446     io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar<T> {  }");
3447     io_delegate_.SetFileContents("Baz.aidl", "parcelable Baz<T> {  }");
3448     io_delegate_.SetFileContents("Qux.aidl", "parcelable Qux {  }");
3449 
3450     Options options = Options::From(cmd);
3451     CaptureStderr();
3452     EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3453     EXPECT_EQ("", GetCapturedStderr());
3454   }
3455 };
3456 
TEST_F(GenericAidlTest,ImportGenericParameterTypesCPP)3457 TEST_F(GenericAidlTest, ImportGenericParameterTypesCPP) {
3458   Compile("aidl Foo.aidl --lang=cpp -I . -o out -h out");
3459   string code;
3460   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
3461   EXPECT_THAT(code, testing::HasSubstr("#include <Bar.h>"));
3462   EXPECT_THAT(code, testing::HasSubstr("#include <Baz.h>"));
3463   EXPECT_THAT(code, testing::HasSubstr("#include <Qux.h>"));
3464 }
3465 
TEST_F(GenericAidlTest,ImportGenericParameterTypesNDK)3466 TEST_F(GenericAidlTest, ImportGenericParameterTypesNDK) {
3467   Compile("aidl Foo.aidl --lang=ndk -I . -o out -h out");
3468   string code;
3469   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
3470   EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Bar.h>"));
3471   EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Baz.h>"));
3472   EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Qux.h>"));
3473 }
3474 
TEST_P(AidlTest,RejectGenericStructuredParcelabelRepeatedParam)3475 TEST_P(AidlTest, RejectGenericStructuredParcelabelRepeatedParam) {
3476   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { int a; int A; }");
3477   Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
3478   const string expected_stderr =
3479       "ERROR: Foo.aidl:1.11-15: Every type parameter should be unique.\n";
3480   CaptureStderr();
3481   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3482   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3483 }
3484 
TEST_P(AidlTest,RejectGenericStructuredParcelableField)3485 TEST_P(AidlTest, RejectGenericStructuredParcelableField) {
3486   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { T a; int A; }");
3487   Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
3488   const string expected_stderr = "ERROR: Foo.aidl:1.22-24: Failed to resolve 'T'\n";
3489   CaptureStderr();
3490   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3491   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3492 }
3493 
TEST_P(AidlTest,LongCommentWithinConstExpression)3494 TEST_P(AidlTest, LongCommentWithinConstExpression) {
3495   io_delegate_.SetFileContents("Foo.aidl", "enum Foo { FOO = (1 << 1) /* comment */ | 0x0 }");
3496   Options options = Options::From("aidl Foo.aidl --lang=" + to_string(GetLanguage()));
3497   CaptureStderr();
3498   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
3499   EXPECT_EQ("", GetCapturedStderr());
3500 }
3501 
TEST_F(AidlTest,RejectUntypdeListAndMapInUnion)3502 TEST_F(AidlTest, RejectUntypdeListAndMapInUnion) {
3503   io_delegate_.SetFileContents("a/Foo.aidl", "package a; union Foo { List l; Map m; }");
3504   Options options = Options::From("aidl a/Foo.aidl --lang=java -o out");
3505   std::string expectedErr =
3506       "ERROR: a/Foo.aidl:1.28-30: "
3507       "Encountered an untyped List or Map. The use of untyped List/Map is "
3508       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3509       "the receiving side. Consider switching to an array or a generic List/Map.\n"
3510       "ERROR: a/Foo.aidl:1.35-37: "
3511       "Encountered an untyped List or Map. The use of untyped List/Map is "
3512       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3513       "the receiving side. Consider switching to an array or a generic List/Map.\n";
3514   CaptureStderr();
3515   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3516   EXPECT_EQ(expectedErr, GetCapturedStderr());
3517 }
3518 
TEST_F(AidlTest,RejectUntypdeListAndMapInUnstructuredParcelable)3519 TEST_F(AidlTest, RejectUntypdeListAndMapInUnstructuredParcelable) {
3520   io_delegate_.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { List l; Map m; }");
3521   Options options = Options::From("aidl a/Foo.aidl --lang=java -o out");
3522   std::string expectedErr =
3523       "ERROR: a/Foo.aidl:1.33-35: "
3524       "Encountered an untyped List or Map. The use of untyped List/Map is "
3525       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3526       "the receiving side. Consider switching to an array or a generic List/Map.\n"
3527       "ERROR: a/Foo.aidl:1.40-42: "
3528       "Encountered an untyped List or Map. The use of untyped List/Map is "
3529       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3530       "the receiving side. Consider switching to an array or a generic List/Map.\n";
3531   CaptureStderr();
3532   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3533   EXPECT_EQ(expectedErr, GetCapturedStderr());
3534 }
3535 
TEST_F(AidlTest,RejectNestedUntypedListAndMap)3536 TEST_F(AidlTest, RejectNestedUntypedListAndMap) {
3537   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<T>;");
3538   io_delegate_.SetFileContents(
3539       "a/Foo.aidl", "package a; import a.Bar; parcelable Foo { Bar<List> a; Bar<Map> b; }");
3540   Options options = Options::From("aidl a/Foo.aidl -I . --lang=java -o out");
3541   std::string expectedErr =
3542       "ERROR: a/Foo.aidl:1.52-54: "
3543       "Encountered an untyped List or Map. The use of untyped List/Map is "
3544       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3545       "the receiving side. Consider switching to an array or a generic List/Map.\n"
3546       "ERROR: a/Foo.aidl:1.64-66: "
3547       "Encountered an untyped List or Map. The use of untyped List/Map is "
3548       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3549       "the receiving side. Consider switching to an array or a generic List/Map.\n";
3550   CaptureStderr();
3551   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
3552   EXPECT_EQ(expectedErr, GetCapturedStderr());
3553 }
3554 
TEST_F(AidlTest,EnumWithDefaults_Java)3555 TEST_F(AidlTest, EnumWithDefaults_Java) {
3556   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
3557   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3558 package p;
3559 import p.Enum;
3560 parcelable Foo {
3561   Enum e = Enum.BAR;
3562 })");
3563   CaptureStderr();
3564   auto options = Options::From("aidl -I a --lang java -o out a/p/Foo.aidl");
3565   EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3566   auto err = GetCapturedStderr();
3567   EXPECT_EQ("", err);
3568 
3569   string code;
3570   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.java", &code));
3571   EXPECT_THAT(code, testing::HasSubstr("byte e = p.Enum.BAR"));
3572 }
3573 
TEST_F(AidlTest,EnumWithDefaults_Cpp)3574 TEST_F(AidlTest, EnumWithDefaults_Cpp) {
3575   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
3576   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3577 package p;
3578 import p.Enum;
3579 parcelable Foo {
3580   Enum e = Enum.BAR;
3581 })");
3582   CaptureStderr();
3583   auto options = Options::From("aidl -I a --lang cpp -o out -h out a/p/Foo.aidl");
3584   EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3585   auto err = GetCapturedStderr();
3586   EXPECT_EQ("", err);
3587 
3588   string code;
3589   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.h", &code));
3590   EXPECT_THAT(code, testing::HasSubstr("::p::Enum e = ::p::Enum(::p::Enum::BAR);"));
3591 }
3592 
TEST_F(AidlTest,EnumWithDefaults_Ndk)3593 TEST_F(AidlTest, EnumWithDefaults_Ndk) {
3594   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
3595   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3596 package p;
3597 import p.Enum;
3598 parcelable Foo {
3599   Enum e = Enum.BAR;
3600 })");
3601   CaptureStderr();
3602   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
3603   EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3604   auto err = GetCapturedStderr();
3605   EXPECT_EQ("", err);
3606 
3607   string code;
3608   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
3609   EXPECT_THAT(code, testing::HasSubstr("::aidl::p::Enum e = ::aidl::p::Enum::BAR;"));
3610 }
3611 
TEST_F(AidlTest,EnumWithDefaults_Rust)3612 TEST_F(AidlTest, EnumWithDefaults_Rust) {
3613   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
3614   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3615 package p;
3616 import p.Enum;
3617 parcelable Foo {
3618   int  n = 42;
3619   Enum e = Enum.BAR;
3620 })");
3621   CaptureStderr();
3622   auto options = Options::From("aidl -I a --lang rust -o out -h out a/p/Foo.aidl");
3623   EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3624   auto err = GetCapturedStderr();
3625   EXPECT_EQ("", err);
3626 
3627   string code;
3628   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.rs", &code));
3629   EXPECT_THAT(code, testing::HasSubstr(R"(
3630   fn default() -> Self {
3631     Self {
3632       n: 42,
3633       e: crate::mangled::_1_p_4_Enum::BAR,
3634     }
3635   })"));
3636 }
3637 
TEST_P(AidlTest,EnumeratorIsConstantValue_DefaultValue)3638 TEST_P(AidlTest, EnumeratorIsConstantValue_DefaultValue) {
3639   import_paths_.insert("a");
3640   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
3641   CaptureStderr();
3642   const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
3643 package p;
3644 import p.Enum;
3645 parcelable Foo {
3646   int e = Enum.FOO | Enum.BAR;
3647 })",
3648                                       typenames_, GetLanguage());
3649   auto err = GetCapturedStderr();
3650   EXPECT_EQ("", err);
3651   EXPECT_TRUE(type);
3652   const auto& fields = type->AsStructuredParcelable()->GetFields();
3653   EXPECT_EQ("int e = 3", fields[0]->ToString());
3654 }
3655 
TEST_P(AidlTest,EnumeratorIsConstantValue_CanDefineOtherEnumerator)3656 TEST_P(AidlTest, EnumeratorIsConstantValue_CanDefineOtherEnumerator) {
3657   CaptureStderr();
3658   const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
3659 @Backing(type="int")
3660 enum Foo {
3661       STANDARD_SHIFT = 16,
3662       STANDARD_BT709 = 1 << STANDARD_SHIFT,
3663       STANDARD_BT601_625 = 2 << STANDARD_SHIFT,
3664 }
3665 )",
3666                                       typenames_, GetLanguage());
3667   auto err = GetCapturedStderr();
3668   EXPECT_EQ("", err);
3669   EXPECT_TRUE(type);
3670   const auto& enum_type = type->AsEnumDeclaration();
3671   string code;
3672   auto writer = CodeWriter::ForString(&code);
3673   DumpVisitor visitor(*writer);
3674   visitor.Visit(*enum_type);
3675   writer->Close();
3676   EXPECT_EQ(R"--(@Backing(type="int")
3677 enum Foo {
3678   STANDARD_SHIFT = 16,
3679   STANDARD_BT709 = 65536,
3680   STANDARD_BT601_625 = 131072,
3681 }
3682 )--",
3683             code);
3684 }
3685 
TEST_F(AidlTest,EnumDefaultShouldBeEnumerators)3686 TEST_F(AidlTest, EnumDefaultShouldBeEnumerators) {
3687   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
3688   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
3689 package p;
3690 import p.Enum;
3691 parcelable Foo {
3692   Enum e = Enum.FOO | Enum.BAR;
3693 })");
3694   CaptureStderr();
3695   auto options = Options::From("aidl -I a --lang java -o out -h out a/p/Foo.aidl");
3696   EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3697   auto err = GetCapturedStderr();
3698   EXPECT_EQ("ERROR: a/p/Foo.aidl:5.11-20: Invalid value (Enum.FOO|Enum.BAR) for enum p.Enum\n",
3699             err);
3700 }
3701 
TEST_P(AidlTest,DefaultWithEmptyArray)3702 TEST_P(AidlTest, DefaultWithEmptyArray) {
3703   io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; parcelable Foo { p.Bar[] bars = {}; }");
3704   io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; parcelable Bar { }");
3705   CaptureStderr();
3706   auto options =
3707       Options::From("aidl -I a --lang " + to_string(GetLanguage()) + " -o out -h out a/p/Foo.aidl");
3708   EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3709   auto err = GetCapturedStderr();
3710   EXPECT_EQ("", err);
3711 }
3712 
TEST_P(AidlTest,RejectRefsInAnnotation)3713 TEST_P(AidlTest, RejectRefsInAnnotation) {
3714   io_delegate_.SetFileContents("a/p/IFoo.aidl",
3715                                "package p; interface IFoo {\n"
3716                                "  const String ANNOTATION = \"@Annotation\";\n"
3717                                "  @JavaPassthrough(annotation=ANNOTATION) void foo();\n"
3718                                "}");
3719   CaptureStderr();
3720   auto options =
3721       Options::From("aidl --lang " + to_string(GetLanguage()) + " -o out -h out a/p/IFoo.aidl");
3722   EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3723   auto err = GetCapturedStderr();
3724   EXPECT_EQ(
3725       "ERROR: a/p/IFoo.aidl:3.31-41: Value must be a constant expression but contains reference to "
3726       "ANNOTATION.\n",
3727       err);
3728 }
3729 
TEST_F(AidlTest,DefaultWithEnumValues)3730 TEST_F(AidlTest, DefaultWithEnumValues) {
3731   io_delegate_.SetFileContents(
3732       "a/p/Foo.aidl",
3733       "package p; import p.Bar; parcelable Foo { Bar[] bars = { Bar.FOO, Bar.FOO }; }");
3734   io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; enum Bar { FOO, BAR }");
3735   CaptureStderr();
3736   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
3737   EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3738   auto err = GetCapturedStderr();
3739   EXPECT_EQ("", err);
3740   string code;
3741   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
3742   EXPECT_THAT(
3743       code, testing::HasSubstr(
3744                 "std::vector<::aidl::p::Bar> bars = {::aidl::p::Bar::FOO, ::aidl::p::Bar::FOO};"));
3745 }
3746 
TEST_F(AidlTest,RejectsCircularReferencingEnumerators)3747 TEST_F(AidlTest, RejectsCircularReferencingEnumerators) {
3748   io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; enum Foo { A = B, B }");
3749   CaptureStderr();
3750   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
3751   EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3752   auto err = GetCapturedStderr();
3753   EXPECT_EQ(
3754       "ERROR: a/p/Foo.aidl:1.26-28: Found a circular reference: B -> A -> B\n"
3755       "ERROR: a/p/Foo.aidl:1.29-31: Found a circular reference: A -> B -> A\n",
3756       err);
3757 }
3758 
TEST_F(AidlTest,RejectsCircularReferencingConsts)3759 TEST_F(AidlTest, RejectsCircularReferencingConsts) {
3760   io_delegate_.SetFileContents("a/p/Foo.aidl",
3761                                "package p; parcelable Foo { const int A = A + 1; }");
3762   CaptureStderr();
3763   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
3764   EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3765   auto err = GetCapturedStderr();
3766   EXPECT_EQ("ERROR: a/p/Foo.aidl:1.42-44: Found a circular reference: A -> A\n", err);
3767 }
3768 
TEST_F(AidlTest,RecursiveReferences)3769 TEST_F(AidlTest, RecursiveReferences) {
3770   io_delegate_.SetFileContents("a/p/Foo.aidl",
3771                                "package p; parcelable Foo { const int A = p.Bar.A + 1; }");
3772   io_delegate_.SetFileContents("a/p/Bar.aidl",
3773                                "package p; parcelable Bar { const int A = p.Baz.A + 1; }");
3774   io_delegate_.SetFileContents("a/p/Baz.aidl", "package p; parcelable Baz { const int A = 1; }");
3775   CaptureStderr();
3776   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
3777   EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3778   EXPECT_EQ("", GetCapturedStderr());
3779 }
3780 
TEST_P(AidlTest,UnknownConstReference)3781 TEST_P(AidlTest, UnknownConstReference) {
3782   io_delegate_.SetFileContents("Foo.aidl", " parcelable Foo { UnknownType field = UNKNOWN_REF; }");
3783   auto options =
3784       Options::From("aidl --lang " + to_string(GetLanguage()) + " -o out -h out Foo.aidl");
3785   const string err =
3786       "ERROR: Foo.aidl:1.18-30: Failed to resolve 'UnknownType'\n"
3787       "ERROR: Foo.aidl:1.38-50: Can't find UNKNOWN_REF in Foo\n"
3788       "ERROR: Foo.aidl:1.38-50: Unknown reference 'UNKNOWN_REF'\n";
3789   CaptureStderr();
3790   EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3791   EXPECT_EQ(err, GetCapturedStderr());
3792 }
3793 
TEST_P(AidlTest,JavaCompatibleBuiltinTypes)3794 TEST_P(AidlTest, JavaCompatibleBuiltinTypes) {
3795   string contents = R"(
3796 import android.os.IBinder;
3797 import android.os.IInterface;
3798 interface IFoo {}
3799   )";
3800   EXPECT_NE(nullptr, Parse("IFoo.aidl", contents, typenames_, GetLanguage()));
3801 }
3802 
TEST_P(AidlTest,WarningInterfaceName)3803 TEST_P(AidlTest, WarningInterfaceName) {
3804   io_delegate_.SetFileContents("p/Foo.aidl", "interface Foo {}");
3805   auto options = Options::From("aidl --lang " + to_string(GetLanguage()) +
3806                                " -Weverything -o out -h out p/Foo.aidl");
3807   CaptureStderr();
3808   EXPECT_EQ(0, aidl::compile_aidl(options, io_delegate_));
3809   EXPECT_EQ("WARNING: p/Foo.aidl:1.1-10: Interface names should start with I. [-Winterface-name]\n",
3810             GetCapturedStderr());
3811 }
3812 
TEST_P(AidlTest,ErrorInterfaceName)3813 TEST_P(AidlTest, ErrorInterfaceName) {
3814   io_delegate_.SetFileContents("p/Foo.aidl", "interface Foo {}");
3815   auto options = Options::From("aidl --lang " + to_string(GetLanguage()) +
3816                                " -Weverything -Werror -o out -h out p/Foo.aidl");
3817   CaptureStderr();
3818   EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3819   EXPECT_EQ("ERROR: p/Foo.aidl:1.1-10: Interface names should start with I. [-Winterface-name]\n",
3820             GetCapturedStderr());
3821 }
3822 
TEST_F(AidlTest,RejectsIncorrectOutputFilePathOnLegacyCppInput)3823 TEST_F(AidlTest, RejectsIncorrectOutputFilePathOnLegacyCppInput) {
3824   const std::string input_file = "base/p/q/IFoo.aidl";
3825   const std::string header_dir = "out/";
3826   const std::string output_file = "out/base/p/q/IFoo.cpp";
3827   const std::string package = "p.q";  // not base.p.q
3828   io_delegate_.SetFileContents(input_file, "package " + package + "; interface IFoo {}");
3829 
3830   auto options = Options::From({"aidl-cpp", input_file, header_dir, output_file});
3831   CaptureStderr();
3832   EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3833   EXPECT_THAT(
3834       GetCapturedStderr(),
3835       testing::StartsWith(
3836           "ERROR: base/p/q/IFoo.aidl:1.13-23: Output file is expected to be at out/p/q/IFoo.cpp, "
3837           "but is out/base/p/q/IFoo.cpp."));
3838 }
3839 
TEST_F(AidlTest,FormatCommentsForJava)3840 TEST_F(AidlTest, FormatCommentsForJava) {
3841   using android::aidl::FormatCommentsForJava;
3842 
3843   struct TestCase {
3844     vector<Comment> comments;
3845     string formatted;
3846   };
3847   vector<TestCase> testcases = {
3848       {{}, ""},
3849       {{{"// line comments\n"}}, "// line comments\n"},
3850       {{{"// @hide \n"}}, "// @hide \n"},
3851       // Transform the last block comment as Javadoc.
3852       {{{"/*\n"
3853          " * Hello, world!\n"
3854          " */"}},
3855        "/**\n"
3856        " * Hello, world!\n"
3857        " */"},
3858       {{{"/* @hide */"}}, "/** @hide */"},
3859       {{{"/**\n"
3860          "   @param foo ...\n"
3861          "*/"}},
3862        "/**\n"
3863        "   @param foo ...\n"
3864        "*/"},
3865       {{{"/* @hide */"}, {"/* @hide */"}}, "/* @hide *//** @hide */"},
3866       {{{"/* @deprecated first */"}, {"/* @deprecated second */"}},
3867        "/* @deprecated first *//** @deprecated second */"},
3868       {{{"/* @deprecated */"}, {"/** @param foo */"}}, "/* @deprecated *//** @param foo */"},
3869       // Line comments are printed as they are
3870       {{{"/* @deprecated */"}, {"// line comments\n"}}, "/* @deprecated */// line comments\n"},
3871   };
3872   for (const auto& [input, formatted] : testcases) {
3873     EXPECT_EQ(formatted, FormatCommentsForJava(input));
3874   }
3875 }
3876 
TEST_F(AidlTest,HideIsNotForArgs)3877 TEST_F(AidlTest, HideIsNotForArgs) {
3878   io_delegate_.SetFileContents("IFoo.aidl",
3879                                "interface IFoo {\n"
3880                                "  void foo(in @Hide int x);\n"
3881                                "}");
3882   auto options = Options::From("aidl --lang=java IFoo.aidl");
3883   CaptureStderr();
3884   EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3885   EXPECT_THAT(GetCapturedStderr(), HasSubstr("@Hide is not available"));
3886 }
3887 
TEST_F(AidlTest,SuppressWarningsIsNotForArgs)3888 TEST_F(AidlTest, SuppressWarningsIsNotForArgs) {
3889   io_delegate_.SetFileContents(
3890       "IFoo.aidl",
3891       "interface IFoo {\n"
3892       "  void foo(in @SuppressWarnings(value=\"inout-parameter\") int x);\n"
3893       "}");
3894   auto options = Options::From("aidl --lang=java IFoo.aidl");
3895   CaptureStderr();
3896   EXPECT_EQ(1, aidl::compile_aidl(options, io_delegate_));
3897   EXPECT_THAT(GetCapturedStderr(), HasSubstr("@SuppressWarnings is not available"));
3898 }
3899 
3900 struct TypeParam {
3901   string kind;
3902   string literal;
3903 };
3904 
3905 const TypeParam kTypeParams[] = {
3906     {"primitive", "int"},   {"primitiveArray", "int[]"},
3907     {"String", "String"},   {"StringArray", "String[]"},
3908     {"IBinder", "IBinder"}, {"ParcelFileDescriptor", "ParcelFileDescriptor"},
3909     {"parcelable", "Foo"},  {"enum", "a.Enum"},
3910     {"union", "a.Union"},   {"interface", "a.IBar"},
3911 };
3912 
3913 const std::map<std::string, std::string> kListSupportExpectations = {
3914     {"cpp_primitive", "A generic type cannot have any primitive type parameters."},
3915     {"java_primitive", "A generic type cannot have any primitive type parameters."},
3916     {"ndk_primitive", "A generic type cannot have any primitive type parameters."},
3917     {"rust_primitive", "A generic type cannot have any primitive type parameters."},
3918     {"cpp_primitiveArray", "List of arrays is not supported."},
3919     {"java_primitiveArray", "List of arrays is not supported."},
3920     {"ndk_primitiveArray", "List of arrays is not supported."},
3921     {"rust_primitiveArray", "List of arrays is not supported."},
3922     {"cpp_String", ""},
3923     {"java_String", ""},
3924     {"ndk_String", ""},
3925     {"rust_String", ""},
3926     {"cpp_StringArray", "List of arrays is not supported."},
3927     {"java_StringArray", "List of arrays is not supported."},
3928     {"ndk_StringArray", "List of arrays is not supported."},
3929     {"rust_StringArray", "List of arrays is not supported."},
3930     {"cpp_IBinder", ""},
3931     {"java_IBinder", ""},
3932     {"ndk_IBinder", "List<IBinder> is not supported. List in NDK doesn't support IBinder."},
3933     {"rust_IBinder", ""},
3934     {"cpp_ParcelFileDescriptor", ""},
3935     {"java_ParcelFileDescriptor", ""},
3936     {"ndk_ParcelFileDescriptor", ""},
3937     {"rust_ParcelFileDescriptor", ""},
3938     {"cpp_interface", "List<a.IBar> is not supported."},
3939     {"java_interface", "List<a.IBar> is not supported."},
3940     {"ndk_interface", "List<a.IBar> is not supported."},
3941     {"rust_interface", "List<a.IBar> is not supported."},
3942     {"cpp_parcelable", ""},
3943     {"java_parcelable", ""},
3944     {"ndk_parcelable", ""},
3945     {"rust_parcelable", ""},
3946     {"cpp_enum", "A generic type cannot have any primitive type parameters."},
3947     {"java_enum", "A generic type cannot have any primitive type parameters."},
3948     {"ndk_enum", "A generic type cannot have any primitive type parameters."},
3949     {"rust_enum", "A generic type cannot have any primitive type parameters."},
3950     {"cpp_union", ""},
3951     {"java_union", ""},
3952     {"ndk_union", ""},
3953     {"rust_union", ""},
3954 };
3955 
3956 const std::map<std::string, std::string> kArraySupportExpectations = {
3957     {"cpp_primitive", ""},
3958     {"java_primitive", ""},
3959     {"ndk_primitive", ""},
3960     {"rust_primitive", ""},
3961     {"cpp_primitiveArray", "Can only have one dimensional arrays."},
3962     {"java_primitiveArray", "Can only have one dimensional arrays."},
3963     {"ndk_primitiveArray", "Can only have one dimensional arrays."},
3964     {"rust_primitiveArray", "Can only have one dimensional arrays."},
3965     {"cpp_String", ""},
3966     {"java_String", ""},
3967     {"ndk_String", ""},
3968     {"rust_String", ""},
3969     {"cpp_StringArray", "Can only have one dimensional arrays."},
3970     {"java_StringArray", "Can only have one dimensional arrays."},
3971     {"ndk_StringArray", "Can only have one dimensional arrays."},
3972     {"rust_StringArray", "Can only have one dimensional arrays."},
3973     {"cpp_IBinder", ""},
3974     {"java_IBinder", ""},
3975     {"ndk_IBinder", "The ndk backend does not support array of IBinder"},
3976     {"rust_IBinder", "The rust backend does not support array of IBinder"},
3977     {"cpp_ParcelFileDescriptor", ""},
3978     {"java_ParcelFileDescriptor", ""},
3979     {"ndk_ParcelFileDescriptor", ""},
3980     {"rust_ParcelFileDescriptor", ""},
3981     {"cpp_interface", "Binder type cannot be an array"},
3982     {"java_interface", "Binder type cannot be an array"},
3983     {"ndk_interface", "Binder type cannot be an array"},
3984     {"rust_interface", "Binder type cannot be an array"},
3985     {"cpp_parcelable", ""},
3986     {"java_parcelable", ""},
3987     {"ndk_parcelable", ""},
3988     {"rust_parcelable", ""},
3989     {"cpp_enum", ""},
3990     {"java_enum", ""},
3991     {"ndk_enum", ""},
3992     {"rust_enum", ""},
3993     {"cpp_union", ""},
3994     {"java_union", ""},
3995     {"ndk_union", ""},
3996     {"rust_union", ""},
3997 };
3998 
3999 class AidlTypeParamTest : public testing::TestWithParam<std::tuple<Options::Language, TypeParam>> {
4000  public:
Run(const std::string & generic_type_decl,const std::map<std::string,std::string> & expectations)4001   void Run(const std::string& generic_type_decl,
4002            const std::map<std::string, std::string>& expectations) {
4003     const auto& param = GetParam();
4004     const auto& lang = to_string(std::get<0>(param));
4005     const auto& kind = std::get<1>(param).kind;
4006 
4007     FakeIoDelegate io;
4008     io.SetFileContents("a/IBar.aidl", "package a; interface IBar { }");
4009     io.SetFileContents("a/Enum.aidl", "package a; enum Enum { A }");
4010     io.SetFileContents("a/Union.aidl", "package a; union Union { int a; }");
4011     std::string decl = fmt::format(generic_type_decl, std::get<1>(param).literal);
4012     io.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { " + decl + " f; }");
4013 
4014     const auto options =
4015         Options::From(fmt::format("aidl -I . --lang={} a/Foo.aidl -o out -h out", lang));
4016     CaptureStderr();
4017     compile_aidl(options, io);
4018     auto it = expectations.find(lang + "_" + kind);
4019     EXPECT_TRUE(it != expectations.end());
4020     const string err = GetCapturedStderr();
4021     if (it->second.empty()) {
4022       EXPECT_EQ("", err);
4023     } else {
4024       EXPECT_THAT(err, testing::HasSubstr(it->second));
4025     }
4026   }
4027 };
4028 
4029 INSTANTIATE_TEST_SUITE_P(
4030     AidlTestSuite, AidlTypeParamTest,
4031     testing::Combine(testing::Values(Options::Language::CPP, Options::Language::JAVA,
4032                                      Options::Language::NDK, Options::Language::RUST),
4033                      testing::ValuesIn(kTypeParams)),
__anon758595f20402(const testing::TestParamInfo<std::tuple<Options::Language, TypeParam>>& info) 4034     [](const testing::TestParamInfo<std::tuple<Options::Language, TypeParam>>& info) {
4035       return to_string(std::get<0>(info.param)) + "_" + std::get<1>(info.param).kind;
4036     });
4037 
TEST_P(AidlTypeParamTest,ListSupportedTypes)4038 TEST_P(AidlTypeParamTest, ListSupportedTypes) {
4039   Run("List<{}>", kListSupportExpectations);
4040 }
4041 
TEST_P(AidlTypeParamTest,ArraySupportedTypes)4042 TEST_P(AidlTypeParamTest, ArraySupportedTypes) {
4043   Run("{}[]", kArraySupportExpectations);
4044 }
4045 
4046 }  // namespace aidl
4047 }  // namespace android
4048