• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <unordered_map>
29 #include <unordered_set>
30 #include <variant>
31 #include <vector>
32 
33 #include "aidl_checkapi.h"
34 #include "aidl_dumpapi.h"
35 #include "aidl_language.h"
36 #include "aidl_to_cpp.h"
37 #include "aidl_to_cpp_common.h"
38 #include "aidl_to_java.h"
39 #include "aidl_to_ndk.h"
40 #include "aidl_to_rust.h"
41 #include "comments.h"
42 #include "logging.h"
43 #include "options.h"
44 #include "parser.h"
45 #include "preprocess.h"
46 #include "tests/fake_io_delegate.h"
47 
48 using android::aidl::test::FakeIoDelegate;
49 using android::base::StringPrintf;
50 using std::map;
51 using std::set;
52 using std::string;
53 using std::unique_ptr;
54 using std::variant;
55 using std::vector;
56 using testing::HasSubstr;
57 using testing::TestParamInfo;
58 using testing::internal::CaptureStderr;
59 using testing::internal::GetCapturedStderr;
60 
61 namespace android {
62 namespace aidl {
63 namespace {
64 
65 const char kExpectedDepFileContents[] =
66 R"(place/for/output/p/IFoo.java : \
67   p/IFoo.aidl
68 
69 p/IFoo.aidl :
70 )";
71 
72 const char kExpectedNinjaDepFileContents[] =
73 R"(place/for/output/p/IFoo.java : \
74   p/IFoo.aidl
75 )";
76 
77 const char kExpectedParcelableDeclarationDepFileContents[] =
78     R"( : \
79   p/Foo.aidl
80 
81 p/Foo.aidl :
82 )";
83 
84 const char kExpectedStructuredParcelableDepFileContents[] =
85     R"(place/for/output/p/Foo.java : \
86   p/Foo.aidl
87 
88 p/Foo.aidl :
89 )";
90 
91 }  // namespace
92 
93 const string INVALID_INT8_VALUE = "Invalid type specifier for an int8 literal";
94 const string INVALID_FLOAT_VALUE = "Invalid type specifier for a literal float";
95 const string INVALID_OPERATION = "Cannot perform operation";
96 
97 class AidlTest : public ::testing::TestWithParam<Options::Language> {
98  protected:
Parse(const string & path,const string & contents,AidlTypenames & typenames_,Options::Language lang,AidlError * error=nullptr,const vector<string> additional_arguments={})99   AidlDefinedType* Parse(const string& path, const string& contents, AidlTypenames& typenames_,
100                          Options::Language lang, AidlError* error = nullptr,
101                          const vector<string> additional_arguments = {}) {
102     io_delegate_.SetFileContents(path, contents);
103     vector<string> args;
104     args.emplace_back("aidl");
105     args.emplace_back("--min_sdk_version=current");
106     args.emplace_back("--lang=" + to_string(lang));
107     for (const string& s : additional_arguments) {
108       args.emplace_back(s);
109     }
110     for (const string& f : preprocessed_files_) {
111       args.emplace_back("--preprocessed=" + f);
112     }
113     args.emplace_back("--include=.");
114     for (const string& i : import_paths_) {
115       args.emplace_back("--include=" + i);
116     }
117     args.emplace_back(path);
118     Options options = Options::From(args);
119     vector<string> imported_files;
120     ImportResolver import_resolver{io_delegate_, path, import_paths_};
121     AidlError actual_error = ::android::aidl::internals::load_and_validate_aidl(
122         path, options, io_delegate_, &typenames_, &imported_files);
123 
124     if (error != nullptr) {
125       *error = actual_error;
126     }
127 
128     if (actual_error != AidlError::OK) {
129       return nullptr;
130     }
131 
132     const auto& defined_types = typenames_.MainDocument().DefinedTypes();
133     EXPECT_EQ(1ul, defined_types.size());
134 
135     return defined_types.front().get();
136   }
137 
EvaluateInvalidAssignment(string content,string expected_stderr,AidlTypenames & typenames_,Options::Language lang)138   void EvaluateInvalidAssignment(string content, string expected_stderr, AidlTypenames& typenames_,
139                                  Options::Language lang) {
140     AidlError error;
141     CaptureStderr();
142     EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", content, typenames_, lang, &error));
143     EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_stderr));
144   };
145 
EvaluateValidAssignment(string content,string expected_stderr,AidlTypenames & typenames_,Options::Language lang)146   void EvaluateValidAssignment(string content, string expected_stderr, AidlTypenames& typenames_,
147                                Options::Language lang) {
148     AidlError error;
149     CaptureStderr();
150     EXPECT_NE(nullptr, Parse("a/IFoo.aidl", content, typenames_, lang, &error));
151     EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_stderr));
152   };
153 
GetLanguage()154   Options::Language GetLanguage() { return GetParam(); }
155 
156   FakeIoDelegate io_delegate_;
157   vector<string> preprocessed_files_;
158   set<string> import_paths_;
159   AidlTypenames typenames_;
160 };
161 
162 // Instantiate the AidlTest parameterized suite, calling all of the TEST_P
163 // tests with each of the supported languages as a parameter.
164 INSTANTIATE_TEST_SUITE_P(AidlTestSuite, AidlTest,
165                          testing::Values(Options::Language::CPP, Options::Language::JAVA,
166                                          Options::Language::NDK, Options::Language::RUST),
__anon52baf79a0202(const testing::TestParamInfo<Options::Language>& info) 167                          [](const testing::TestParamInfo<Options::Language>& info) {
168                            return to_string(info.param);
169                          });
170 
TEST_P(AidlTest,AcceptMissingPackage)171 TEST_P(AidlTest, AcceptMissingPackage) {
172   EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", typenames_, GetLanguage()));
173 }
174 
TEST_P(AidlTest,EndsInSingleLineComment)175 TEST_P(AidlTest, EndsInSingleLineComment) {
176   EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { } // foo", typenames_, GetLanguage()));
177 }
178 
TEST_P(AidlTest,InterfaceRequiresCorrectPath)179 TEST_P(AidlTest, InterfaceRequiresCorrectPath) {
180   const string expected_stderr =
181       "ERROR: a/Foo.aidl:1.11-21: IBar should be declared in a file called a/IBar.aidl\n";
182   const std::string file_contents = "package a; interface IBar {}";
183   CaptureStderr();
184   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
185   EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
186 }
187 
TEST_P(AidlTest,ParcelableRequiresCorrectPath)188 TEST_P(AidlTest, ParcelableRequiresCorrectPath) {
189   const string expected_stderr =
190       "ERROR: a/Foo.aidl:1.11-21: Bar should be declared in a file called a/Bar.aidl\n";
191   const std::string file_contents = "package a; interface Bar {}";
192   CaptureStderr();
193   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
194   EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
195 }
196 
TEST_P(AidlTest,UnstructuredParcelableRequiresCorrectPath)197 TEST_P(AidlTest, UnstructuredParcelableRequiresCorrectPath) {
198   const string expected_stderr =
199       "ERROR: a/Foo.aidl:1.22-26: Bar should be declared in a file called a/Bar.aidl\n";
200   const std::string file_contents = "package a; parcelable Bar cpp_header \"anything.h\";";
201   CaptureStderr();
202   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
203   EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
204 }
205 
TEST_P(AidlTest,EnumRequiresCorrectPath)206 TEST_P(AidlTest, EnumRequiresCorrectPath) {
207   const string expected_stderr =
208       "ERROR: a/Foo.aidl:1.16-20: Bar should be declared in a file called a/Bar.aidl\n";
209   const std::string file_contents = "package a; enum Bar { A, }";
210   CaptureStderr();
211   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", file_contents, typenames_, GetLanguage()));
212   EXPECT_EQ(expected_stderr, GetCapturedStderr()) << file_contents;
213 }
214 
TEST_P(AidlTest,SupportOnlyOutParameters)215 TEST_P(AidlTest, SupportOnlyOutParameters) {
216   const string interface_list = "package a; interface IBar { void f(out List<String> bar); }";
217   EXPECT_NE(nullptr, Parse("a/IBar.aidl", interface_list, typenames_, GetLanguage()));
218 }
219 
TEST_P(AidlTest,RejectOutParametersForIBinder)220 TEST_P(AidlTest, RejectOutParametersForIBinder) {
221   const string interface_ibinder = "package a; interface IBaz { void f(out IBinder bar); }";
222   const string expected_ibinder_stderr =
223       "ERROR: a/IBaz.aidl:1.47-51: 'bar' can't be an out parameter because IBinder can only be an "
224       "in parameter.\n";
225   CaptureStderr();
226   EXPECT_EQ(nullptr, Parse("a/IBaz.aidl", interface_ibinder, typenames_, GetLanguage()));
227   EXPECT_EQ(expected_ibinder_stderr, GetCapturedStderr());
228 }
229 
TEST_P(AidlTest,RejectsOutParametersInOnewayInterface)230 TEST_P(AidlTest, RejectsOutParametersInOnewayInterface) {
231   const string oneway_interface = "package a; oneway interface IBar { void f(out int[] bar); }";
232   const string expected_stderr =
233       "ERROR: a/IBar.aidl:1.40-42: oneway method 'f' cannot have out parameters\n";
234   CaptureStderr();
235   EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, GetLanguage()));
236   EXPECT_EQ(expected_stderr, GetCapturedStderr());
237 }
238 
TEST_P(AidlTest,RejectsOutParametersInOnewayMethod)239 TEST_P(AidlTest, RejectsOutParametersInOnewayMethod) {
240   const string oneway_method = "package a; interface IBar { oneway void f(out int[] bar); }";
241   const string expected_stderr =
242       "ERROR: a/IBar.aidl:1.40-42: oneway method 'f' cannot have out parameters\n";
243   CaptureStderr();
244   EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, typenames_, GetLanguage()));
245   EXPECT_EQ(expected_stderr, GetCapturedStderr());
246 }
247 
TEST_P(AidlTest,RejectsOnewayNonVoidReturn)248 TEST_P(AidlTest, RejectsOnewayNonVoidReturn) {
249   const string oneway_method = "package a; interface IFoo { oneway int f(); }";
250   const string expected_stderr =
251       "ERROR: a/IFoo.aidl:1.39-41: oneway method 'f' cannot return a value\n";
252   CaptureStderr();
253   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
254   EXPECT_EQ(expected_stderr, GetCapturedStderr());
255 }
256 
TEST_P(AidlTest,RejectsNullablePrimitive)257 TEST_P(AidlTest, RejectsNullablePrimitive) {
258   const string oneway_method = "package a; interface IFoo { @nullable int f(); }";
259   const string expected_stderr =
260       "ERROR: a/IFoo.aidl:1.38-42: Primitive type cannot get nullable annotation\n";
261   CaptureStderr();
262   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
263   EXPECT_EQ(expected_stderr, GetCapturedStderr());
264 }
265 
TEST_P(AidlTest,AcceptNullableList)266 TEST_P(AidlTest, AcceptNullableList) {
267   const string oneway_method = "package a; interface IFoo { @nullable List<String> f(); }";
268   const string expected_stderr = "";
269   CaptureStderr();
270   EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
271   EXPECT_EQ(expected_stderr, GetCapturedStderr());
272 }
273 
TEST_P(AidlTest,RejectRecursiveParcelable)274 TEST_P(AidlTest, RejectRecursiveParcelable) {
275   CaptureStderr();
276   EXPECT_EQ(nullptr, Parse("Foo.aidl", "parcelable Foo { Foo foo; }", typenames_, GetLanguage()));
277   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Foo is a recursive parcelable"));
278 }
279 
TEST_P(AidlTest,RejectIndirectRecursiveParcelable)280 TEST_P(AidlTest, RejectIndirectRecursiveParcelable) {
281   io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { Foo foo; }");
282   import_paths_.emplace("");
283   CaptureStderr();
284   EXPECT_EQ(nullptr, Parse("Foo.aidl", "parcelable Foo { Bar bar; }", typenames_, GetLanguage()));
285   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Foo is a recursive parcelable"));
286 }
287 
TEST_P(AidlTest,RejectRecursiveTypeEvenIfNullable)288 TEST_P(AidlTest, RejectRecursiveTypeEvenIfNullable) {
289   // Note: in native backends @nullable is mapped to non-heap wrapper like std::optional/Option<T>
290   io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { @nullable Foo foo; }");
291   import_paths_.emplace("");
292   CaptureStderr();
293   EXPECT_EQ(nullptr, Parse("Foo.aidl", "parcelable Foo { Bar bar; }", typenames_, GetLanguage()));
294   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Foo is a recursive parcelable"));
295 }
296 
TEST_P(AidlTest,OkayIfRecursionInvolvesHeapType)297 TEST_P(AidlTest, OkayIfRecursionInvolvesHeapType) {
298   CaptureStderr();
299   std::string java_only_map_field;
300   if (GetLanguage() == Options::Language::JAVA) {
301     java_only_map_field = "  Map<String, Foo> map;\n";
302   }
303   EXPECT_NE(nullptr, Parse("Foo.aidl",
304                            "parcelable Foo {\n"
305                            "  List<Foo> list;\n" +
306                                java_only_map_field +
307                                "  Foo[] arr;\n"
308                                "  @nullable(heap=true) Foo heap_nullable;\n"
309                                "}\n",
310                            typenames_, GetLanguage()));
311   EXPECT_THAT(GetCapturedStderr(), "");
312 }
313 
TEST_P(AidlTest,InterfaceCanReferenceItself)314 TEST_P(AidlTest, InterfaceCanReferenceItself) {
315   CaptureStderr();
316   EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { void foo(in IFoo self); }", typenames_,
317                            GetLanguage()));
318   EXPECT_THAT(GetCapturedStderr(), "");
319 }
320 
TEST_P(AidlTest,HeapNullableCantApplyToOtherThanParcelables)321 TEST_P(AidlTest, HeapNullableCantApplyToOtherThanParcelables) {
322   CaptureStderr();
323   EXPECT_EQ(nullptr, Parse("Foo.aidl",
324                            "parcelable Foo {\n"
325                            "  @nullable(heap=true) String s;\n"
326                            "}",
327                            typenames_, GetLanguage()));
328   EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable(heap=true) is available to parcelables"));
329 }
330 
TEST_P(AidlTest,RejectsDuplicatedArgumentNames)331 TEST_P(AidlTest, RejectsDuplicatedArgumentNames) {
332   const string method = "package a; interface IFoo { void f(int a, int a); }";
333   const string expected_stderr =
334       "ERROR: a/IFoo.aidl:1.33-35: method 'f' has duplicate argument name 'a'\n";
335   CaptureStderr();
336   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage()));
337   EXPECT_EQ(expected_stderr, GetCapturedStderr());
338 }
339 
TEST_P(AidlTest,RejectsDuplicatedFieldNames)340 TEST_P(AidlTest, RejectsDuplicatedFieldNames) {
341   const string method = "package a; parcelable Foo { int a; String a; }";
342   const string expected_stderr = "ERROR: a/Foo.aidl:1.42-44: 'Foo' has duplicate field name 'a'\n";
343   CaptureStderr();
344   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
345   EXPECT_EQ(expected_stderr, GetCapturedStderr());
346 }
347 
TEST_P(AidlTest,AcceptsEmptyParcelable)348 TEST_P(AidlTest, AcceptsEmptyParcelable) {
349   CaptureStderr();
350   EXPECT_NE(nullptr, Parse("Foo.aidl", "parcelable Foo {}", typenames_, GetLanguage()));
351   EXPECT_EQ("", GetCapturedStderr());
352 }
353 
TEST_P(AidlTest,RejectsDuplicatedAnnotationParams)354 TEST_P(AidlTest, RejectsDuplicatedAnnotationParams) {
355   const string method = "package a; interface IFoo { @UnsupportedAppUsage(foo=1, foo=2)void f(); }";
356   const string expected_stderr = "ERROR: a/IFoo.aidl:1.56-62: Trying to redefine parameter foo.\n";
357   CaptureStderr();
358   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage()));
359   EXPECT_EQ(expected_stderr, GetCapturedStderr());
360 }
361 
TEST_P(AidlTest,RejectUnsupportedInterfaceAnnotations)362 TEST_P(AidlTest, RejectUnsupportedInterfaceAnnotations) {
363   AidlError error;
364   const string method = "package a; @nullable interface IFoo { int f(); }";
365   CaptureStderr();
366   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
367   EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable is not available."));
368   EXPECT_EQ(AidlError::BAD_TYPE, error);
369 }
370 
TEST_P(AidlTest,RejectUnsupportedTypeAnnotations)371 TEST_P(AidlTest, RejectUnsupportedTypeAnnotations) {
372   AidlError error;
373   const string method = "package a; interface IFoo { @JavaOnlyStableParcelable int f(); }";
374   CaptureStderr();
375   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, GetLanguage(), &error));
376   EXPECT_THAT(GetCapturedStderr(), HasSubstr("@JavaOnlyStableParcelable is not available."));
377   EXPECT_EQ(AidlError::BAD_TYPE, error);
378 }
379 
TEST_P(AidlTest,RejectUnsupportedParcelableDefineAnnotations)380 TEST_P(AidlTest, RejectUnsupportedParcelableDefineAnnotations) {
381   AidlError error;
382   const string method = "package a; @nullable parcelable Foo { String a; String b; }";
383   CaptureStderr();
384   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage(), &error));
385   EXPECT_THAT(GetCapturedStderr(), HasSubstr("@nullable is not available."));
386   EXPECT_EQ(AidlError::BAD_TYPE, error);
387 }
388 
TEST_P(AidlTest,ParsesNonNullableAnnotation)389 TEST_P(AidlTest, ParsesNonNullableAnnotation) {
390   auto parse_result =
391       Parse("a/IFoo.aidl", "package a; interface IFoo { String f(); }", typenames_, GetLanguage());
392   ASSERT_NE(nullptr, parse_result);
393   const AidlInterface* interface = parse_result->AsInterface();
394   ASSERT_NE(nullptr, interface);
395   ASSERT_FALSE(interface->GetMethods().empty());
396   EXPECT_FALSE(interface->GetMethods()[0]->GetType().IsNullable());
397 }
398 
TEST_P(AidlTest,ParsesNullableAnnotation)399 TEST_P(AidlTest, ParsesNullableAnnotation) {
400   auto parse_result = Parse("a/IFoo.aidl", "package a; interface IFoo { @nullable String f(); }",
401                             typenames_, GetLanguage());
402   ASSERT_NE(nullptr, parse_result);
403   const AidlInterface* interface = parse_result->AsInterface();
404   ASSERT_NE(nullptr, interface);
405   ASSERT_FALSE(interface->GetMethods().empty());
406   EXPECT_TRUE(interface->GetMethods()[0]->GetType().IsNullable());
407 }
408 
TEST_P(AidlTest,ParsesNonUtf8Annotations)409 TEST_P(AidlTest, ParsesNonUtf8Annotations) {
410   auto parse_result =
411       Parse("a/IFoo.aidl", "package a; interface IFoo { String f(); }", typenames_, GetLanguage());
412   ASSERT_NE(nullptr, parse_result);
413   const AidlInterface* interface = parse_result->AsInterface();
414   ASSERT_NE(nullptr, interface);
415   ASSERT_FALSE(interface->GetMethods().empty());
416   EXPECT_FALSE(interface->GetMethods()[0]->GetType().IsUtf8InCpp());
417 }
418 
TEST_P(AidlTest,ParsesUtf8Annotations)419 TEST_P(AidlTest, ParsesUtf8Annotations) {
420   auto parse_result = Parse("a/IFoo.aidl", "package a; interface IFoo { @utf8InCpp String f(); }",
421                             typenames_, GetLanguage());
422   ASSERT_NE(nullptr, parse_result);
423   const AidlInterface* interface = parse_result->AsInterface();
424   ASSERT_NE(nullptr, interface);
425   ASSERT_FALSE(interface->GetMethods().empty());
426   EXPECT_TRUE(interface->GetMethods()[0]->GetType().IsUtf8InCpp());
427 }
428 
TEST_P(AidlTest,VintfRequiresStructuredAndStability)429 TEST_P(AidlTest, VintfRequiresStructuredAndStability) {
430   AidlError error;
431   const string expected_stderr =
432       "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface 'stability: "
433       "\"vintf\"'\n"
434       "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface "
435       "--structured\n";
436   CaptureStderr();
437   ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
438                            GetLanguage(), &error));
439   EXPECT_EQ(expected_stderr, GetCapturedStderr());
440   ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
441 }
442 
TEST_P(AidlTest,VintfRequiresStructured)443 TEST_P(AidlTest, VintfRequiresStructured) {
444   AidlError error;
445   const string expected_stderr =
446       "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface "
447       "--structured\n";
448   CaptureStderr();
449   ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
450                            GetLanguage(), &error, {"--stability", "vintf"}));
451   EXPECT_EQ(expected_stderr, GetCapturedStderr());
452   ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
453 }
454 
TEST_P(AidlTest,VintfRequiresSpecifiedStability)455 TEST_P(AidlTest, VintfRequiresSpecifiedStability) {
456   AidlError error;
457   const string expected_stderr =
458       "ERROR: IFoo.aidl:1.16-26: Must compile @VintfStability type w/ aidl_interface 'stability: "
459       "\"vintf\"'\n";
460   CaptureStderr();
461   ASSERT_EQ(nullptr, Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
462                            GetLanguage(), &error, {"--structured"}));
463   EXPECT_EQ(expected_stderr, GetCapturedStderr());
464   ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
465 }
466 
TEST_P(AidlTest,ParsesStabilityAnnotations)467 TEST_P(AidlTest, ParsesStabilityAnnotations) {
468   AidlError error;
469   auto parse_result = Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
470                             GetLanguage(), &error, {"--structured", "--stability", "vintf"});
471   ASSERT_EQ(AidlError::OK, error);
472   ASSERT_NE(nullptr, parse_result);
473   const AidlInterface* interface = parse_result->AsInterface();
474   ASSERT_NE(nullptr, interface);
475   ASSERT_TRUE(interface->IsVintfStability());
476 }
477 
TEST_P(AidlTest,TypesShouldHaveVintfStabilityWhenCompilingWithTheVintfFlag)478 TEST_P(AidlTest, TypesShouldHaveVintfStabilityWhenCompilingWithTheVintfFlag) {
479   CaptureStderr();
480   string code =
481       "@VintfStability\n"
482       "parcelable Foo {\n"
483       "  interface INested { interface INastyNester {} }"
484       "}";
485   EXPECT_NE(nullptr, Parse("Foo.aidl", code, typenames_, GetLanguage(), nullptr,
486                            {"--structured", "--stability", "vintf"}));
487   EXPECT_EQ(GetCapturedStderr(), "");
488   auto nested = typenames_.TryGetDefinedType("Foo.INested");
489   ASSERT_NE(nullptr, nested);
490   ASSERT_TRUE(nested->IsVintfStability());
491 
492   auto nastyNester = typenames_.TryGetDefinedType("Foo.INested.INastyNester");
493   ASSERT_NE(nullptr, nastyNester);
494   ASSERT_TRUE(nastyNester->IsVintfStability());
495 }
496 
TEST_P(AidlTest,VintfStabilityAppliesToNestedTypesAsWell)497 TEST_P(AidlTest, VintfStabilityAppliesToNestedTypesAsWell) {
498   CaptureStderr();
499   EXPECT_EQ(nullptr, Parse("Foo.aidl", "parcelable Foo {}", typenames_, GetLanguage(), nullptr,
500                            {"--structured", "--stability", "vintf"}));
501   EXPECT_THAT(GetCapturedStderr(),
502               HasSubstr("Foo does not have VINTF level stability (marked @VintfStability)"));
503 }
504 
TEST_F(AidlTest,ParsesJavaOnlyStableParcelable)505 TEST_F(AidlTest, ParsesJavaOnlyStableParcelable) {
506   Options java_options = Options::From("aidl -I . -o out --structured a/Foo.aidl");
507   Options cpp_options = Options::From("aidl -I . --lang=cpp -o out -h out/include a/Foo.aidl");
508   Options cpp_structured_options =
509       Options::From("aidl --lang=cpp -I . --structured -o out -h out/include a/Foo.aidl");
510   Options rust_options = Options::From("aidl -I . --lang=rust -o out --structured a/Foo.aidl");
511   io_delegate_.SetFileContents(
512       "a/Foo.aidl",
513       StringPrintf("package a; @JavaOnlyStableParcelable parcelable Foo cpp_header \"Foo.h\" ;"));
514 
515   EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
516   EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
517 
518   CaptureStderr();
519   EXPECT_FALSE(compile_aidl(cpp_structured_options, io_delegate_));
520   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Cannot declare unstructured"));
521 
522   CaptureStderr();
523   EXPECT_FALSE(compile_aidl(rust_options, io_delegate_));
524   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Cannot declare unstructured"));
525 }
526 
TEST_F(AidlTest,ParsesNdkOnlyStableParcelable)527 TEST_F(AidlTest, ParsesNdkOnlyStableParcelable) {
528   Options java_options = Options::From("aidl -I . -o out --structured a/Foo.aidl");
529   Options ndk_structured_options =
530       Options::From("aidl --lang=ndk --structured -I . -o out -h out/include a/Foo.aidl");
531   Options rust_options = Options::From("aidl --lang=rust -I . -o out --structured a/Foo.aidl");
532   Options cpp_options = Options::From("aidl --lang=cpp -I . -o out -h out/include a/Foo.aidl");
533   io_delegate_.SetFileContents(
534       "a/Foo.aidl",
535       StringPrintf("package a; @NdkOnlyStableParcelable parcelable Foo cpp_header \"Foo.h\" ;"));
536 
537   EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
538 
539   // not considered unstructured, but it still can't be compiled directly with
540   // --structured AIDL - it can only be used as an import
541   CaptureStderr();
542   EXPECT_FALSE(compile_aidl(ndk_structured_options, io_delegate_));
543   EXPECT_THAT(GetCapturedStderr(),
544               HasSubstr("Refusing to generate code with unstructured parcelables"));
545 
546   CaptureStderr();
547   EXPECT_FALSE(compile_aidl(java_options, io_delegate_));
548   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Cannot declare unstructured"));
549 
550   CaptureStderr();
551   EXPECT_FALSE(compile_aidl(rust_options, io_delegate_));
552   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Cannot declare unstructured"));
553 }
554 
TEST_P(AidlTest,NdkAndJavaAndRustStabilityIsVintfStable)555 TEST_P(AidlTest, NdkAndJavaAndRustStabilityIsVintfStable) {
556   CaptureStderr();
557 
558   io_delegate_.SetFileContents(
559       "NonPortableThing.aidl",
560       "@NdkOnlyStableParcelable @JavaOnlyStableParcelable @RustOnlyStableParcelable parcelable "
561       "NonPortableThing ndk_header \"lol.h\" cpp_header \"lolol.h\" rust_type \"lol::Lol\";");
562   import_paths_.emplace("");
563 
564   auto result =
565       Parse("IFoo.aidl",
566             "import NonPortableThing; @VintfStability interface IFoo { NonPortableThing get(); }",
567             typenames_, GetLanguage(), nullptr, {"--structured", "--stability", "vintf"});
568 
569   if (GetLanguage() == Options::Language::NDK || GetLanguage() == Options::Language::JAVA ||
570       GetLanguage() == Options::Language::RUST) {
571     EXPECT_NE(result, nullptr);
572     EXPECT_EQ(GetCapturedStderr(), "");
573   } else {
574     EXPECT_EQ(result, nullptr);
575     EXPECT_THAT(
576         GetCapturedStderr(),
577         HasSubstr("NonPortableThing does not have VINTF level stability (marked @VintfStability)"));
578   }
579 }
580 
TEST_F(AidlTest,ParcelableSupportJavaDeriveToString)581 TEST_F(AidlTest, ParcelableSupportJavaDeriveToString) {
582   io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
583     @JavaDerive(toString=true) parcelable Foo { int a; float b; })");
584   Options java_options = Options::From("aidl --lang=java -I . -o out a/Foo.aidl");
585   EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
586 
587   string java_out;
588   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
589   EXPECT_THAT(java_out, testing::HasSubstr("public String toString() {"));
590 
591   // Other backends shouldn't be bothered
592   Options cpp_options = Options::From("aidl --lang=cpp -I . -o out -h out a/Foo.aidl");
593   EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
594 
595   Options ndk_options = Options::From("aidl --lang=ndk -I . -o out -h out a/Foo.aidl");
596   EXPECT_TRUE(compile_aidl(ndk_options, io_delegate_));
597 }
598 
TEST_F(AidlTest,UnionSupportJavaDeriveToString)599 TEST_F(AidlTest, UnionSupportJavaDeriveToString) {
600   io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
601     @JavaDerive(toString=true) union Foo { int a; int[] b; })");
602   CaptureStderr();
603   Options java_options = Options::From("aidl --lang=java -I . -o out a/Foo.aidl");
604   EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
605   EXPECT_EQ("", GetCapturedStderr());
606 }
607 
TEST_F(AidlTest,ParcelableSupportJavaDeriveEquals)608 TEST_F(AidlTest, ParcelableSupportJavaDeriveEquals) {
609   io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
610     @JavaDerive(equals=true) parcelable Foo { int a; float b; })");
611   CaptureStderr();
612   Options java_options = Options::From("aidl --lang=java -I . -o out a/Foo.aidl");
613   EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
614   EXPECT_EQ("", GetCapturedStderr());
615 
616   const std::string expected = R"--(
617   @Override
618   public boolean equals(Object other) {
619     if (this == other) return true;
620     if (other == null) return false;
621     if (!(other instanceof Foo)) return false;
622     Foo that = (Foo)other;
623     if (!java.util.Objects.deepEquals(a, that.a)) return false;
624     if (!java.util.Objects.deepEquals(b, that.b)) return false;
625     return true;
626   }
627 
628   @Override
629   public int hashCode() {
630     return java.util.Arrays.deepHashCode(java.util.Arrays.asList(a, b).toArray());
631   }
632 )--";
633 
634   string java_out;
635   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
636   EXPECT_THAT(java_out, testing::HasSubstr(expected));
637 }
638 
TEST_F(AidlTest,UnionSupportJavaDeriveEquals)639 TEST_F(AidlTest, UnionSupportJavaDeriveEquals) {
640   io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
641     @JavaDerive(equals=true) union Foo { int a; int[] b; })");
642   CaptureStderr();
643   Options java_options = Options::From("aidl --lang=java -I . -o out a/Foo.aidl");
644   EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
645   EXPECT_EQ("", GetCapturedStderr());
646 
647   const std::string expected = R"--(
648   @Override
649   public boolean equals(Object other) {
650     if (this == other) return true;
651     if (other == null) return false;
652     if (!(other instanceof Foo)) return false;
653     Foo that = (Foo)other;
654     if (_tag != that._tag) return false;
655     if (!java.util.Objects.deepEquals(_value, that._value)) return false;
656     return true;
657   }
658 
659   @Override
660   public int hashCode() {
661     return java.util.Arrays.deepHashCode(java.util.Arrays.asList(_tag, _value).toArray());
662   }
663 )--";
664 
665   string java_out;
666   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &java_out));
667   EXPECT_THAT(java_out, testing::HasSubstr(expected));
668 }
669 
TEST_F(AidlTest,RejectsJavaDeriveAnnotation)670 TEST_F(AidlTest, RejectsJavaDeriveAnnotation) {
671   {
672     io_delegate_.SetFileContents("a/Foo.aidl",
673                                  "package a; @JavaDerive(blah=true) parcelable Foo{}");
674     Options java_options = Options::From("aidl --lang=java -I . -o out a/Foo.aidl");
675     CaptureStderr();
676     EXPECT_FALSE(compile_aidl(java_options, io_delegate_));
677     const std::string expected_stderr =
678         "ERROR: a/Foo.aidl:1.11-34: Parameter blah not supported for annotation JavaDerive.";
679     EXPECT_THAT(GetCapturedStderr(),
680                 HasSubstr("Parameter blah not supported for annotation JavaDerive."));
681   }
682 
683   {
684     io_delegate_.SetFileContents("a/IFoo.aidl", "package a; @JavaDerive interface IFoo{}");
685     Options java_options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
686     CaptureStderr();
687     EXPECT_FALSE(compile_aidl(java_options, io_delegate_));
688     EXPECT_THAT(GetCapturedStderr(), HasSubstr("@JavaDerive is not available."));
689   }
690 }
691 
TEST_P(AidlTest,ParseDescriptorAnnotation)692 TEST_P(AidlTest, ParseDescriptorAnnotation) {
693   AidlError error;
694   auto parse_result = Parse("IFoo.aidl", R"(@Descriptor(value="IBar") interface IFoo{})",
695                             typenames_, GetLanguage(), &error, {"--structured"});
696   ASSERT_EQ(AidlError::OK, error);
697   ASSERT_NE(nullptr, parse_result);
698   const AidlInterface* interface = parse_result->AsInterface();
699   ASSERT_NE(nullptr, interface);
700   ASSERT_EQ("IBar", interface->GetDescriptor());
701 }
702 
TEST_P(AidlTest,UnknownAnnotation)703 TEST_P(AidlTest, UnknownAnnotation) {
704   CaptureStderr();
705   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", "package a; @Unknown interface IFoo { }", typenames_,
706                            GetLanguage()));
707   EXPECT_THAT(GetCapturedStderr(), HasSubstr("not a recognized annotation"));
708 
709   CaptureStderr();
710   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", "package a; @Unknown(param=true) interface IFoo { }",
711                            typenames_, GetLanguage()));
712   EXPECT_THAT(GetCapturedStderr(), HasSubstr("not a recognized annotation"));
713 }
714 
TEST_P(AidlTest,AcceptsOnewayMethod)715 TEST_P(AidlTest, AcceptsOnewayMethod) {
716   const string oneway_method = "package a; interface IFoo { oneway void f(int a); }";
717   EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
718 }
719 
TEST_P(AidlTest,AcceptsOnewayInterface)720 TEST_P(AidlTest, AcceptsOnewayInterface) {
721   const string oneway_interface = "package a; oneway interface IBar { void f(int a); }";
722   EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, GetLanguage()));
723 }
724 
TEST_P(AidlTest,AcceptsAnnotatedOnewayMethod)725 TEST_P(AidlTest, AcceptsAnnotatedOnewayMethod) {
726   const string oneway_method =
727       "package a; interface IFoo { @UnsupportedAppUsage oneway void f(int a); }";
728   EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage()));
729 }
730 
TEST_P(AidlTest,AnnotationsInMultiplePlaces)731 TEST_P(AidlTest, AnnotationsInMultiplePlaces) {
732   const string oneway_method =
733       "package a; interface IFoo { @UnsupportedAppUsage oneway @PropagateAllowBlocking void f(int "
734       "a); }";
735   const AidlDefinedType* defined = Parse("a/IFoo.aidl", oneway_method, typenames_, GetLanguage());
736   ASSERT_NE(nullptr, defined);
737   const AidlInterface* iface = defined->AsInterface();
738   ASSERT_NE(nullptr, iface);
739 
740   const auto& methods = iface->GetMethods();
741   ASSERT_EQ(1u, methods.size());
742   const auto& method = methods[0];
743   const AidlTypeSpecifier& ret_type = method->GetType();
744 
745   // TODO(b/151102494): these annotations should be on the method
746   ASSERT_NE(nullptr, ret_type.UnsupportedAppUsage());
747   ASSERT_TRUE(ret_type.IsPropagateAllowBlocking());
748 }
749 
TEST_P(AidlTest,AnnotationValueAttribute)750 TEST_P(AidlTest, AnnotationValueAttribute) {
751   const string content =
752       "package a; @Descriptor(\"descriptor_value\") interface IFoo { void f(int a); }";
753   const AidlDefinedType* defined = Parse("a/IFoo.aidl", content, typenames_, GetLanguage());
754   ASSERT_NE(nullptr, defined);
755   const AidlInterface* iface = defined->AsInterface();
756   ASSERT_NE(nullptr, iface);
757 
758   ASSERT_EQ("descriptor_value", iface->GetDescriptor());
759 }
760 
TEST_F(AidlTest,CheckApiForAnnotationValueAttribute)761 TEST_F(AidlTest, CheckApiForAnnotationValueAttribute) {
762   Options options = Options::From("aidl --checkapi=equal old new");
763 
764   io_delegate_.SetFileContents("old/p/IFoo.aidl",
765                                "package p; @Descriptor(value=\"v1\") interface IFoo{ void foo();}");
766   io_delegate_.SetFileContents("new/p/IFoo.aidl",
767                                "package p; @Descriptor(\"v1\") interface IFoo{ void foo();}");
768 
769   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
770 }
771 
TEST_P(AidlTest,WritesComments)772 TEST_P(AidlTest, WritesComments) {
773   string foo_interface =
774       R"(package a;
775         /* foo */
776         interface IFoo {
777           /* i */
778           int i();
779           // j
780           @nullable String j();
781           // k1
782           /* k2 */
783           @UnsupportedAppUsage oneway void k(int a);
784         })";
785 
786   CaptureStderr();
787   auto parse_result = Parse("a/IFoo.aidl", foo_interface, typenames_, GetLanguage());
788   EXPECT_NE(nullptr, parse_result);
789   EXPECT_EQ("", GetCapturedStderr());
790 
791   EXPECT_EQ((Comments{{"/* foo */"}}), parse_result->GetComments());
792 
793   const AidlInterface* interface = parse_result->AsInterface();
794   EXPECT_EQ((Comments{{"/* i */"}}), interface->GetMethods()[0]->GetComments());
795   EXPECT_EQ((Comments{{"// j\n"}}), interface->GetMethods()[1]->GetComments());
796   EXPECT_EQ((Comments{{"// k1\n"}, {"/* k2 */"}}), interface->GetMethods()[2]->GetComments());
797 }
798 
TEST_P(AidlTest,CppHeaderCanBeIdentifierAsWell)799 TEST_P(AidlTest, CppHeaderCanBeIdentifierAsWell) {
800   io_delegate_.SetFileContents("p/cpp_header.aidl",
801                                R"(package p;
802          parcelable cpp_header cpp_header "bar/header" ndk_header "ndk/bar/header" )"
803                                R"(rust_type "package::SomeType";)");
804   import_paths_.emplace("");
805   const string input_path = "p/IFoo.aidl";
806   const string input = R"(package p;
807                           import p.cpp_header;
808                           interface IFoo {
809                             // get bar
810                             cpp_header get();
811                           })";
812 
813   auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
814   EXPECT_NE(nullptr, parse_result);
815   const AidlInterface* interface = parse_result->AsInterface();
816   EXPECT_EQ((Comments{{"// get bar\n"}}), interface->GetMethods()[0]->GetComments());
817 }
818 
TEST_F(AidlTest,RejectsIfCppHeaderIsMissing)819 TEST_F(AidlTest, RejectsIfCppHeaderIsMissing) {
820   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo;");
821   Options options = Options::From("aidl -I . --lang cpp -h h -o o Foo.aidl");
822   CaptureStderr();
823   EXPECT_FALSE(compile_aidl(options, io_delegate_));
824   EXPECT_THAT(GetCapturedStderr(), HasSubstr("must have cpp_header defined"));
825 }
826 
TEST_F(AidlTest,RejectsIfTypeRefsCppHeaderIsMissing)827 TEST_F(AidlTest, RejectsIfTypeRefsCppHeaderIsMissing) {
828   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo;");
829   io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void bar(in Foo foo); }");
830   Options options = Options::From("aidl -I . --lang cpp -h h -o o IBar.aidl");
831   CaptureStderr();
832   EXPECT_FALSE(compile_aidl(options, io_delegate_));
833   EXPECT_THAT(GetCapturedStderr(), HasSubstr("must have cpp_header defined"));
834 }
835 
TEST_F(AidlTest,ParsesPreprocessedFile)836 TEST_F(AidlTest, ParsesPreprocessedFile) {
837   string simple_content = "parcelable a.Foo;\ninterface b.IBar;";
838   io_delegate_.SetFileContents("path", simple_content);
839   EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").is_resolved);
840   EXPECT_TRUE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
841   EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").is_resolved);
842   EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").is_resolved);
843 }
844 
TEST_F(AidlTest,ParsesPreprocessedFileWithWhitespace)845 TEST_F(AidlTest, ParsesPreprocessedFileWithWhitespace) {
846   string simple_content = "parcelable    a.Foo;\n  interface b.IBar  ;\t";
847   io_delegate_.SetFileContents("path", simple_content);
848 
849   EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").is_resolved);
850   EXPECT_TRUE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
851   EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").is_resolved);
852   EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").is_resolved);
853 }
854 
TEST_P(AidlTest,PreferImportToPreprocessed)855 TEST_P(AidlTest, PreferImportToPreprocessed) {
856   io_delegate_.SetFileContents("preprocessed", "interface another.IBar;");
857   io_delegate_.SetFileContents("one/IBar.aidl", "package one; "
858                                                 "interface IBar {}");
859   preprocessed_files_.push_back("preprocessed");
860   import_paths_.emplace("");
861   auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
862                             typenames_, GetLanguage());
863   EXPECT_NE(nullptr, parse_result);
864 
865   // We expect to know about both kinds of IBar
866   EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
867   EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
868   // But if we request just "IBar" we should get our imported one.
869   AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", /*array=*/std::nullopt, nullptr, {});
870   ambiguous_type.Resolve(typenames_, parse_result);
871   EXPECT_EQ("one.IBar", ambiguous_type.GetName());
872 }
873 
874 // Special case of PreferImportToPreprocessed. Imported type should be preferred
875 // even when the preprocessed file already has the same type.
TEST_P(AidlTest,B147918827)876 TEST_P(AidlTest, B147918827) {
877   io_delegate_.SetFileContents("preprocessed", "interface another.IBar;\ninterface one.IBar;");
878   io_delegate_.SetFileContents("one/IBar.aidl",
879                                "package one; "
880                                "interface IBar {}");
881   preprocessed_files_.push_back("preprocessed");
882   import_paths_.emplace("");
883   auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
884                             typenames_, GetLanguage());
885   EXPECT_NE(nullptr, parse_result);
886 
887   // We expect to know about both kinds of IBar
888   EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
889   EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
890   // But if we request just "IBar" we should get our imported one.
891   AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", /*array=*/std::nullopt, nullptr, {});
892   ambiguous_type.Resolve(typenames_, parse_result);
893   EXPECT_EQ("one.IBar", ambiguous_type.GetName());
894 }
895 
TEST_F(AidlTest,WritePreprocessedFile)896 TEST_F(AidlTest, WritePreprocessedFile) {
897   io_delegate_.SetFileContents("p/Outer.aidl",
898                                "package p; parcelable Outer.Inner;");
899   io_delegate_.SetFileContents("one/IBar.aidl", "package one; import p.Outer;"
900                                                 "interface IBar {}");
901 
902   vector<string> args{"aidl", "--preprocess", "preprocessed",
903                       "-I.",  "p/Outer.aidl", "one/IBar.aidl"};
904   Options options = Options::From(args);
905   EXPECT_TRUE(::android::aidl::Preprocess(options, io_delegate_));
906 
907   std::map<std::string, std::string> expected = {{"preprocessed",
908                                                   "parcelable p.Outer.Inner;\n"
909                                                   "interface one.IBar {\n"
910                                                   "}\n"}};
911   EXPECT_THAT(io_delegate_.OutputFiles(), testing::Eq(expected));
912 }
913 
TEST_F(AidlTest,PreprocessVariousThings)914 TEST_F(AidlTest, PreprocessVariousThings) {
915   io_delegate_.SetFileContents("foo/bar/IFoo.aidl",
916                                "package foo.bar;\n"
917                                "interface IFoo {\n"
918                                "    int foo();\n"
919                                "    const int FOO = foo.bar.Bar.BAR + 1; // should be 44\n"
920                                "}\n");
921   io_delegate_.SetFileContents("foo/bar/Bar.aidl",
922                                "package foo.bar;\n"
923                                "parcelable Bar {\n"
924                                "    const int BAR = imported.Foo.FOO + 1; // should be 43\n"
925                                "    imported.Foo foo;\n"
926                                "}\n");
927   io_delegate_.SetFileContents("foo/bar/Gen.aidl",
928                                "package foo.bar;\n"
929                                "parcelable Gen<T> {\n"
930                                "}\n");
931   io_delegate_.SetFileContents("foo/bar/Enum.aidl",
932                                "package foo.bar;\n"
933                                "enum Enum {\n"
934                                "    FOO = 3, BAR = FOO + 3, // should be 3, 6\n"
935                                "}\n");
936   io_delegate_.SetFileContents("sub/imported/Foo.aidl",
937                                "package imported;\n"
938                                "parcelable Foo {\n"
939                                "    const int FOO = 42;\n"
940                                "}\n");
941 
942   vector<string> args = {
943       "aidl",
944       "--preprocess",
945       "preprocessed",
946       "-Isub",
947       "-I.",
948       "foo/bar/IFoo.aidl",
949       "foo/bar/Bar.aidl",
950       "foo/bar/Gen.aidl",
951       "foo/bar/Enum.aidl",
952   };
953   ASSERT_TRUE(Preprocess(Options::From(args), io_delegate_));
954   std::string preprocessed =
955       "interface foo.bar.IFoo {\n"
956       "  const int FOO = 44;\n"
957       "}\n"
958       "parcelable foo.bar.Bar {\n"
959       "  const int BAR = 43;\n"
960       "}\n"
961       "parcelable foo.bar.Gen<T> {\n"
962       "}\n"
963       "enum foo.bar.Enum {\n"
964       "  FOO = 3,\n"
965       "  BAR = 6,\n"
966       "}\n";
967   std::map<std::string, std::string> expected = {{"preprocessed", preprocessed}};
968   EXPECT_THAT(io_delegate_.OutputFiles(), testing::Eq(expected));
969 
970   // use preprocessed
971   io_delegate_.SetFileContents("a/Foo.aidl",
972                                "package a; parcelable Foo { const int y = foo.bar.Bar.BAR; }");
973   io_delegate_.SetFileContents("preprocessed", preprocessed);
974   CaptureStderr();
975   auto options = Options::From("aidl --lang java -I . -o out a/Foo.aidl -ppreprocessed");
976   EXPECT_TRUE(compile_aidl(options, io_delegate_));
977   EXPECT_EQ("", GetCapturedStderr());
978   string code;
979   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
980   EXPECT_THAT(code, testing::HasSubstr("public static final int y = 43;"));
981 }
982 
TEST_F(AidlTest,AllowMultipleUnstructuredNestedParcelablesInASingleDocument)983 TEST_F(AidlTest, AllowMultipleUnstructuredNestedParcelablesInASingleDocument) {
984   io_delegate_.SetFileContents("p/IFoo.aidl",
985                                "package p;\n"
986                                "import x.Outer;\n"
987                                "interface IFoo {\n"
988                                "  void foo(in Outer.Inner1 in1, in Outer.Inner2 in2);\n"
989                                "}");
990   io_delegate_.SetFileContents("imported/x/Outer.aidl",
991                                "package x;\n"
992                                "parcelable Outer.Inner1;\n"
993                                "parcelable Outer.Inner2;\n");
994   auto opt = Options::From("aidl -I . -Iimported --lang=java p/IFoo.aidl");
995   CaptureStderr();
996   EXPECT_TRUE(compile_aidl(opt, io_delegate_));
997   EXPECT_EQ("", GetCapturedStderr());
998 }
999 
TEST_F(AidlTest,StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlLater)1000 TEST_F(AidlTest,
1001        StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlLater) {
1002   // Main doc(Foo.aidl) is loaded
1003   // And then framework.aidl is loaded as preprocessed. (conflict)
1004   io_delegate_.SetFileContents("sdk/framework.aidl", "parcelable x.Foo.Inner;\n");
1005   io_delegate_.SetFileContents("x/Foo.aidl",
1006                                "package x;\n"
1007                                "parcelable Foo.Inner;\n");
1008   auto opt = Options::From("aidl -psdk/framework.aidl -I. x/Foo.aidl");
1009   CaptureStderr();
1010   EXPECT_TRUE(compile_aidl(opt, io_delegate_));
1011   EXPECT_EQ("", GetCapturedStderr());
1012 }
1013 
TEST_F(AidlTest,StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlFirst)1014 TEST_F(AidlTest,
1015        StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlFirst) {
1016   // Main doc(IBar.aidl) is loaded first.
1017   // Framework.aidl is loaded as preprocessed.
1018   // And then import(Foo.aidl) is loaded. (conflict)
1019   io_delegate_.SetFileContents("sdk/framework.aidl", "parcelable x.Foo.Inner;\n");
1020   io_delegate_.SetFileContents("x/IBar.aidl",
1021                                "package x;\n"
1022                                "import x.Foo;\n"
1023                                "interface IBar {\n"
1024                                "  void bar(in Foo.Inner inner);\n"
1025                                "}");
1026   io_delegate_.SetFileContents("x/Foo.aidl",
1027                                "package x;\n"
1028                                "parcelable Foo.Inner;\n");
1029   auto opt = Options::From("aidl -psdk/framework.aidl -I. x/IBar.aidl");
1030   CaptureStderr();
1031   EXPECT_TRUE(compile_aidl(opt, io_delegate_));
1032   EXPECT_EQ("", GetCapturedStderr());
1033 }
1034 
TEST_F(AidlTest,PreprocessedFileCantDeclarePackage)1035 TEST_F(AidlTest, PreprocessedFileCantDeclarePackage) {
1036   string simple_content = "package xxx; parcelable a.Foo;";
1037   io_delegate_.SetFileContents("path", simple_content);
1038   CaptureStderr();
1039   EXPECT_FALSE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
1040   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Preprocessed file can't declare package."));
1041 }
1042 
TEST_F(AidlTest,RejectQualifiedTypeNameUnlessPreprocessed)1043 TEST_F(AidlTest, RejectQualifiedTypeNameUnlessPreprocessed) {
1044   string simple_content = "parcelable a.Foo {}";
1045   io_delegate_.SetFileContents("path", simple_content);
1046   CaptureStderr();
1047   EXPECT_FALSE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/false));
1048   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Type name can't be qualified"));
1049 }
1050 
TEST_P(AidlTest,PreprocessedCanDeclareJavaStyleBuiltinTypes)1051 TEST_P(AidlTest, PreprocessedCanDeclareJavaStyleBuiltinTypes) {
1052   string contents = R"(
1053     interface android.os.IBinder;
1054     interface android.os.IInterface;
1055     parcelable android.os.ParcelFileDescriptor;
1056   )";
1057   io_delegate_.SetFileContents("path", contents);
1058   CaptureStderr();
1059   EXPECT_TRUE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
1060   EXPECT_THAT(GetCapturedStderr(), "");
1061 }
1062 
TEST_P(AidlTest,SupportDeprecated)1063 TEST_P(AidlTest, SupportDeprecated) {
1064   struct TestCase {
1065     std::string output_file;
1066     std::string annotation;
1067   };
1068 
1069   auto CheckDeprecated = [&](const std::string& filename, const std::string& contents,
1070                              std::vector<std::pair<Options::Language, TestCase>> expectations) {
1071     io_delegate_.SetFileContents(filename, contents);
1072 
1073     auto options = Options::From("aidl -I . --lang=" + to_string(GetLanguage()) + " " + filename +
1074                                  " --out=out --header_out=out");
1075     EXPECT_TRUE(compile_aidl(options, io_delegate_));
1076     for (const auto& [lang, test_case] : expectations) {
1077       if (lang != GetLanguage()) continue;
1078       string output;
1079       EXPECT_TRUE(io_delegate_.GetWrittenContents(test_case.output_file, &output));
1080       EXPECT_THAT(output, HasSubstr(test_case.annotation));
1081     }
1082   };
1083 
1084   // Emit escaped string for notes
1085   CheckDeprecated(
1086       "IFoo.aidl",
1087       R"(interface IFoo {
1088            /**
1089             * @note asdf
1090             * @deprecated a really long deprecation message
1091             *
1092             *    which is really long
1093             * @param foo bar
1094             */
1095            List<String> foo();
1096         })",
1097       {
1098           {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1099           {Options::Language::CPP,
1100            {"out/IFoo.h",
1101             R"(__attribute__((deprecated("a really long deprecation message which is really long"))))"}},
1102           {Options::Language::NDK,
1103            {"out/aidl/IFoo.h",
1104             R"(__attribute__((deprecated("a really long deprecation message which is really long"))))"}},
1105           {Options::Language::RUST,
1106            {"out/IFoo.rs",
1107             R"(#[deprecated = "a really long deprecation message which is really long"])"}},
1108       });
1109 
1110   // In AIDL @deprecated can be in block comments as well as javadoc style
1111   CheckDeprecated(
1112       "IFoo.aidl",
1113       "interface IFoo {\n"
1114       "  /* @deprecated use bar() */\n"
1115       "  List<String> foo();\n"
1116       "}",
1117       {
1118           {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1119           {Options::Language::JAVA, {"out/IFoo.java", "/** @deprecated use bar() */"}},
1120           {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated(\"use bar()\")))"}},
1121           {Options::Language::NDK,
1122            {"out/aidl/IFoo.h", "__attribute__((deprecated(\"use bar()\")))"}},
1123           {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated = \"use bar()\"]"}},
1124       });
1125 
1126   // but not in line comments
1127   auto parsed = Parse("IFoo.aidl", "// @deprecated\ninterface IFoo {}", typenames_, GetLanguage());
1128   EXPECT_FALSE(parsed->IsDeprecated());
1129 
1130   // parcelable
1131   CheckDeprecated("Foo.aidl",
1132                   "parcelable Foo {\n"
1133                   "  /** @deprecated use bar*/\n"
1134                   "  int foo = 0;\n"
1135                   "}",
1136                   {
1137                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1138                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1139                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1140                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1141                   });
1142 
1143   // interface constants
1144   CheckDeprecated("IFoo.aidl",
1145                   "interface IFoo {\n"
1146                   "  /** @deprecated use bar*/\n"
1147                   "  const int FOO = 0;\n"
1148                   "}",
1149                   {
1150                       {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1151                       {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
1152                       {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
1153                       {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
1154                   });
1155 
1156   // union fields
1157   CheckDeprecated("Foo.aidl",
1158                   "union Foo {\n"
1159                   "  int bar = 0;\n"
1160                   "  /** @deprecated use bar*/\n"
1161                   "  int foo;\n"
1162                   "}",
1163                   {
1164                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1165                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1166                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1167                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1168                   });
1169 
1170   CheckDeprecated("Foo.aidl",
1171                   "/** @deprecated use Bar */\n"
1172                   "parcelable Foo {}",
1173                   {
1174                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1175                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1176                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1177                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1178                   });
1179 
1180   CheckDeprecated("Foo.aidl",
1181                   "/** @deprecated use Bar */\n"
1182                   "union Foo { int foo = 0; }",
1183                   {
1184                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1185                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1186                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1187                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1188                   });
1189 
1190   CheckDeprecated("IFoo.aidl",
1191                   "/** @deprecated use IBar */\n"
1192                   "interface IFoo {}",
1193                   {
1194                       {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1195                       {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
1196                       {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
1197                       {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
1198                   });
1199 
1200   CheckDeprecated("Foo.aidl",
1201                   "/** @deprecated use IBar */\n"
1202                   "enum Foo { FOO }",
1203                   {
1204                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1205                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1206                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1207                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1208                   });
1209 
1210   CheckDeprecated("Foo.aidl",
1211                   "enum Foo {\n"
1212                   " /** @deprecated */\n"
1213                   " FOO,\n"
1214                   " BAR,\n"
1215                   "}",
1216                   {
1217                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1218                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1219                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1220                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1221                   });
1222 }
1223 
TEST_P(AidlTest,RequireOuterClass)1224 TEST_P(AidlTest, RequireOuterClass) {
1225   const string expected_stderr =
1226       "ERROR: p/IFoo.aidl: Couldn't find import for class Inner. Searched here:\n - ./\nERROR: "
1227       "p/IFoo.aidl:1.54-60: Failed to resolve 'Inner'\n";
1228   io_delegate_.SetFileContents("p/Outer.aidl",
1229                                "package p; parcelable Outer.Inner;");
1230   import_paths_.emplace("");
1231   CaptureStderr();
1232   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1233                            "package p; import p.Outer; interface IFoo { void f(in Inner c); }",
1234                            typenames_, GetLanguage()));
1235   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1236 }
1237 
TEST_P(AidlTest,ParseCompoundParcelableFromPreprocess)1238 TEST_P(AidlTest, ParseCompoundParcelableFromPreprocess) {
1239   io_delegate_.SetFileContents("preprocessed",
1240                                "parcelable p.Outer.Inner cpp_header \"inner.h\" ndk_header "
1241                                "\"ndk/inner.h\" rust_type \"package::Inner\";");
1242   preprocessed_files_.push_back("preprocessed");
1243   auto parse_result = Parse("p/IFoo.aidl", "package p; interface IFoo { void f(in Inner c); }",
1244                             typenames_, GetLanguage());
1245   // Require legacy behavior - inner class name can be used without outer class name.
1246   EXPECT_NE(nullptr, parse_result);
1247 }
1248 
TEST_F(AidlTest,ApiMappingAcceptsUnstructuredParcelables)1249 TEST_F(AidlTest, ApiMappingAcceptsUnstructuredParcelables) {
1250   io_delegate_.SetFileContents("p/Foo.aidl", "package p; parcelable Foo;");
1251 
1252   Options options1 = Options::From("aidl -I . --apimapping mapping.txt p/Foo.aidl");
1253   CaptureStderr();
1254   EXPECT_EQ(0, aidl_entry(options1, io_delegate_));
1255   EXPECT_EQ("", GetCapturedStderr());
1256 }
1257 
TEST_F(AidlTest,FailOnParcelable)1258 TEST_F(AidlTest, FailOnParcelable) {
1259   const string expected_foo_stderr =
1260       "ERROR: p/IFoo.aidl:1.22-27: Refusing to generate code with unstructured parcelables. "
1261       "Declared parcelables should be in their own file and/or cannot be used with --structured "
1262       "interfaces.\n";
1263   io_delegate_.SetFileContents("p/IFoo.aidl", "package p; parcelable IFoo;");
1264 
1265   // By default, we shouldn't fail on parcelable.
1266   Options options1 = Options::From("aidl -I . p/IFoo.aidl");
1267   CaptureStderr();
1268   EXPECT_TRUE(compile_aidl(options1, io_delegate_));
1269   EXPECT_EQ("", GetCapturedStderr());
1270 
1271   // -b considers this an error
1272   Options options2 = Options::From("aidl -I . -b p/IFoo.aidl");
1273   CaptureStderr();
1274   EXPECT_FALSE(compile_aidl(options2, io_delegate_));
1275   EXPECT_EQ(expected_foo_stderr, GetCapturedStderr());
1276 
1277   const string expected_bar_stderr =
1278       "ERROR: p/IBar.aidl:1.22-26: Refusing to generate code with unstructured parcelables. "
1279       "Declared parcelables should be in their own file and/or cannot be used with --structured "
1280       "interfaces.\n";
1281   io_delegate_.SetFileContents("p/IBar.aidl", "package p; parcelable Foo; interface IBar{}");
1282 
1283   // With '-b' option, a parcelable and an interface should fail.
1284   Options options3 = Options::From("aidl -I . p/IBar.aidl");
1285   CaptureStderr();
1286   EXPECT_TRUE(compile_aidl(options3, io_delegate_));
1287   EXPECT_EQ("", GetCapturedStderr());
1288   Options options4 = Options::From("aidl -I . -b p/IBar.aidl");
1289   CaptureStderr();
1290   EXPECT_FALSE(compile_aidl(options4, io_delegate_));
1291   EXPECT_EQ(expected_bar_stderr, GetCapturedStderr());
1292 }
1293 
TEST_P(AidlTest,ImportingJavaStyleBuiltinTypesIsAllowed)1294 TEST_P(AidlTest, ImportingJavaStyleBuiltinTypesIsAllowed) {
1295   string contents = R"(
1296     import android.os.IBinder;
1297     import android.os.IInterface;
1298     interface IFoo {
1299       void foo(in IBinder b);
1300     }
1301   )";
1302   EXPECT_NE(nullptr, Parse("IFoo.aidl", contents, typenames_, GetLanguage()));
1303 }
1304 
TEST_P(AidlTest,StructuredFailOnUnstructuredParcelable)1305 TEST_P(AidlTest, StructuredFailOnUnstructuredParcelable) {
1306   const string expected_stderr =
1307       "o.WhoKnowsWhat is not structured, but this is a structured interface";
1308   io_delegate_.SetFileContents("o/WhoKnowsWhat.aidl",
1309                                "package o; parcelable WhoKnowsWhat cpp_header \"who_knows.h\" "
1310                                "ndk_header \"ndk/who_knows.h\" rust_type \"WhoKnows\";");
1311   import_paths_.emplace("");
1312   AidlError error;
1313   CaptureStderr();
1314   EXPECT_EQ(
1315       nullptr,
1316       Parse("p/IFoo.aidl",
1317             "package p; import o.WhoKnowsWhat; interface IFoo { void f(in WhoKnowsWhat thisIs); }",
1318             typenames_, GetLanguage(), &error, {"--structured"}));
1319   EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_stderr));
1320   EXPECT_EQ(AidlError::NOT_STRUCTURED, error);
1321 }
1322 
TEST_P(AidlTest,FailOnDuplicateConstantNames)1323 TEST_P(AidlTest, FailOnDuplicateConstantNames) {
1324   AidlError error;
1325   const string expected_stderr =
1326       "ERROR: p/IFoo.aidl:4.34-45: Found duplicate constant name 'DUPLICATED'\n";
1327   CaptureStderr();
1328   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1329                            R"(package p;
1330                       interface IFoo {
1331                         const String DUPLICATED = "d";
1332                         const int DUPLICATED = 1;
1333                       }
1334                    )",
1335                            typenames_, GetLanguage(), &error));
1336   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1337   EXPECT_EQ(AidlError::BAD_TYPE, error);
1338 }
1339 
TEST_P(AidlTest,FailOnDoubleUnderscore)1340 TEST_P(AidlTest, FailOnDoubleUnderscore) {
1341   AidlError error;
1342   const string expected_stderr = "ERROR: p/IFoo.aidl:3.52-57: Could not parse integer: 1__0\n";
1343   CaptureStderr();
1344   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1345                            R"(package p;
1346                       interface IFoo {
1347                         const int UNDERSCORE_USER = 1__0;
1348                       }
1349                    )",
1350                            typenames_, GetLanguage(), &error));
1351   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1352   EXPECT_EQ(AidlError::PARSE_ERROR, error);
1353 }
1354 
TEST_P(AidlTest,FailOnUnderscoreBeforeModifier)1355 TEST_P(AidlTest, FailOnUnderscoreBeforeModifier) {
1356   AidlError error;
1357   const string expected_stderr = "ERROR: p/IFoo.aidl:3.52-59: Could not parse hexvalue: 0xFF_L\n";
1358   CaptureStderr();
1359   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1360                            R"(package p;
1361                       interface IFoo {
1362                         const int UNDERSCORE_USER = 0xFF_L;
1363                       }
1364                    )",
1365                            typenames_, GetLanguage(), &error));
1366   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1367   EXPECT_EQ(AidlError::PARSE_ERROR, error);
1368 }
1369 
TEST_P(AidlTest,FailOnEndingUnderscore)1370 TEST_P(AidlTest, FailOnEndingUnderscore) {
1371   AidlError error;
1372   const string expected_stderr = "ERROR: p/IFoo.aidl:3.52-56: Could not parse integer: 10_\n";
1373   CaptureStderr();
1374   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1375                            R"(package p;
1376                       interface IFoo {
1377                         const int UNDERSCORE_USER = 10_;
1378                       }
1379                    )",
1380                            typenames_, GetLanguage(), &error));
1381   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1382   EXPECT_EQ(AidlError::PARSE_ERROR, error);
1383 }
1384 
TEST_P(AidlTest,FailOnLeadingUnderscore)1385 TEST_P(AidlTest, FailOnLeadingUnderscore) {
1386   AidlError error;
1387   const string expected_stderr =
1388       "ERROR: p/IFoo.aidl:3.52-56: Can't find _10 in IFoo\nERROR: p/IFoo.aidl:3.52-56: Unknown "
1389       "reference '_10'\n";
1390   CaptureStderr();
1391   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1392                            R"(package p;
1393                       interface IFoo {
1394                         const int UNDERSCORE_USER = _10;
1395                       }
1396                    )",
1397                            typenames_, GetLanguage(), &error));
1398   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1399   EXPECT_EQ(AidlError::BAD_TYPE, error);
1400 }
1401 
TEST_P(AidlTest,InvalidConstString)1402 TEST_P(AidlTest, InvalidConstString) {
1403   AidlError error;
1404   const string expected_stderr =
1405       "ERROR: p/IFoo.aidl:3.47-60: Found invalid character '\\' at index 4 in string constant "
1406       "'\"test\\\"test\"'\n";
1407   CaptureStderr();
1408   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1409                            R"(package p;
1410                       interface IFoo {
1411                         const String someVar = "test\"test";
1412                       }
1413                    )",
1414                            typenames_, GetLanguage(), &error));
1415   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1416   EXPECT_EQ(AidlError::BAD_TYPE, error);
1417 }
1418 
TEST_F(AidlTest,InvalidCharLiteral)1419 TEST_F(AidlTest, InvalidCharLiteral) {
1420   auto filename = "Foo.aidl";
1421   char code[] = "parcelable Foo { char a = '\0'; char b = '\t'; }";
1422   io_delegate_.SetFileContents(filename,
1423                                string{code, sizeof(code) - 1});  // -1 to drop nil at the end
1424   CaptureStderr();
1425   EXPECT_TRUE(Parser::Parse(filename, io_delegate_, typenames_, /*is_preprocessed=*/false));
1426   auto err = GetCapturedStderr();
1427   EXPECT_THAT(err, HasSubstr("Invalid character literal \\0"));
1428   EXPECT_THAT(err, HasSubstr("Invalid character literal \\t"));
1429 }
1430 
TEST_P(AidlTest,RejectUnstructuredParcelablesInNDKandRust)1431 TEST_P(AidlTest, RejectUnstructuredParcelablesInNDKandRust) {
1432   io_delegate_.SetFileContents("o/Foo.aidl", "package o; parcelable Foo cpp_header \"cpp/Foo.h\";");
1433   const auto options =
1434       Options::From("aidl --lang=" + to_string(GetLanguage()) + " -o out -h out -I. o/Foo.aidl");
1435   const bool reject_unstructured_parcelables =
1436       GetLanguage() == Options::Language::NDK || GetLanguage() == Options::Language::RUST;
1437   const string expected_err = reject_unstructured_parcelables
1438                                   ? "Refusing to generate code with unstructured parcelables"
1439                                   : "";
1440   CaptureStderr();
1441   EXPECT_EQ(compile_aidl(options, io_delegate_), !reject_unstructured_parcelables);
1442   EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_err));
1443 }
1444 
TEST_F(AidlTest,CosntantValueType)1445 TEST_F(AidlTest, CosntantValueType) {
1446   unique_ptr<AidlConstantValue> num{AidlConstantValue::Integral(AIDL_LOCATION_HERE, "1")};
1447   EXPECT_EQ(num->GetType(), AidlConstantValue::Type::INT8);
1448 }
1449 
TEST_P(AidlTest,FailOnTooBigConstant)1450 TEST_P(AidlTest, FailOnTooBigConstant) {
1451   AidlError error;
1452   const string expected_stderr =
1453       "ERROR: p/IFoo.aidl:3.48-52: Invalid type specifier for an int32 literal: byte (256).\n";
1454   CaptureStderr();
1455   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1456                            R"(package p;
1457                       interface IFoo {
1458                         const byte type2small = 256;
1459                       }
1460                    )",
1461                            typenames_, GetLanguage(), &error));
1462   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1463   EXPECT_EQ(AidlError::BAD_TYPE, error);
1464 }
1465 
TEST_F(AidlTest,BoolConstantsEvaluatesToIntegers)1466 TEST_F(AidlTest, BoolConstantsEvaluatesToIntegers) {
1467   io_delegate_.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { const int y = true; }");
1468   CaptureStderr();
1469   auto options = Options::From("aidl -I . --lang java -o out a/Foo.aidl");
1470   EXPECT_TRUE(compile_aidl(options, io_delegate_));
1471   EXPECT_EQ("", GetCapturedStderr());
1472   string code;
1473   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
1474   EXPECT_THAT(code, testing::HasSubstr("public static final int y = 1;"));
1475 }
1476 
TEST_F(AidlTest,AidlConstantValue_EvaluatedValue)1477 TEST_F(AidlTest, AidlConstantValue_EvaluatedValue) {
1478   using Ptr = unique_ptr<AidlConstantValue>;
1479   const AidlLocation& loc = AIDL_LOCATION_HERE;
1480 
1481   EXPECT_EQ('c', Ptr(AidlConstantValue::Character(loc, "'c'"))->EvaluatedValue<char16_t>());
1482   EXPECT_EQ("abc", Ptr(AidlConstantValue::String(loc, "\"abc\""))->EvaluatedValue<string>());
1483   EXPECT_FLOAT_EQ(1.0f, Ptr(AidlConstantValue::Floating(loc, "1.0f"))->EvaluatedValue<float>());
1484   EXPECT_EQ(true, Ptr(AidlConstantValue::Boolean(loc, true))->EvaluatedValue<bool>());
1485 
1486   AidlBinaryConstExpression one_plus_one(loc, Ptr(AidlConstantValue::Integral(loc, "1")), "+",
1487                                          Ptr(AidlConstantValue::Integral(loc, "1")));
1488   EXPECT_EQ(2, one_plus_one.EvaluatedValue<int32_t>());
1489 
1490   auto values = unique_ptr<vector<Ptr>>{new vector<Ptr>};
1491   values->emplace_back(AidlConstantValue::String(loc, "\"hello\""));
1492   values->emplace_back(AidlConstantValue::String(loc, "\"world\""));
1493   vector<string> expected{"hello", "world"};
1494   EXPECT_EQ(
1495       expected,
1496       Ptr(AidlConstantValue::Array(loc, std::move(values)))->EvaluatedValue<vector<string>>());
1497 
1498   // evaluate array of floating
1499   vector<float> testFloats({32.f, 14.f, 50.f});
1500   auto testFloatValues = unique_ptr<vector<Ptr>>{new vector<Ptr>()};
1501   testFloatValues->emplace_back(AidlConstantValue::Floating(loc, "32.f"));
1502   testFloatValues->emplace_back(AidlConstantValue::Floating(loc, "14.f"));
1503   testFloatValues->emplace_back(AidlConstantValue::Floating(loc, "50.f"));
1504   EXPECT_EQ(testFloats, Ptr(AidlConstantValue::Array(loc, std::move(testFloatValues)))
1505                             ->EvaluatedValue<vector<float>>());
1506 }
1507 
1508 // TODO: b/313951203 add floating/string operands test
TEST_F(AidlTest,AidlBinaryConstExpression_CompatibleTypes)1509 TEST_F(AidlTest, AidlBinaryConstExpression_CompatibleTypes) {
1510   const AidlLocation& loc = AIDL_LOCATION_HERE;
1511   static const std::unordered_map<AidlConstantValue::Type,
1512                                   const std::unordered_set<AidlConstantValue::Type>>
1513       compatibleTypesMap({{AidlConstantValue::Type::BOOLEAN,
1514                            {AidlConstantValue::Type::BOOLEAN, AidlConstantValue::Type::INT8,
1515                             AidlConstantValue::Type::INT32, AidlConstantValue::Type::INT64}},
1516                           {AidlConstantValue::Type::INT8,
1517                            {AidlConstantValue::Type::BOOLEAN, AidlConstantValue::Type::INT8,
1518                             AidlConstantValue::Type::INT32, AidlConstantValue::Type::INT64}},
1519                           {AidlConstantValue::Type::INT32,
1520                            {AidlConstantValue::Type::BOOLEAN, AidlConstantValue::Type::INT8,
1521                             AidlConstantValue::Type::INT32, AidlConstantValue::Type::INT64}},
1522                           {AidlConstantValue::Type::INT64,
1523                            {AidlConstantValue::Type::BOOLEAN, AidlConstantValue::Type::INT8,
1524                             AidlConstantValue::Type::INT32, AidlConstantValue::Type::INT64}},
1525                           {AidlConstantValue::Type::ARRAY, {AidlConstantValue::Type::ARRAY}},
1526                           {AidlConstantValue::Type::STRING, {AidlConstantValue::Type::STRING}}});
1527 
1528   // go over all possible combination
1529   for (int l = 0; l <= (int)AidlConstantValue::Type::ERROR; ++l) {
1530     for (int r = 0; r <= (int)AidlConstantValue::Type::ERROR; ++r) {
1531       const AidlConstantValue::Type lType = static_cast<AidlConstantValue::Type>(l),
1532                                     rType = static_cast<AidlConstantValue::Type>(r);
1533       const auto typeItor = compatibleTypesMap.find(lType);
1534       const bool isCompatibleOperandType = typeItor != compatibleTypesMap.end() &&
1535                                            typeItor->second.find(rType) != typeItor->second.end();
1536       const bool isCompatibleArrayType =
1537           isCompatibleOperandType || (lType == AidlConstantValue::Type::FLOATING &&
1538                                       rType == AidlConstantValue::Type::FLOATING);
1539       EXPECT_EQ(isCompatibleOperandType,
1540                 AidlBinaryConstExpression::AreCompatibleOperandTypes(lType, rType))
1541           << AidlConstantValue::ToString(lType) << ", " << AidlConstantValue::ToString(rType);
1542       EXPECT_EQ(isCompatibleArrayType,
1543                 AidlBinaryConstExpression::AreCompatibleArrayTypes(lType, rType))
1544           << AidlConstantValue::ToString(lType) << ", " << AidlConstantValue::ToString(rType);
1545     }
1546   }
1547 }
1548 
TEST_F(AidlTest,AidlConstantCharacterDefault)1549 TEST_F(AidlTest, AidlConstantCharacterDefault) {
1550   auto char_type = typenames_.MakeResolvedType(AIDL_LOCATION_HERE, "char", false);
1551   auto default_value = unique_ptr<AidlConstantValue>(AidlConstantValue::Default(*char_type));
1552   EXPECT_EQ("'\\0'", default_value->ValueString(*char_type, cpp::ConstantValueDecorator));
1553   EXPECT_EQ("'\\0'", default_value->ValueString(*char_type, ndk::ConstantValueDecorator));
1554   EXPECT_EQ("'\\0'", default_value->ValueString(*char_type, java::ConstantValueDecorator));
1555 }
1556 
TEST_P(AidlTest,FailOnManyDefinedTypes)1557 TEST_P(AidlTest, FailOnManyDefinedTypes) {
1558   AidlError error;
1559   const string expected_stderr =
1560       "ERROR: p/IFoo.aidl:3.33-38: You must declare only one type per file.\n";
1561   CaptureStderr();
1562   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1563                            R"(package p;
1564                       interface IFoo {}
1565                       parcelable IBar {}
1566                       parcelable StructuredParcelable {}
1567                       interface IBaz {}
1568                   )",
1569                            typenames_, GetLanguage(), &error));
1570   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1571   // Parse success is important for clear error handling even if the cases aren't
1572   // actually supported in code generation.
1573   EXPECT_EQ(AidlError::BAD_TYPE, error);
1574 }
1575 
TEST_P(AidlTest,FailOnNoDefinedTypes)1576 TEST_P(AidlTest, FailOnNoDefinedTypes) {
1577   AidlError error;
1578   const string expected_stderr = "ERROR: p/IFoo.aidl:1.11-11: syntax error, unexpected $end\n";
1579   const string expected_stderr_newbison =
1580       "ERROR: p/IFoo.aidl:1.11-11: syntax error, unexpected end of file\n";
1581   CaptureStderr();
1582   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p;)", typenames_, GetLanguage(), &error));
1583   EXPECT_THAT(GetCapturedStderr(),
1584               testing::AnyOf(testing::Eq(expected_stderr), testing::Eq(expected_stderr_newbison)));
1585   EXPECT_EQ(AidlError::PARSE_ERROR, error);
1586 }
1587 
TEST_P(AidlTest,FailOnEmptyListWithComma)1588 TEST_P(AidlTest, FailOnEmptyListWithComma) {
1589   AidlError error;
1590   const string expected_stderr =
1591       "ERROR: p/Foo.aidl:1.45-47: syntax error, unexpected ',', expecting '}'\n";
1592   CaptureStderr();
1593   EXPECT_EQ(nullptr, Parse("p/Foo.aidl", R"(package p; parcelable Foo { uint64_t[] a = { , }; })",
1594                            typenames_, GetLanguage(), &error));
1595   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1596   EXPECT_EQ(AidlError::PARSE_ERROR, error);
1597 }
1598 
TEST_P(AidlTest,FailOnMalformedConstHexValue)1599 TEST_P(AidlTest, FailOnMalformedConstHexValue) {
1600   AidlError error;
1601   const string expected_stderr =
1602       "ERROR: p/IFoo.aidl:3.50-71: Could not parse hexvalue: 0xffffffffffffffffff\n";
1603   CaptureStderr();
1604   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
1605                            R"(package p;
1606                       interface IFoo {
1607                         const int BAD_HEX_VALUE = 0xffffffffffffffffff;
1608                       }
1609                    )",
1610                            typenames_, GetLanguage(), &error));
1611   EXPECT_EQ(expected_stderr, GetCapturedStderr());
1612   EXPECT_EQ(AidlError::PARSE_ERROR, error);
1613 }
1614 
TEST_P(AidlTest,FailOnMalformedQualifiedNameAsIdentifier)1615 TEST_P(AidlTest, FailOnMalformedQualifiedNameAsIdentifier) {
1616   AidlError error;
1617   const string expected_stderr =
1618       "ERROR: p/IFoo.aidl:1.25-26: syntax error, unexpected ';', expecting identifier";
1619   CaptureStderr();
1620   // Notice the trailing dot(.) in the name, which isn't a correct name
1621   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p; parcelable A.; )", typenames_,
1622                            GetLanguage(), &error));
1623   EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_stderr));
1624   EXPECT_EQ(AidlError::PARSE_ERROR, error);
1625 }
1626 
TEST_P(AidlTest,FailOnAssigningByteSizeIntToByteWithHelp)1627 TEST_P(AidlTest, FailOnAssigningByteSizeIntToByteWithHelp) {
1628   EvaluateInvalidAssignment(
1629       R"(package a; interface IFoo { const byte INT_VALUE = 0xFF; })",
1630       "Invalid type specifier for an int32 literal: byte (0xFF). Did you mean: 0xFFu8?", typenames_,
1631       GetLanguage());
1632 }
1633 
TEST_P(AidlTest,FailOnAssigningDoubleInFloatConst)1634 TEST_P(AidlTest, FailOnAssigningDoubleInFloatConst) {
1635   EvaluateInvalidAssignment(R"(package a; interface IFoo { const float DOUBLE_VALUE = 1.1; })",
1636                             INVALID_FLOAT_VALUE, typenames_, GetLanguage());
1637 }
1638 
TEST_P(AidlTest,FailOnAssigningFloatInDoubleConst)1639 TEST_P(AidlTest, FailOnAssigningFloatInDoubleConst) {
1640   EvaluateValidAssignment(R"(package a; interface IFoo { const double FLOAT_VALUE = 1.1f; })", "",
1641                           typenames_, GetLanguage());
1642 }
1643 
TEST_P(AidlTest,FailOnAssigningIntInFloatConst)1644 TEST_P(AidlTest, FailOnAssigningIntInFloatConst) {
1645   EvaluateInvalidAssignment(R"(package a; interface IFoo { const float INT_VALUE = 1; })",
1646                             INVALID_INT8_VALUE, typenames_, GetLanguage());
1647 }
1648 
TEST_P(AidlTest,FailOnAssigningFloatInIntConst)1649 TEST_P(AidlTest, FailOnAssigningFloatInIntConst) {
1650   EvaluateInvalidAssignment(R"(package a; interface IFoo { const int FLOAT_VALUE = 1.1f; })",
1651                             INVALID_FLOAT_VALUE, typenames_, GetLanguage());
1652 }
1653 
TEST_P(AidlTest,FailOnAssigningIntInDoubleConst)1654 TEST_P(AidlTest, FailOnAssigningIntInDoubleConst) {
1655   EvaluateInvalidAssignment(R"(package a; interface IFoo { const double INT_VALUE = 1; })",
1656                             INVALID_INT8_VALUE, typenames_, GetLanguage());
1657 }
1658 
TEST_P(AidlTest,FailOnAssigningDoubleInIntConst)1659 TEST_P(AidlTest, FailOnAssigningDoubleInIntConst) {
1660   EvaluateInvalidAssignment(R"(package a; interface IFoo { const int DOUBLE_VALUE = 1.1; })",
1661                             INVALID_FLOAT_VALUE, typenames_, GetLanguage());
1662 }
1663 
TEST_P(AidlTest,FailOnAssigningFloatPlusIntConst)1664 TEST_P(AidlTest, FailOnAssigningFloatPlusIntConst) {
1665   EvaluateInvalidAssignment(R"(package a; interface IFoo { const float FLOAT_VALUE = 1.1f + 1; })",
1666                             INVALID_OPERATION, typenames_, GetLanguage());
1667 }
1668 
TEST_P(AidlTest,FailOnAssigningIntPlusFloatConst)1669 TEST_P(AidlTest, FailOnAssigningIntPlusFloatConst) {
1670   EvaluateInvalidAssignment(R"(package a; interface IFoo { const float FLOAT_VALUE = 1 + 1.1f; })",
1671                             INVALID_OPERATION, typenames_, GetLanguage());
1672 }
1673 
TEST_P(AidlTest,FailOnAssigningDoublePlusIntConst)1674 TEST_P(AidlTest, FailOnAssigningDoublePlusIntConst) {
1675   EvaluateInvalidAssignment(R"(package a; interface IFoo { const double DOUBLE_VALUE = 1.1 + 1; })",
1676                             INVALID_OPERATION, typenames_, GetLanguage());
1677 }
1678 
TEST_P(AidlTest,FailOnAssigningIntPlusDoubleConst)1679 TEST_P(AidlTest, FailOnAssigningIntPlusDoubleConst) {
1680   EvaluateInvalidAssignment(R"(package a; interface IFoo { const double DOUBLE_VALUE = 1 + 1.1; })",
1681                             INVALID_OPERATION, typenames_, GetLanguage());
1682 }
1683 
TEST_P(AidlTest,FailOnAssigningTooLargeFloatConst)1684 TEST_P(AidlTest, FailOnAssigningTooLargeFloatConst) {
1685   EvaluateInvalidAssignment(R"(package a; interface IFoo { const float DOUBLE_VALUE = 1e50f; })",
1686                             INVALID_FLOAT_VALUE, typenames_, GetLanguage());
1687 }
1688 
TEST_P(AidlTest,FailOnAssigningTooLargeDoubleConst)1689 TEST_P(AidlTest, FailOnAssigningTooLargeDoubleConst) {
1690   EvaluateInvalidAssignment(R"(package a; interface IFoo { const double DOUBLE_VALUE = 1e310; })",
1691                             INVALID_FLOAT_VALUE, typenames_, GetLanguage());
1692 }
1693 
TEST_P(AidlTest,PassOnAssigningLargeFloatConst)1694 TEST_P(AidlTest, PassOnAssigningLargeFloatConst) {
1695   EvaluateValidAssignment(R"(package a; interface IFoo { const float DOUBLE_VALUE = 1e20f; })", "",
1696                           typenames_, GetLanguage());
1697 }
1698 
TEST_P(AidlTest,PassOnAssigningLargeDoubleConst)1699 TEST_P(AidlTest, PassOnAssigningLargeDoubleConst) {
1700   EvaluateValidAssignment(R"(package a; interface IFoo { const double DOUBLE_VALUE = 1e150; })", "",
1701                           typenames_, GetLanguage());
1702 }
1703 
TEST_P(AidlTest,FailOnMalformedQualifiedNameAsPackage)1704 TEST_P(AidlTest, FailOnMalformedQualifiedNameAsPackage) {
1705   AidlError error;
1706   const string expected_stderr =
1707       "ERROR: p/IFoo.aidl:1.11-12: syntax error, unexpected ';', expecting identifier";
1708   CaptureStderr();
1709   // Notice the trailing dot(.) in the package name
1710   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p.; parcelable A; )", typenames_,
1711                            GetLanguage(), &error));
1712   EXPECT_THAT(GetCapturedStderr(), HasSubstr(expected_stderr));
1713   EXPECT_EQ(AidlError::PARSE_ERROR, error);
1714 }
1715 
TEST_P(AidlTest,ParsePositiveConstHexValue)1716 TEST_P(AidlTest, ParsePositiveConstHexValue) {
1717   AidlError error;
1718   auto parse_result = Parse("p/IFoo.aidl",
1719                             R"(package p;
1720               interface IFoo {
1721                 const int POSITIVE_HEX_VALUE = 0xf5;
1722               }
1723            )",
1724                             typenames_, GetLanguage(), &error);
1725   EXPECT_NE(nullptr, parse_result);
1726   const AidlInterface* interface = parse_result->AsInterface();
1727   ASSERT_NE(nullptr, interface);
1728   const auto& cpp_constants = interface->GetConstantDeclarations();
1729   EXPECT_EQ((size_t)1, cpp_constants.size());
1730   EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_constants[0]->GetName());
1731   EXPECT_TRUE(cpp_constants[0]->CheckValid(typenames_));
1732   EXPECT_EQ("245", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
1733 }
1734 
TEST_P(AidlTest,ParseNegativeConstHexValue)1735 TEST_P(AidlTest, ParseNegativeConstHexValue) {
1736   AidlError error;
1737   auto parse_result = Parse("p/IFoo.aidl",
1738                             R"(package p;
1739               interface IFoo {
1740                 const int NEGATIVE_HEX_VALUE = 0xffffffff;
1741               }
1742            )",
1743                             typenames_, GetLanguage(), &error);
1744   ASSERT_NE(nullptr, parse_result);
1745   const AidlInterface* interface = parse_result->AsInterface();
1746   ASSERT_NE(nullptr, interface);
1747   const auto& cpp_constants = interface->GetConstantDeclarations();
1748   EXPECT_EQ((size_t)1, cpp_constants.size());
1749   EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_constants[0]->GetName());
1750   EXPECT_EQ(true, cpp_constants[0]->CheckValid(typenames_));
1751   EXPECT_EQ("-1", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
1752 }
1753 
TEST_F(AidlTest,ByteAndByteArrayDifferInCpp)1754 TEST_F(AidlTest, ByteAndByteArrayDifferInCpp) {
1755   auto type = Parse("p/Foo.aidl",
1756                     R"(
1757                       package p;
1758                       parcelable Foo {
1759                         byte a = -1;
1760                         byte[] b = {-1, 1};
1761                         @nullable byte[] c = {-1, 1};
1762                       }
1763                     )",
1764                     typenames_, Options::Language::CPP);
1765   ASSERT_NE(nullptr, type);
1766   auto& fields = type->GetFields();
1767   ASSERT_EQ(3ul, fields.size());
1768   EXPECT_EQ("-1", fields[0]->ValueString(cpp::ConstantValueDecorator));
1769   EXPECT_EQ("{uint8_t(-1), 1}", fields[1]->ValueString(cpp::ConstantValueDecorator));
1770   EXPECT_EQ("{{uint8_t(-1), 1}}", fields[2]->ValueString(cpp::ConstantValueDecorator));
1771 }
1772 
TEST_F(AidlTest,ByteAndByteArrayDifferInNdk)1773 TEST_F(AidlTest, ByteAndByteArrayDifferInNdk) {
1774   auto type = Parse("p/Foo.aidl",
1775                     R"(
1776                       package p;
1777                       parcelable Foo {
1778                         byte a = -1;
1779                         byte[] b = {-1, 1};
1780                         @nullable byte[] c = {-1, 1};
1781                       }
1782                     )",
1783                     typenames_, Options::Language::NDK);
1784   ASSERT_NE(nullptr, type);
1785   auto& fields = type->GetFields();
1786   ASSERT_EQ(3ul, fields.size());
1787   EXPECT_EQ("-1", fields[0]->ValueString(ndk::ConstantValueDecorator));
1788   EXPECT_EQ("{uint8_t(-1), 1}", fields[1]->ValueString(ndk::ConstantValueDecorator));
1789   EXPECT_EQ("{{uint8_t(-1), 1}}", fields[2]->ValueString(ndk::ConstantValueDecorator));
1790 }
1791 
TEST_P(AidlTest,UnderstandsNestedUnstructuredParcelables)1792 TEST_P(AidlTest, UnderstandsNestedUnstructuredParcelables) {
1793   io_delegate_.SetFileContents("p/Outer.aidl",
1794                                "package p; parcelable Outer.Inner cpp_header \"baz/header\" "
1795                                "ndk_header \"ndk/baz/header\" rust_type \"baz::Inner\";");
1796   import_paths_.emplace("");
1797   const string input_path = "p/IFoo.aidl";
1798   const string input = "package p; import p.Outer; interface IFoo"
1799                        " { Outer.Inner get(); }";
1800 
1801   auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1802   EXPECT_NE(nullptr, parse_result);
1803 
1804   EXPECT_TRUE(typenames_.ResolveTypename("p.Outer.Inner").is_resolved);
1805   // C++ uses "::" instead of "." to refer to a inner class.
1806   AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.Outer.Inner", /*array=*/std::nullopt,
1807                                 nullptr, {});
1808   EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
1809 }
1810 
TEST_P(AidlTest,UnderstandsNestedUnstructuredParcelablesWithoutImports)1811 TEST_P(AidlTest, UnderstandsNestedUnstructuredParcelablesWithoutImports) {
1812   io_delegate_.SetFileContents("p/Outer.aidl",
1813                                "package p; parcelable Outer.Inner cpp_header \"baz/header\" "
1814                                "ndk_header \"ndk/baz/header\" rust_type \"baz::Inner\";");
1815   import_paths_.emplace("");
1816   const string input_path = "p/IFoo.aidl";
1817   const string input = "package p; interface IFoo { p.Outer.Inner get(); }";
1818 
1819   auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1820   EXPECT_NE(nullptr, parse_result);
1821 
1822   EXPECT_TRUE(typenames_.ResolveTypename("p.Outer.Inner").is_resolved);
1823   // C++ uses "::" instead of "." to refer to a inner class.
1824   AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.Outer.Inner", /*array=*/std::nullopt,
1825                                 nullptr, {});
1826   EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
1827 }
1828 
TEST_F(AidlTest,UnderstandsNestedTypes)1829 TEST_F(AidlTest, UnderstandsNestedTypes) {
1830   io_delegate_.SetFileContents("p/IOuter.aidl",
1831                                "package p;\n"
1832                                "interface IOuter {\n"
1833                                "  parcelable Inner {}\n"
1834                                "}");
1835   import_paths_.emplace("");
1836   const string input_path = "p/IFoo.aidl";
1837   const string input =
1838       "package p;\n"
1839       "import p.IOuter;\n"
1840       "interface IFoo {\n"
1841       "  IOuter.Inner get();\n"
1842       "}";
1843   CaptureStderr();
1844   EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1845   EXPECT_EQ(GetCapturedStderr(), "");
1846 
1847   EXPECT_TRUE(typenames_.ResolveTypename("p.IOuter.Inner").is_resolved);
1848   // C++ uses "::" instead of "." to refer to a inner class.
1849   AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.IOuter.Inner", /*array=*/std::nullopt,
1850                                 nullptr, {});
1851   EXPECT_EQ("::p::IOuter::Inner", cpp::CppNameOf(nested_type, typenames_));
1852 }
1853 
TEST_F(AidlTest,DefinedTypeKnowsItsParentScope)1854 TEST_F(AidlTest, DefinedTypeKnowsItsParentScope) {
1855   const string input_path = "p/IFoo.aidl";
1856   const string input =
1857       "package p;\n"
1858       "interface IFoo {\n"
1859       "  parcelable Inner {\n"
1860       "    enum Enum { A }\n"
1861       "  }\n"
1862       "}";
1863   CaptureStderr();
1864   EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1865   EXPECT_EQ(GetCapturedStderr(), "");
1866 
1867   auto enum_type = typenames_.ResolveTypename("p.IFoo.Inner.Enum");
1868   auto inner_type = typenames_.ResolveTypename("p.IFoo.Inner");
1869   auto ifoo_type = typenames_.ResolveTypename("p.IFoo");
1870   EXPECT_TRUE(enum_type.is_resolved);
1871   EXPECT_TRUE(inner_type.is_resolved);
1872   EXPECT_TRUE(ifoo_type.is_resolved);
1873   // GetParentType()
1874   EXPECT_EQ(inner_type.defined_type, enum_type.defined_type->GetParentType());
1875   EXPECT_EQ(ifoo_type.defined_type, inner_type.defined_type->GetParentType());
1876   EXPECT_EQ(nullptr, ifoo_type.defined_type->GetParentType());
1877   // GetRootType()
1878   EXPECT_EQ(ifoo_type.defined_type, enum_type.defined_type->GetRootType());
1879   EXPECT_EQ(ifoo_type.defined_type, inner_type.defined_type->GetRootType());
1880   EXPECT_EQ(ifoo_type.defined_type, ifoo_type.defined_type->GetRootType());
1881   // GetDocument()
1882   auto main_document = &typenames_.MainDocument();
1883   EXPECT_EQ(main_document, &enum_type.defined_type->GetDocument());
1884   EXPECT_EQ(main_document, &inner_type.defined_type->GetDocument());
1885   EXPECT_EQ(main_document, &ifoo_type.defined_type->GetDocument());
1886 }
1887 
TEST_F(AidlTest,UnderstandsNestedTypesViaFullyQualifiedName)1888 TEST_F(AidlTest, UnderstandsNestedTypesViaFullyQualifiedName) {
1889   io_delegate_.SetFileContents("p/IOuter.aidl",
1890                                "package p;\n"
1891                                "interface IOuter {\n"
1892                                "  parcelable Inner {}\n"
1893                                "}");
1894   import_paths_.emplace("");
1895   const string input_path = "p/IFoo.aidl";
1896   const string input =
1897       "package p;\n"
1898       "interface IFoo {\n"
1899       "  p.IOuter.Inner get();\n"
1900       "}";
1901   CaptureStderr();
1902   EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1903   EXPECT_EQ(GetCapturedStderr(), "");
1904 
1905   EXPECT_TRUE(typenames_.ResolveTypename("p.IOuter.Inner").is_resolved);
1906 }
1907 
TEST_F(AidlTest,IncludeParentsRawHeaderForNestedInterface)1908 TEST_F(AidlTest, IncludeParentsRawHeaderForNestedInterface) {
1909   CaptureStderr();
1910   EXPECT_NE(nullptr, Parse("p/Outer.aidl",
1911                            "package p;\n"
1912                            "parcelable Outer {\n"
1913                            "  interface IInner {}\n"
1914                            "}",
1915                            typenames_, Options::Language::CPP));
1916 
1917   EXPECT_EQ(GetCapturedStderr(), "");
1918   auto resolved = typenames_.ResolveTypename("p.Outer.IInner");
1919   ASSERT_TRUE(resolved.defined_type);
1920   EXPECT_EQ(cpp::HeaderFile(*resolved.defined_type, cpp::ClassNames::CLIENT), "p/Outer.h");
1921 }
1922 
TEST_F(AidlTest,UnderstandsNestedTypesViaFullyQualifiedImport)1923 TEST_F(AidlTest, UnderstandsNestedTypesViaFullyQualifiedImport) {
1924   io_delegate_.SetFileContents("p/IOuter.aidl",
1925                                "package p;\n"
1926                                "interface IOuter {\n"
1927                                "  parcelable Inner {}\n"
1928                                "}");
1929   import_paths_.emplace("");
1930   const string input_path = "p/IFoo.aidl";
1931   const string input =
1932       "package p;\n"
1933       "import p.IOuter.Inner;"
1934       "interface IFoo {\n"
1935       "  Inner get();\n"
1936       "}";
1937   CaptureStderr();
1938   EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1939   EXPECT_EQ(GetCapturedStderr(), "");
1940 
1941   EXPECT_TRUE(typenames_.ResolveTypename("p.IOuter.Inner").is_resolved);
1942 }
1943 
TEST_F(AidlTest,UnderstandsNestedTypesInTheSameScope)1944 TEST_F(AidlTest, UnderstandsNestedTypesInTheSameScope) {
1945   const string input_path = "p/IFoo.aidl";
1946   const string input =
1947       "package p;\n"
1948       "interface IFoo {\n"
1949       "  parcelable Result {}\n"
1950       "  Result get();\n"
1951       "}";
1952   CaptureStderr();
1953   EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1954   EXPECT_EQ(GetCapturedStderr(), "");
1955 
1956   EXPECT_TRUE(typenames_.ResolveTypename("p.IFoo.Result").is_resolved);
1957 }
1958 
1959 // Finding the type of nested named member.
1960 struct TypeFinder : AidlVisitor {
1961   string name;
1962   const AidlTypeSpecifier* type = nullptr;
TypeFinderandroid::aidl::TypeFinder1963   TypeFinder(std::string name) : name(name) {}
Visitandroid::aidl::TypeFinder1964   void Visit(const AidlVariableDeclaration& v) override {
1965     if (v.GetName() == name) {
1966       type = &v.GetType();
1967     }
1968   }
Visitandroid::aidl::TypeFinder1969   void Visit(const AidlMethod& m) override {
1970     if (m.GetName() == name) {
1971       type = &m.GetType();
1972     }
1973   }
Getandroid::aidl::TypeFinder1974   static string Get(const AidlDefinedType& type, const string& name) {
1975     TypeFinder v(name);
1976     VisitTopDown(v, type);
1977     return v.type ? v.type->Signature() : "(null)";
1978   };
1979 };
1980 
TEST_F(AidlTest,UnderstandsNestedTypesViaQualifiedInTheSameScope)1981 TEST_F(AidlTest, UnderstandsNestedTypesViaQualifiedInTheSameScope) {
1982   io_delegate_.SetFileContents("q/IBar.aidl",
1983                                "package q;\n"
1984                                "interface IBar {\n"
1985                                "  parcelable Baz {}\n"
1986                                "}");
1987   import_paths_.emplace("");
1988   const string input_path = "p/IFoo.aidl";
1989   const string input =
1990       "package p;\n"
1991       "import q.IBar;\n"
1992       "interface IFoo {\n"
1993       "  parcelable Nested {\n"
1994       "    Baz t1;\n"
1995       "  }\n"
1996       "  parcelable Baz { }\n"
1997       "  IBar.Baz t2();\n"
1998       "  Baz t3();\n"
1999       "}";
2000   CaptureStderr();
2001   auto foo = Parse(input_path, input, typenames_, Options::Language::CPP);
2002   EXPECT_EQ(GetCapturedStderr(), "");
2003   ASSERT_NE(nullptr, foo);
2004 
2005   EXPECT_EQ(TypeFinder::Get(*foo, "t1"), "p.IFoo.Baz");
2006   EXPECT_EQ(TypeFinder::Get(*foo, "t2"), "q.IBar.Baz");
2007   EXPECT_EQ(TypeFinder::Get(*foo, "t3"), "p.IFoo.Baz");
2008 }
2009 
TEST_F(AidlTest,NestedTypeResolutionWithNoPackage)2010 TEST_F(AidlTest, NestedTypeResolutionWithNoPackage) {
2011   const string input_path = "Foo.aidl";
2012   const string input =
2013       "parcelable Foo {\n"
2014       "  parcelable Bar {\n"
2015       "    enum Baz { BAZ }\n"
2016       "    Baz baz = Baz.BAZ;\n"
2017       "  }\n"
2018       "  Bar bar;\n"
2019       "}";
2020   CaptureStderr();
2021   auto foo = Parse(input_path, input, typenames_, Options::Language::CPP);
2022   EXPECT_EQ(GetCapturedStderr(), "");
2023   ASSERT_NE(nullptr, foo);
2024 
2025   EXPECT_EQ(TypeFinder::Get(*foo, "bar"), "Foo.Bar");
2026   EXPECT_EQ(TypeFinder::Get(*foo, "baz"), "Foo.Bar.Baz");
2027 }
2028 
TEST_F(AidlTest,RejectsNestedTypesWithParentsName)2029 TEST_F(AidlTest, RejectsNestedTypesWithParentsName) {
2030   const string input_path = "p/Foo.aidl";
2031   const string input =
2032       "package p;\n"
2033       "parcelable Foo {\n"
2034       "  parcelable Foo {}\n"
2035       "}";
2036   CaptureStderr();
2037   EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
2038   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Nested type 'Foo' has the same name as its parent."));
2039 }
2040 
TEST_F(AidlTest,RejectUnstructuredParcelableAsNestedTypes)2041 TEST_F(AidlTest, RejectUnstructuredParcelableAsNestedTypes) {
2042   const string input_path = "p/IFoo.aidl";
2043   const string input =
2044       "package p;\n"
2045       "interface IFoo {\n"
2046       "  parcelable Bar cpp_header \"Bar.h\";\n"
2047       "}";
2048   CaptureStderr();
2049   EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
2050   EXPECT_THAT(GetCapturedStderr(),
2051               HasSubstr("Unstructured parcelables should be at the root scope"));
2052 }
2053 
TEST_F(AidlTest,RejectGenericTypeWithNestedTypes)2054 TEST_F(AidlTest, RejectGenericTypeWithNestedTypes) {
2055   const string input_path = "p/Foo.aidl";
2056   const string input =
2057       "package p;\n"
2058       "parcelable Foo<T> {\n"
2059       "  parcelable Bar {}\n"
2060       "}";
2061   CaptureStderr();
2062   EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
2063   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Generic types can't have nested types."));
2064 }
2065 
TEST_F(AidlTest,HandleSyntaxErrorsInNestedDecl)2066 TEST_F(AidlTest, HandleSyntaxErrorsInNestedDecl) {
2067   const string input_path = "p/IFoo.aidl";
2068   const string input =
2069       "package p;\n"
2070       "interface IFoo {\n"
2071       "  parcelable;\n"  // missing identifier
2072       "}";
2073   CaptureStderr();
2074   EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
2075   EXPECT_THAT(GetCapturedStderr(), HasSubstr("expecting identifier"));
2076 }
2077 
TEST_F(AidlTest,RejectsNestedTypesWithDuplicateNames)2078 TEST_F(AidlTest, RejectsNestedTypesWithDuplicateNames) {
2079   const string input_path = "p/Foo.aidl";
2080   const string input =
2081       "package p;\n"
2082       "interface Foo {\n"
2083       "  parcelable Bar {}\n"
2084       "  parcelable Bar {}\n"
2085       "}";
2086   CaptureStderr();
2087   EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
2088   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Redefinition of 'Bar'"));
2089 }
2090 
TEST_F(AidlTest,TypeResolutionWithMultipleLevelsOfNesting)2091 TEST_F(AidlTest, TypeResolutionWithMultipleLevelsOfNesting) {
2092   struct Failure {
2093     string err;
2094   };
2095   struct TestCase {
2096     string type;
2097     variant<string, Failure> expected;  // success<0> or failure<1>
2098   };
2099   vector<TestCase> cases = {
2100       {"foo.A", "foo.A"},
2101       {"foo.A.B", "foo.A.B"},
2102       {"@nullable(heap=true) A", "foo.A.B.A"},
2103       // In the scope of foo.A.B.A, B is resolved to A.B.A.B first.
2104       {"B.A", Failure{"Failed to resolve 'B.A'"}},
2105       {"B", "foo.A.B.A.B"},
2106       {"A.B", "foo.A.B.A.B"},
2107   };
2108   const string input_path = "foo/A.aidl";
2109   for (auto& [type, expected] : cases) {
2110     AidlTypenames typenames;
2111     // clang-format off
2112     const string input =
2113         "package foo;\n"
2114         "parcelable A {\n"
2115         "  parcelable B {\n"
2116         "    parcelable A {\n"
2117         "      parcelable B {\n"
2118         "      }\n"
2119         "      " + type + " m;\n"
2120         "    }\n"
2121         "  }\n"
2122         "}";
2123     // clang-format on
2124     CaptureStderr();
2125     auto foo = Parse(input_path, input, typenames, Options::Language::CPP);
2126     if (auto failure = std::get_if<Failure>(&expected); failure) {
2127       ASSERT_EQ(nullptr, foo);
2128       EXPECT_THAT(GetCapturedStderr(), HasSubstr(failure->err));
2129     } else {
2130       EXPECT_EQ(GetCapturedStderr(), "");
2131       ASSERT_NE(nullptr, foo);
2132       EXPECT_EQ(TypeFinder::Get(*foo, "m"), std::get<string>(expected));
2133     }
2134   }
2135 }
2136 
TEST_F(AidlTest,HeaderForNestedTypeShouldPointToTopMostParent)2137 TEST_F(AidlTest, HeaderForNestedTypeShouldPointToTopMostParent) {
2138   const string input_path = "p/IFoo.aidl";
2139   const string input =
2140       "package p;\n"
2141       "interface IFoo {\n"
2142       "  parcelable Result {}\n"
2143       "}";
2144   CaptureStderr();
2145   auto foo = Parse(input_path, input, typenames_, Options::Language::CPP);
2146   ASSERT_NE(nullptr, foo);
2147   EXPECT_EQ(GetCapturedStderr(), "");
2148 
2149   auto result = typenames_.ResolveTypename("p.IFoo.Result").defined_type;
2150   ASSERT_NE(nullptr, result);
2151   EXPECT_EQ("p/IFoo.h", cpp::CppHeaderForType(*result));
2152 }
2153 
TEST_F(AidlTest,ReorderNestedTypesForCppOutput)2154 TEST_F(AidlTest, ReorderNestedTypesForCppOutput) {
2155   const string input_path = "p/IFoo.aidl";
2156   const string input = R"(
2157     package p;
2158     interface IFoo {
2159       // partial orderings for [A, D, G]:
2160       //   D - A
2161       //   A - G
2162       parcelable A {
2163         // partial orderings for [B, C]:
2164         //   C - B
2165         parcelable B {
2166           C c;
2167           D.E d;
2168         }
2169         parcelable C {}
2170       }
2171       parcelable D {
2172         // partial orderings for [E, F]:
2173         //   F - E
2174         parcelable E {
2175           F f;
2176         }
2177         parcelable F {}
2178       }
2179       parcelable G {
2180         A.B b;
2181       }
2182     }
2183   )";
2184   Options options = Options::From("aidl --lang cpp -I. -oout -hout p/IFoo.aidl");
2185   io_delegate_.SetFileContents(input_path, input);
2186   CaptureStderr();
2187   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2188   EXPECT_EQ(GetCapturedStderr(), "");
2189 
2190   string code;
2191   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/IFoo.h", &code));
2192   // check partial orderings: a should comes before b
2193   EXPECT_LE(code.find("class D"), code.find("class A"));
2194   EXPECT_LE(code.find("class A"), code.find("class G"));
2195   EXPECT_LE(code.find("class C"), code.find("class B"));
2196   EXPECT_LE(code.find("class F"), code.find("class E"));
2197 }
2198 
TEST_F(AidlTest,RejectsNestedTypesWithCyclicDeps)2199 TEST_F(AidlTest, RejectsNestedTypesWithCyclicDeps) {
2200   const string input_path = "p/IFoo.aidl";
2201   const string input = R"(
2202     package p;
2203     interface IFoo {
2204       // Cycles:
2205       //   D - A
2206       //   A - G
2207       //   G - D
2208       parcelable A {
2209         parcelable B {
2210           C c;
2211         }
2212       }
2213       parcelable C {
2214         parcelable D {
2215           E e;
2216         }
2217       }
2218       parcelable E {
2219         parcelable F {
2220           A a;
2221         }
2222       }
2223     }
2224   )";
2225   Options options = Options::From("aidl --lang cpp -I. -oout -hout p/IFoo.aidl");
2226   io_delegate_.SetFileContents(input_path, input);
2227   CaptureStderr();
2228   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2229   EXPECT_THAT(GetCapturedStderr(), HasSubstr("IFoo has nested types with cyclic references."));
2230 }
2231 
TEST_F(AidlTest,RejectsCyclicNestedInterfaces)2232 TEST_F(AidlTest, RejectsCyclicNestedInterfaces) {
2233   Options options = Options::From(
2234       "aidl --lang cpp -I. -oout -hout "
2235       "p/IFoo.aidl p/IBar.aidl p/IQux.aidl");
2236   io_delegate_.SetFileContents("p/IFoo.aidl",
2237                                "package p; import p.IBar; "
2238                                "interface IFoo { IBar getBar(); }");
2239   io_delegate_.SetFileContents("p/IBar.aidl",
2240                                "package p; import p.IQux; "
2241                                "interface IBar { IQux.Inner getQux(); }");
2242   io_delegate_.SetFileContents("p/IQux.aidl",
2243                                "package p; import p.IFoo; "
2244                                "interface IQux { interface Inner { IFoo getFoo(); } }");
2245   CaptureStderr();
2246   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2247   EXPECT_THAT(GetCapturedStderr(),
2248               HasSubstr("ERROR: p/IQux.aidl:1.43-53: has cyclic references to nested types."));
2249 }
2250 
TEST_F(AidlTest,RejectsCyclicNestedInterfacesAndParcelables)2251 TEST_F(AidlTest, RejectsCyclicNestedInterfacesAndParcelables) {
2252   Options options = Options::From(
2253       "aidl --lang cpp -I. -oout -hout "
2254       "p/IFoo.aidl p/Bar.aidl");
2255   io_delegate_.SetFileContents("p/IFoo.aidl",
2256                                "package p; import p.Bar; "
2257                                "interface IFoo { interface Inner { Bar getBar(); } }");
2258   io_delegate_.SetFileContents("p/Bar.aidl",
2259                                "package p; import p.IFoo; "
2260                                "parcelable Bar { IFoo.Inner foo; }");
2261   CaptureStderr();
2262   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2263   EXPECT_THAT(GetCapturedStderr(),
2264               HasSubstr("ERROR: p/IFoo.aidl:1.42-52: has cyclic references to nested types."));
2265 }
2266 
TEST_F(AidlTest,CppNameOf_GenericType)2267 TEST_F(AidlTest, CppNameOf_GenericType) {
2268   const string input_path = "p/Wrapper.aidl";
2269   const string input = "package p; parcelable Wrapper<T> {}";
2270 
2271   auto parse_result = Parse(input_path, input, typenames_, Options::Language::CPP);
2272   EXPECT_NE(nullptr, parse_result);
2273 
2274   auto type = [](std::string name, auto&&... type_params) -> std::unique_ptr<AidlTypeSpecifier> {
2275     auto params = new std::vector<std::unique_ptr<AidlTypeSpecifier>>;
2276     (..., params->emplace_back(std::move(type_params)));
2277     return std::make_unique<AidlTypeSpecifier>(AIDL_LOCATION_HERE, name, std::nullopt, params,
2278                                                Comments{});
2279   };
2280 
2281   auto set_nullable = [](std::unique_ptr<AidlTypeSpecifier>&& type) {
2282     std::vector<std::unique_ptr<AidlAnnotation>> annotations;
2283     annotations.emplace_back(std::unique_ptr<AidlAnnotation>(
2284         AidlAnnotation::Parse(AIDL_LOCATION_HERE, "nullable", {}, {})));
2285     type->Annotate(std::move(annotations));
2286     return std::move(type);
2287   };
2288 
2289   auto set_array = [](std::unique_ptr<AidlTypeSpecifier>&& type) {
2290     (void)type->MakeArray(DynamicArray{});
2291     return std::move(type);
2292   };
2293 
2294   auto w = type("p.Wrapper", type("String"));
2295   EXPECT_EQ("::p::Wrapper<::android::String16>", cpp::CppNameOf(*w, typenames_));
2296 
2297   auto nullable_w = set_nullable(type("p.Wrapper", type("String")));
2298   EXPECT_EQ("::std::optional<::p::Wrapper<::android::String16>>",
2299             cpp::CppNameOf(*nullable_w, typenames_));
2300 
2301   auto array_w = set_array(type("p.Wrapper", type("String")));
2302   EXPECT_EQ("::std::vector<::p::Wrapper<::android::String16>>",
2303             cpp::CppNameOf(*array_w, typenames_));
2304 
2305   auto nullable_array_w = set_nullable(set_array(type("p.Wrapper", type("String"))));
2306   EXPECT_EQ("::std::optional<::std::vector<::std::optional<::p::Wrapper<::android::String16>>>>",
2307             cpp::CppNameOf(*nullable_array_w, typenames_));
2308 
2309   auto list_w = type("List", type("p.Wrapper", type("String")));
2310   EXPECT_EQ("::std::vector<::p::Wrapper<::android::String16>>",
2311             cpp::CppNameOf(*list_w, typenames_));
2312 
2313   auto nullable_list_w = set_nullable(type("List", type("p.Wrapper", type("String"))));
2314   EXPECT_EQ("::std::optional<::std::vector<::std::optional<::p::Wrapper<::android::String16>>>>",
2315             cpp::CppNameOf(*nullable_list_w, typenames_));
2316 }
2317 
TEST_P(AidlTest,UnderstandsNativeParcelables)2318 TEST_P(AidlTest, UnderstandsNativeParcelables) {
2319   io_delegate_.SetFileContents(
2320       "p/Bar.aidl",
2321       "package p; parcelable Bar cpp_header \"baz/header\";");
2322   import_paths_.emplace("");
2323   const string input_path = "p/IFoo.aidl";
2324   const string input = "package p; import p.Bar; interface IFoo { }";
2325   auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
2326   EXPECT_NE(nullptr, parse_result);
2327   EXPECT_TRUE(typenames_.ResolveTypename("p.Bar").is_resolved);
2328   AidlTypeSpecifier native_type(AIDL_LOCATION_HERE, "p.Bar", /*array=*/std::nullopt, nullptr, {});
2329   native_type.Resolve(typenames_, parse_result);
2330 
2331   EXPECT_EQ("p.Bar", java::InstantiableJavaSignatureOf(native_type));
2332   // C++ understands C++ specific stuff
2333   EXPECT_EQ("::p::Bar", cpp::CppNameOf(native_type, typenames_));
2334   set<string> headers;
2335   cpp::AddHeaders(native_type, typenames_, &headers);
2336   EXPECT_EQ(1u, headers.size());
2337   EXPECT_EQ(1u, headers.count("baz/header"));
2338 }
2339 
TEST_F(AidlTest,WritesCorrectDependencyFile)2340 TEST_F(AidlTest, WritesCorrectDependencyFile) {
2341   // While the in tree build system always gives us an output file name,
2342   // other android tools take advantage of our ability to infer the intended
2343   // file name.  This test makes sure we handle this correctly.
2344   vector<string> args = {"aidl", "-I .", "-d dep/file/path", "-o place/for/output", "p/IFoo.aidl"};
2345   Options options = Options::From(args);
2346   io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
2347   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2348   string actual_dep_file_contents;
2349   EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
2350   EXPECT_EQ(actual_dep_file_contents, kExpectedDepFileContents);
2351 }
2352 
TEST_F(AidlTest,WritesCorrectDependencyFileNinja)2353 TEST_F(AidlTest, WritesCorrectDependencyFileNinja) {
2354   // While the in tree build system always gives us an output file name,
2355   // other android tools take advantage of our ability to infer the intended
2356   // file name.  This test makes sure we handle this correctly.
2357   vector<string> args = {"aidl",       "-I .", "-d dep/file/path", "--ninja", "-o place/for/output",
2358                          "p/IFoo.aidl"};
2359   Options options = Options::From(args);
2360   io_delegate_.SetFileContents(options.InputFiles().front(), "package p; interface IFoo {}");
2361   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2362   string actual_dep_file_contents;
2363   EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
2364   EXPECT_EQ(actual_dep_file_contents, kExpectedNinjaDepFileContents);
2365 }
2366 
TEST_F(AidlTest,WritesTrivialDependencyFileForParcelableDeclaration)2367 TEST_F(AidlTest, WritesTrivialDependencyFileForParcelableDeclaration) {
2368   // The SDK uses aidl to decide whether a .aidl file is a parcelable.  It does
2369   // this by calling aidl with every .aidl file it finds, then parsing the
2370   // generated dependency files.  Those that reference .java output files are
2371   // for interfaces and those that do not are parcelables.  However, for both
2372   // parcelables and interfaces, we *must* generate a non-empty dependency file.
2373   vector<string> args = {"aidl", "-I .", "-o place/for/output", "-d dep/file/path", "p/Foo.aidl"};
2374   Options options = Options::From(args);
2375   io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
2376   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2377   string actual_dep_file_contents;
2378   EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
2379   EXPECT_EQ(actual_dep_file_contents, kExpectedParcelableDeclarationDepFileContents);
2380 }
2381 
TEST_F(AidlTest,WritesDependencyFileForStructuredParcelable)2382 TEST_F(AidlTest, WritesDependencyFileForStructuredParcelable) {
2383   vector<string> args = {
2384       "aidl", "-I .", "--structured", "-o place/for/output", "-d dep/file/path", "p/Foo.aidl"};
2385   Options options = Options::From(args);
2386   io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo {int a;}");
2387   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2388   string actual_dep_file_contents;
2389   EXPECT_TRUE(io_delegate_.GetWrittenContents(options.DependencyFile(), &actual_dep_file_contents));
2390   EXPECT_EQ(actual_dep_file_contents, kExpectedStructuredParcelableDepFileContents);
2391 }
2392 
TEST_F(AidlTest,NoJavaOutputForParcelableDeclaration)2393 TEST_F(AidlTest, NoJavaOutputForParcelableDeclaration) {
2394   vector<string> args = {"aidl", "-I .", "--lang=java", "-o place/for/output", "p/Foo.aidl"};
2395   Options options = Options::From(args);
2396   io_delegate_.SetFileContents(options.InputFiles().front(), "package p; parcelable Foo;");
2397   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2398   string output_file_contents;
2399   EXPECT_FALSE(io_delegate_.GetWrittenContents(options.OutputFile(), &output_file_contents));
2400 }
2401 
TEST_P(AidlTest,RejectsListArray)2402 TEST_P(AidlTest, RejectsListArray) {
2403   const string input = "package a; parcelable Foo { List<String>[] lists; }";
2404   CaptureStderr();
2405   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", input, typenames_, GetLanguage()));
2406   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Arrays of List are not supported"));
2407 }
2408 
TEST_P(AidlTest,RejectsPrimitiveListInStableAidl)2409 TEST_P(AidlTest, RejectsPrimitiveListInStableAidl) {
2410   AidlError error;
2411   string expected_stderr =
2412       "ERROR: a/IFoo.aidl:2.7-11: "
2413       "Encountered an untyped List or Map. The use of untyped List/Map is "
2414       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
2415       "the receiving side. Consider switching to an array or a generic List/Map.\n";
2416   if (GetLanguage() != Options::Language::JAVA) {
2417     expected_stderr =
2418         "ERROR: a/IFoo.aidl:2.1-7: "
2419         "Currently, only the Java backend supports non-generic List.\n";
2420   }
2421 
2422   const string primitive_interface =
2423       "package a; interface IFoo {\n"
2424       "  List foo(); }";
2425   CaptureStderr();
2426   AidlTypenames tn1;
2427   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", primitive_interface, tn1, GetLanguage(), &error,
2428                            {"--structured"}));
2429   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2430 
2431   string primitive_parcelable =
2432       "package a; parcelable IFoo {\n"
2433       "  List foo;}";
2434   CaptureStderr();
2435   AidlTypenames tn2;
2436   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", primitive_parcelable, tn2, GetLanguage(), &error,
2437                            {"--structured"}));
2438   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2439 }
2440 
TEST_P(AidlTest,ExtensionTest)2441 TEST_P(AidlTest, ExtensionTest) {
2442   CaptureStderr();
2443   string extendable_parcelable =
2444       "package a; parcelable Data {\n"
2445       "  ParcelableHolder extension;\n"
2446       "  ParcelableHolder extension2;\n"
2447       "}";
2448   EXPECT_NE(nullptr, Parse("a/Data.aidl", extendable_parcelable, typenames_, GetLanguage()));
2449   EXPECT_EQ("", GetCapturedStderr());
2450 }
2451 
TEST_P(AidlTest,ParcelableHolderAsReturnType)2452 TEST_P(AidlTest, ParcelableHolderAsReturnType) {
2453   CaptureStderr();
2454   string parcelableholder_return_interface =
2455       "package a; interface IFoo {\n"
2456       "  ParcelableHolder foo();\n"
2457       "}";
2458   EXPECT_EQ(nullptr,
2459             Parse("a/IFoo.aidl", parcelableholder_return_interface, typenames_, GetLanguage()));
2460 
2461   EXPECT_EQ("ERROR: a/IFoo.aidl:2.19-23: ParcelableHolder cannot be a return type\n",
2462             GetCapturedStderr());
2463 }
2464 
TEST_P(AidlTest,ParcelableHolderAsArgumentType)2465 TEST_P(AidlTest, ParcelableHolderAsArgumentType) {
2466   CaptureStderr();
2467   string extendable_parcelable_arg_interface =
2468       "package a; interface IFoo {\n"
2469       "  void foo(in ParcelableHolder ph);\n"
2470       "}";
2471   EXPECT_EQ(nullptr,
2472             Parse("a/IFoo.aidl", extendable_parcelable_arg_interface, typenames_, GetLanguage()));
2473 
2474   EXPECT_EQ("ERROR: a/IFoo.aidl:2.31-34: ParcelableHolder cannot be an argument type\n",
2475             GetCapturedStderr());
2476 }
2477 
TEST_P(AidlTest,RejectNullableParcelableHolderField)2478 TEST_P(AidlTest, RejectNullableParcelableHolderField) {
2479   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { @nullable ParcelableHolder ext; }");
2480   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
2481   const string expected_stderr = "ERROR: Foo.aidl:1.27-44: ParcelableHolder cannot be nullable.\n";
2482   CaptureStderr();
2483   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2484   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2485 }
2486 
TEST_P(AidlTest,ParcelablesWithConstants)2487 TEST_P(AidlTest, ParcelablesWithConstants) {
2488   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { const int BIT = 0x1 << 3; }");
2489   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
2490   CaptureStderr();
2491   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2492   EXPECT_EQ("", GetCapturedStderr());
2493 }
2494 
TEST_P(AidlTest,UnionWithConstants)2495 TEST_P(AidlTest, UnionWithConstants) {
2496   io_delegate_.SetFileContents("Foo.aidl", "union Foo { const int BIT = 0x1 << 3; int n; }");
2497   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
2498   CaptureStderr();
2499   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2500   EXPECT_EQ("", GetCapturedStderr());
2501 }
2502 
TEST_F(AidlTest,ConstantsWithAnnotations)2503 TEST_F(AidlTest, ConstantsWithAnnotations) {
2504   io_delegate_.SetFileContents("IFoo.aidl",
2505                                "interface IFoo {\n"
2506                                " @JavaPassthrough(annotation=\"@Foo\")\n"
2507                                " const @JavaPassthrough(annotation=\"@Bar\") int FOO = 0;\n"
2508                                "}");
2509   Options options = Options::From("aidl IFoo.aidl -I . --lang=java -o out");
2510   CaptureStderr();
2511   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2512   EXPECT_EQ("", GetCapturedStderr());
2513   string code;
2514   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/IFoo.java", &code));
2515   EXPECT_THAT(code, HasSubstr("@Foo\n"));
2516   EXPECT_THAT(code, HasSubstr("@Bar\n"));
2517 }
2518 
TEST_F(AidlTest,ApiDump)2519 TEST_F(AidlTest, ApiDump) {
2520   io_delegate_.SetFileContents(
2521       "foo/bar/IFoo.aidl",
2522       "// comment\n"
2523       "package foo.bar;\n"
2524       "import foo.bar.Data;\n"
2525       "// commented /* @hide */\n"
2526       "interface IFoo {\n"
2527       "    /* @hide applied \n"
2528       "       @deprecated use foo2 */\n"
2529       "    int foo(out int[] a, String b, boolean c, inout List<String> d);\n"
2530       "    int foo2(@utf8InCpp String x, inout List<String> y);\n"
2531       "    IFoo foo3(IFoo foo);\n"
2532       "    void foo4(in int[2][3] fixedArray);\n"
2533       "    Data getData();\n"
2534       "    // @hide not applied\n"
2535       "    /** blahblah\n"
2536       "        @deprecated\n"
2537       "          reason why... */\n"
2538       "    const int A = 1;\n"
2539       "    // @deprecated tags in line comments are ignored\n"
2540       "    const String STR = \"Hello\";\n"
2541       "}\n");
2542   io_delegate_.SetFileContents("foo/bar/Data.aidl",
2543                                "// comment\n"
2544                                "package foo.bar;\n"
2545                                "import foo.bar.IFoo;\n"
2546                                "@JavaDerive(equals=true, toString=true)\n"
2547                                "/* @hide*/\n"
2548                                "parcelable Data {\n"
2549                                "   // @hide\n"
2550                                "   int x = 10;\n"
2551                                "   // @hide\n"
2552                                "   int y;\n"
2553                                "   /*@hide2*/\n"
2554                                "   IFoo foo;\n"
2555                                "   // Ignore @hide property in line comment\n"
2556                                "   @nullable String[] c;\n"
2557                                "}\n");
2558   io_delegate_.SetFileContents("api.aidl", "");
2559   vector<string> args = {"aidl", "--dumpapi", "--out=dump", "--include=.",
2560                          "foo/bar/IFoo.aidl", "foo/bar/Data.aidl"};
2561   Options options = Options::From(args);
2562   bool result = dump_api(options, io_delegate_);
2563   ASSERT_TRUE(result);
2564   string actual;
2565   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
2566   EXPECT_EQ(string("// comment\n").append(string(kPreamble)).append(R"(package foo.bar;
2567 interface IFoo {
2568   /**
2569    * @hide
2570    * @deprecated use foo2
2571    */
2572   int foo(out int[] a, String b, boolean c, inout List<String> d);
2573   int foo2(@utf8InCpp String x, inout List<String> y);
2574   foo.bar.IFoo foo3(foo.bar.IFoo foo);
2575   void foo4(in int[2][3] fixedArray);
2576   foo.bar.Data getData();
2577   /**
2578    * @deprecated reason why...
2579    */
2580   const int A = 1;
2581   const String STR = "Hello";
2582 }
2583 )"),
2584             actual);
2585 
2586   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Data.aidl", &actual));
2587   EXPECT_EQ(string("// comment\n").append(string(kPreamble)).append(R"(package foo.bar;
2588 /* @hide */
2589 @JavaDerive(equals=true, toString=true)
2590 parcelable Data {
2591   int x = 10;
2592   int y;
2593   foo.bar.IFoo foo;
2594   @nullable String[] c;
2595 }
2596 )"),
2597             actual);
2598 }
2599 
TEST_F(AidlTest,ApiDumpWithManualIds)2600 TEST_F(AidlTest, ApiDumpWithManualIds) {
2601   io_delegate_.SetFileContents(
2602       "foo/bar/IFoo.aidl",
2603       "package foo.bar;\n"
2604       "interface IFoo {\n"
2605       "    int foo() = 1;\n"
2606       "    int bar() = 2;\n"
2607       "    int baz() = 10;\n"
2608       "}\n");
2609 
2610   vector<string> args = {"aidl", "-I . ", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
2611   Options options = Options::From(args);
2612   bool result = dump_api(options, io_delegate_);
2613   ASSERT_TRUE(result);
2614   string actual;
2615   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
2616   EXPECT_EQ(actual, string(kPreamble).append(R"(package foo.bar;
2617 interface IFoo {
2618   int foo() = 1;
2619   int bar() = 2;
2620   int baz() = 10;
2621 }
2622 )"));
2623 }
2624 
TEST_F(AidlTest,ApiDumpWithManualIdsOnlyOnSomeMethods)2625 TEST_F(AidlTest, ApiDumpWithManualIdsOnlyOnSomeMethods) {
2626   const string expected_stderr =
2627       "ERROR: foo/bar/IFoo.aidl:4.8-12: You must either assign id's to all methods or to none of "
2628       "them.\n";
2629   io_delegate_.SetFileContents(
2630       "foo/bar/IFoo.aidl",
2631       "package foo.bar;\n"
2632       "interface IFoo {\n"
2633       "    int foo() = 1;\n"
2634       "    int bar();\n"
2635       "    int baz() = 10;\n"
2636       "}\n");
2637 
2638   vector<string> args = {"aidl", "-I . ", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
2639   Options options = Options::From(args);
2640   CaptureStderr();
2641   EXPECT_FALSE(dump_api(options, io_delegate_));
2642   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2643 }
2644 
TEST_F(AidlTest,ApiDumpConstWithAnnotation)2645 TEST_F(AidlTest, ApiDumpConstWithAnnotation) {
2646   io_delegate_.SetFileContents("foo/bar/IFoo.aidl",
2647                                "package foo.bar;\n"
2648                                "interface IFoo {\n"
2649                                "    @utf8InCpp String foo();\n"
2650                                "    const @utf8InCpp String bar = \"bar\";\n"
2651                                "}\n");
2652 
2653   vector<string> args = {"aidl", "-I . ", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
2654   Options options = Options::From(args);
2655   CaptureStderr();
2656   EXPECT_TRUE(dump_api(options, io_delegate_));
2657   EXPECT_EQ("", GetCapturedStderr());
2658   string actual;
2659   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
2660   EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
2661 interface IFoo {
2662   @utf8InCpp String foo();
2663   const @utf8InCpp String bar = "bar";
2664 }
2665 )"),
2666             actual);
2667 }
2668 
TEST_F(AidlTest,ApiDumpWithEnums)2669 TEST_F(AidlTest, ApiDumpWithEnums) {
2670   io_delegate_.SetFileContents("foo/bar/Enum.aidl",
2671                                "package foo.bar;\n"
2672                                "enum Enum {\n"
2673                                "    FOO,\n"
2674                                "    BAR = FOO + 1,\n"
2675                                "}\n");
2676 
2677   vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Enum.aidl"};
2678   Options options = Options::From(args);
2679   CaptureStderr();
2680   EXPECT_TRUE(dump_api(options, io_delegate_));
2681   EXPECT_EQ("", GetCapturedStderr());
2682   string actual;
2683   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Enum.aidl", &actual));
2684   EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
2685                                      "enum Enum {\n"
2686                                      "  FOO,\n"
2687                                      "  BAR = (FOO + 1) /* 1 */,\n"
2688                                      "}\n"),
2689             actual);
2690 }
2691 
TEST_F(AidlTest,ApiDumpWithEnumDefaultValues)2692 TEST_F(AidlTest, ApiDumpWithEnumDefaultValues) {
2693   io_delegate_.SetFileContents("foo/bar/Enum.aidl",
2694                                "package foo.bar;\n"
2695                                "enum Enum {\n"
2696                                "    FOO,\n"
2697                                "}\n");
2698   io_delegate_.SetFileContents("foo/bar/Foo.aidl",
2699                                "package foo.bar;\n"
2700                                "import foo.bar.Enum;\n"
2701                                "parcelable Foo {\n"
2702                                "    Enum e = Enum.FOO;\n"
2703                                "    int n = Enum.FOO;\n"
2704                                "}\n");
2705 
2706   vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Foo.aidl"};
2707   Options options = Options::From(args);
2708   CaptureStderr();
2709   EXPECT_TRUE(dump_api(options, io_delegate_));
2710   EXPECT_EQ("", GetCapturedStderr());
2711   string actual;
2712   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
2713   EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
2714                                      "parcelable Foo {\n"
2715                                      "  foo.bar.Enum e = foo.bar.Enum.FOO;\n"
2716                                      "  int n = foo.bar.Enum.FOO /* 0 */;\n"
2717                                      "}\n"),
2718             actual);
2719 }
2720 
TEST_F(AidlTest,ApiDumpWithGenerics)2721 TEST_F(AidlTest, ApiDumpWithGenerics) {
2722   io_delegate_.SetFileContents("foo/bar/Foo.aidl",
2723                                "package foo.bar;\n"
2724                                "parcelable Foo<T, U> {\n"
2725                                "}\n");
2726 
2727   vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Foo.aidl"};
2728   Options options = Options::From(args);
2729   CaptureStderr();
2730   EXPECT_TRUE(dump_api(options, io_delegate_));
2731   EXPECT_EQ("", GetCapturedStderr());
2732   string actual;
2733   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
2734   EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
2735                                      "parcelable Foo<T, U> {\n"
2736                                      "}\n"),
2737             actual);
2738 }
2739 
TEST_F(AidlTest,ImportedDocumentHasDuplicateDefinitions)2740 TEST_F(AidlTest, ImportedDocumentHasDuplicateDefinitions) {
2741   io_delegate_.SetFileContents("IFoo.aidl", "interface IFoo; interface IFoo;\n");
2742   io_delegate_.SetFileContents("Bar.aidl", "enum Bar { CONST = IFoo.NONE }\n");
2743 
2744   vector<string> args = {"aidl", "--dumpapi", "-I.", "-o out", "Bar.aidl"};
2745   Options options = Options::From(args);
2746   CaptureStderr();
2747   EXPECT_FALSE(dump_api(options, io_delegate_));
2748   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Can't find NONE in IFoo"));
2749 }
2750 
TEST_F(AidlTest,CheckNumGenericTypeSecifier)2751 TEST_F(AidlTest, CheckNumGenericTypeSecifier) {
2752   const string expected_list_stderr =
2753       "ERROR: p/IFoo.aidl:1.37-41: List can only have one type parameter, but got: "
2754       "'List<String,String>'\n";
2755   const string expected_map_stderr =
2756       "ERROR: p/IFoo.aidl:1.37-40: Map must have 0 or 2 type parameters, but got 'Map<String>'\n";
2757   Options options = Options::From("aidl -I . p/IFoo.aidl IFoo.java");
2758   io_delegate_.SetFileContents(options.InputFiles().front(),
2759                                "package p; interface IFoo {"
2760                                "void foo(List<String, String> a);}");
2761   CaptureStderr();
2762   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2763   EXPECT_EQ(expected_list_stderr, GetCapturedStderr());
2764 
2765   io_delegate_.SetFileContents(options.InputFiles().front(),
2766                                "package p; interface IFoo {"
2767                                "void foo(Map<String> a);}");
2768   CaptureStderr();
2769   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2770   EXPECT_EQ(expected_map_stderr, GetCapturedStderr());
2771 }
2772 
TEST_F(AidlTest,CheckTypeParameterInMapType)2773 TEST_F(AidlTest, CheckTypeParameterInMapType) {
2774   const string expected_stderr =
2775       "ERROR: p/IFoo.aidl:1.28-31: The type of key in map must be String, but it is 'p.Bar'\n";
2776   Options options = Options::From("aidl -I . p/IFoo.aidl");
2777   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar { String s; }");
2778 
2779   io_delegate_.SetFileContents("p/IFoo.aidl",
2780                                "package p; interface IFoo {"
2781                                "Map<String, p.Bar> foo();}");
2782   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2783 
2784   io_delegate_.SetFileContents("p/IFoo.aidl",
2785                                "package p; interface IFoo {"
2786                                "Map<p.Bar, p.Bar> foo();}");
2787   CaptureStderr();
2788   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2789   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2790 
2791   io_delegate_.SetFileContents("p/IFoo.aidl",
2792                                "package p; interface IFoo {"
2793                                "Map<String, String> foo();}");
2794   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2795 
2796   io_delegate_.SetFileContents("p/IFoo.aidl",
2797                                "package p; interface IFoo {"
2798                                "Map<String, ParcelFileDescriptor> foo();}");
2799   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2800 }
2801 
TEST_F(AidlTest,WrongGenericType)2802 TEST_F(AidlTest, WrongGenericType) {
2803   const string expected_stderr = "ERROR: p/IFoo.aidl:1.28-34: String is not a generic type.\n";
2804   Options options = Options::From("aidl -I . p/IFoo.aidl IFoo.java");
2805   io_delegate_.SetFileContents(options.InputFiles().front(),
2806                                "package p; interface IFoo {"
2807                                "String<String> foo(); }");
2808   CaptureStderr();
2809   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2810   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2811 }
2812 
TEST_F(AidlTest,UserDefinedUnstructuredGenericParcelableType)2813 TEST_F(AidlTest, UserDefinedUnstructuredGenericParcelableType) {
2814   Options optionsForParcelable = Options::From("aidl -I . p/Bar.aidl");
2815   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, T>;");
2816   CaptureStderr();
2817   EXPECT_FALSE(compile_aidl(optionsForParcelable, io_delegate_));
2818   EXPECT_EQ("ERROR: p/Bar.aidl:1.22-26: Every type parameter should be unique.\n",
2819             GetCapturedStderr());
2820 
2821   Options options = Options::From("aidl -I . p/IFoo.aidl");
2822   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar;");
2823   io_delegate_.SetFileContents("p/IFoo.aidl",
2824                                "package p; interface IFoo {"
2825                                "p.Bar<String, String> foo();}");
2826   CaptureStderr();
2827   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2828   EXPECT_THAT(GetCapturedStderr(), HasSubstr("p.Bar is not a generic type"));
2829   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T>;");
2830   CaptureStderr();
2831   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2832   EXPECT_THAT(GetCapturedStderr(), HasSubstr("p.Bar must have 1 type parameters, but got 2"));
2833   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, V>;");
2834   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2835   io_delegate_.SetFileContents("p/IFoo.aidl",
2836                                "package p; interface IFoo {"
2837                                "p.Bar<String, ParcelFileDescriptor> foo();}");
2838   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2839 
2840   io_delegate_.SetFileContents("p/IFoo.aidl",
2841                                "package p; interface IFoo {"
2842                                "p.Bar<int, long> foo();}");
2843 
2844   io_delegate_.SetFileContents("p/IFoo.aidl",
2845                                "package p; interface IFoo {"
2846                                "p.Bar<int[], long[]> foo();}");
2847 
2848   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2849 }
2850 
TEST_F(AidlTest,FailOnMultipleTypesInSingleFile)2851 TEST_F(AidlTest, FailOnMultipleTypesInSingleFile) {
2852   std::vector<std::string> rawOptions{"aidl --lang=java -I . -o out foo/bar/Foo.aidl",
2853                                       "aidl --lang=cpp -I . -o out -h out/include foo/bar/Foo.aidl",
2854                                       "aidl --lang=rust -I . -o out foo/bar/Foo.aidl"};
2855   for (const auto& rawOption : rawOptions) {
2856     string expected_stderr =
2857         "ERROR: foo/bar/Foo.aidl:3.1-10: You must declare only one type per file.\n";
2858     Options options = Options::From(rawOption);
2859     io_delegate_.SetFileContents(options.InputFiles().front(),
2860                                  "package foo.bar;\n"
2861                                  "interface IFoo1 { int foo(); }\n"
2862                                  "interface IFoo2 { int foo(); }\n"
2863                                  "parcelable Data1 { int a; int b;}\n"
2864                                  "parcelable Data2 { int a; int b;}\n");
2865     CaptureStderr();
2866     EXPECT_FALSE(compile_aidl(options, io_delegate_));
2867     EXPECT_EQ(expected_stderr, GetCapturedStderr());
2868 
2869     io_delegate_.SetFileContents(options.InputFiles().front(),
2870                                  "package foo.bar;\n"
2871                                  "interface IFoo1 { int foo(); }\n"
2872                                  "interface IFoo2 { int foo(); }\n");
2873     CaptureStderr();
2874     EXPECT_FALSE(compile_aidl(options, io_delegate_));
2875     EXPECT_EQ(expected_stderr, GetCapturedStderr());
2876 
2877     expected_stderr = "ERROR: foo/bar/Foo.aidl:3.11-17: You must declare only one type per file.\n";
2878     io_delegate_.SetFileContents(options.InputFiles().front(),
2879                                  "package foo.bar;\n"
2880                                  "parcelable Data1 { int a; int b;}\n"
2881                                  "parcelable Data2 { int a; int b;}\n");
2882     CaptureStderr();
2883     EXPECT_FALSE(compile_aidl(options, io_delegate_));
2884     EXPECT_EQ(expected_stderr, GetCapturedStderr());
2885   }
2886 }
2887 
TEST_P(AidlTest,FailParseOnEmptyFile)2888 TEST_P(AidlTest, FailParseOnEmptyFile) {
2889   const string contents = "";
2890   const string expected_stderr = "ERROR: a/IFoo.aidl:1.1-1: syntax error, unexpected $end\n";
2891   const string expected_stderr_newbison =
2892       "ERROR: a/IFoo.aidl:1.1-1: syntax error, unexpected end of file\n";
2893   CaptureStderr();
2894   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", contents, typenames_, GetLanguage()));
2895   EXPECT_THAT(GetCapturedStderr(),
2896               testing::AnyOf(testing::Eq(expected_stderr), testing::Eq(expected_stderr_newbison)));
2897 }
2898 
TEST_F(AidlTest,MultipleInputFiles)2899 TEST_F(AidlTest, MultipleInputFiles) {
2900   Options options = Options::From(
2901       "aidl --lang=java -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
2902 
2903   io_delegate_.SetFileContents(options.InputFiles().at(0),
2904       "package foo.bar;\n"
2905       "import foo.bar.Data;\n"
2906       "interface IFoo { Data getData(); }\n");
2907 
2908   io_delegate_.SetFileContents(options.InputFiles().at(1),
2909         "package foo.bar;\n"
2910         "import foo.bar.IFoo;\n"
2911         "parcelable Data { IFoo foo; }\n");
2912 
2913   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2914 
2915   string content;
2916   for (const auto file : {
2917     "out/foo/bar/IFoo.java", "out/foo/bar/Data.java"}) {
2918     content.clear();
2919     EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
2920     EXPECT_FALSE(content.empty());
2921   }
2922 }
2923 
TEST_F(AidlTest,MultipleInputFilesCpp)2924 TEST_F(AidlTest, MultipleInputFilesCpp) {
2925   Options options = Options::From(
2926       "aidl --lang=cpp -I . -o out -h out/include "
2927       "-I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
2928 
2929   io_delegate_.SetFileContents(options.InputFiles().at(0),
2930       "package foo.bar;\n"
2931       "import foo.bar.Data;\n"
2932       "interface IFoo { Data getData(); }\n");
2933 
2934   io_delegate_.SetFileContents(options.InputFiles().at(1),
2935         "package foo.bar;\n"
2936         "import foo.bar.IFoo;\n"
2937         "parcelable Data { IFoo foo; }\n");
2938 
2939   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2940 
2941   string content;
2942   for (const auto file : {
2943     "out/foo/bar/IFoo.cpp", "out/foo/bar/Data.cpp",
2944     "out/include/foo/bar/IFoo.h", "out/include/foo/bar/Data.h",
2945     "out/include/foo/bar/BpFoo.h", "out/include/foo/bar/BpData.h",
2946     "out/include/foo/bar/BnFoo.h", "out/include/foo/bar/BnData.h"}) {
2947     content.clear();
2948     EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
2949     EXPECT_FALSE(content.empty());
2950   }
2951 }
2952 
TEST_F(AidlTest,MultipleInputFilesRust)2953 TEST_F(AidlTest, MultipleInputFilesRust) {
2954   Options options =
2955       Options::From("aidl --lang=rust -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
2956 
2957   io_delegate_.SetFileContents(options.InputFiles().at(0),
2958                                "package foo.bar;\n"
2959                                "import foo.bar.Data;\n"
2960                                "interface IFoo { Data getData(); }\n");
2961 
2962   io_delegate_.SetFileContents(options.InputFiles().at(1),
2963                                "package foo.bar;\n"
2964                                "import foo.bar.IFoo;\n"
2965                                "parcelable Data { IFoo foo; }\n");
2966 
2967   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2968 
2969   string content;
2970   for (const auto file : {"out/foo/bar/IFoo.rs", "out/foo/bar/Data.rs"}) {
2971     content.clear();
2972     EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
2973     EXPECT_FALSE(content.empty());
2974   }
2975 }
2976 
TEST_F(AidlTest,ConflictWithMetaTransactionGetVersion)2977 TEST_F(AidlTest, ConflictWithMetaTransactionGetVersion) {
2978   const string expected_stderr =
2979       "ERROR: p/IFoo.aidl:1.31-51:  method getInterfaceVersion() is reserved for internal use.\n";
2980   Options options = Options::From("aidl --lang=java -I . -o place/for/output p/IFoo.aidl");
2981   // int getInterfaceVersion() is one of the meta transactions
2982   io_delegate_.SetFileContents(options.InputFiles().front(),
2983                                "package p; interface IFoo {"
2984                                "int getInterfaceVersion(); }");
2985   CaptureStderr();
2986   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2987   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2988 }
2989 
TEST_F(AidlTest,ConflictWithSimilarMetaTransaction)2990 TEST_F(AidlTest, ConflictWithSimilarMetaTransaction) {
2991   // boolean getInterfaceVersion() is not a meta transaction, but should be
2992   // prevented because return type is not part of a method signature
2993   const string expected_stderr =
2994       "ERROR: p/IFoo.aidl:1.35-55:  method getInterfaceVersion() is reserved for internal use.\n";
2995   Options options = Options::From("aidl --lang=java -I . -o place/for/output p/IFoo.aidl");
2996   io_delegate_.SetFileContents(options.InputFiles().front(),
2997                                "package p; interface IFoo {"
2998                                "boolean getInterfaceVersion(); }");
2999   CaptureStderr();
3000   EXPECT_FALSE(compile_aidl(options, io_delegate_));
3001   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3002 }
3003 
TEST_F(AidlTest,ConflictWithMetaTransactionGetName)3004 TEST_F(AidlTest, ConflictWithMetaTransactionGetName) {
3005   // this is another reserved name
3006   const string expected_stderr =
3007       "ERROR: p/IFoo.aidl:1.34-53:  method getTransactionName(int) is reserved for internal use.\n";
3008   Options options = Options::From("aidl --lang=java -I . -o place/for/output p/IFoo.aidl");
3009   io_delegate_.SetFileContents(options.InputFiles().front(),
3010                                "package p; interface IFoo {"
3011                                "String getTransactionName(int code); }");
3012   CaptureStderr();
3013   EXPECT_FALSE(compile_aidl(options, io_delegate_));
3014   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3015 
3016   // this is not a meta interface method as it differs type arguments
3017   io_delegate_.SetFileContents(options.InputFiles().front(),
3018                                "package p; interface IFoo {"
3019                                "String getTransactionName(); }");
3020   EXPECT_TRUE(compile_aidl(options, io_delegate_));
3021 }
3022 
TEST_F(AidlTest,CheckApiForEquality)3023 TEST_F(AidlTest, CheckApiForEquality) {
3024   CaptureStderr();
3025   Options options = Options::From("aidl --checkapi=equal old new");
3026 
3027   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3028                                "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
3029   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3030                                "package p; interface IFoo{ @utf8InCpp String foo();}");
3031 
3032   EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
3033   EXPECT_THAT(GetCapturedStderr(), HasSubstr("+  @utf8InCpp String foo();"));
3034 }
3035 
TEST_F(AidlTest,DifferentOrderAnnotationsInCheckAPI)3036 TEST_F(AidlTest, DifferentOrderAnnotationsInCheckAPI) {
3037   Options options = Options::From("aidl --checkapi old new");
3038   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3039                                "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
3040   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3041                                "package p; interface IFoo{ @nullable @utf8InCpp String foo();}");
3042 
3043   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3044 }
3045 
TEST_F(AidlTest,JavaPassthroughAnnotationAddedInCheckApi)3046 TEST_F(AidlTest, JavaPassthroughAnnotationAddedInCheckApi) {
3047   Options options = Options::From("aidl --checkapi old new");
3048   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{}");
3049   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3050                                "package p; @JavaPassthrough(annotation=\"@foo\") interface IFoo{}");
3051 
3052   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3053 }
3054 
TEST_F(AidlTest,SuccessOnIdenticalApiDumps)3055 TEST_F(AidlTest, SuccessOnIdenticalApiDumps) {
3056   Options options = Options::From("aidl --checkapi old new");
3057   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
3058   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
3059 
3060   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3061 }
3062 
TEST_F(AidlTest,CheckApi_EnumFieldsWithDefaultValues)3063 TEST_F(AidlTest, CheckApi_EnumFieldsWithDefaultValues) {
3064   Options options = Options::From("aidl --checkapi old new");
3065   const string foo_definition = "package p; parcelable Foo{ p.Enum e = p.Enum.FOO; }";
3066   const string enum_definition = "package p; enum Enum { FOO }";
3067   io_delegate_.SetFileContents("old/p/Foo.aidl", foo_definition);
3068   io_delegate_.SetFileContents("old/p/Enum.aidl", enum_definition);
3069   io_delegate_.SetFileContents("new/p/Foo.aidl", foo_definition);
3070   io_delegate_.SetFileContents("new/p/Enum.aidl", enum_definition);
3071 
3072   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3073 }
3074 
TEST_F(AidlTest,CheckApi_EnumFieldsFromImported)3075 TEST_F(AidlTest, CheckApi_EnumFieldsFromImported) {
3076   Options options = Options::From("aidl --checkapi old new -I import");
3077 
3078   io_delegate_.SetFileContents("old/p/Foo.aidl", "package p; parcelable Foo{ other.Enum e; }");
3079   io_delegate_.SetFileContents("new/p/Foo.aidl",
3080                                "package p; parcelable Foo{ other.Enum e = other.Enum.FOO; }");
3081   io_delegate_.SetFileContents("import/other/Enum.aidl", "package other; enum Enum { FOO }");
3082 
3083   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3084 }
3085 
TEST_F(AidlTest,CheckApiEqual_EnumFieldsWithDefaultValues)3086 TEST_F(AidlTest, CheckApiEqual_EnumFieldsWithDefaultValues) {
3087   Options options = Options::From("aidl --checkapi=equal old new");
3088   const string foo_definition = "package p; parcelable Foo{ p.Enum e = p.Enum.FOO; }";
3089   const string enum_definition = "package p; enum Enum { FOO }";
3090   io_delegate_.SetFileContents("old/p/Foo.aidl", foo_definition);
3091   io_delegate_.SetFileContents("old/p/Enum.aidl", enum_definition);
3092   io_delegate_.SetFileContents("new/p/Foo.aidl", foo_definition);
3093   io_delegate_.SetFileContents("new/p/Enum.aidl", enum_definition);
3094   CaptureStderr();
3095   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3096   EXPECT_EQ("", GetCapturedStderr());
3097 }
3098 
3099 class AidlTestCompatibleChanges : public AidlTest {
3100  protected:
3101   Options options_ = Options::From("aidl --checkapi old new");
3102 };
3103 
TEST_F(AidlTestCompatibleChanges,NewType)3104 TEST_F(AidlTestCompatibleChanges, NewType) {
3105   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3106                                "package p;"
3107                                "interface IFoo {"
3108                                "  void foo(int a);"
3109                                "}");
3110   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3111                                "package p;"
3112                                "interface IFoo {"
3113                                "  void foo(int a);"
3114                                "}");
3115   io_delegate_.SetFileContents("new/p/IBar.aidl",
3116                                "package p;"
3117                                "interface IBar {"
3118                                "  void bar();"
3119                                "}");
3120   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3121 }
3122 
TEST_F(AidlTestCompatibleChanges,NewMethod)3123 TEST_F(AidlTestCompatibleChanges, NewMethod) {
3124   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3125                                "package p;"
3126                                "interface IFoo {"
3127                                "  void foo(int a);"
3128                                "}");
3129   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3130                                "package p;"
3131                                "interface IFoo {"
3132                                "  void foo(int a);"
3133                                "  void bar();"
3134                                "  void baz(in List<String> arg);"
3135                                "}");
3136   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3137 }
3138 
TEST_F(AidlTestCompatibleChanges,NewField)3139 TEST_F(AidlTestCompatibleChanges, NewField) {
3140   io_delegate_.SetFileContents("old/p/Data.aidl",
3141                                "package p;"
3142                                "parcelable Data {"
3143                                "  int foo;"
3144                                "}");
3145   io_delegate_.SetFileContents("new/p/Data.aidl",
3146                                "package p;"
3147                                "parcelable Data {"
3148                                "  int foo;"
3149                                "  int bar = 0;"
3150                                "  @nullable List<Data> list;"
3151                                "}");
3152   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3153 }
3154 
TEST_F(AidlTestCompatibleChanges,NewField2)3155 TEST_F(AidlTestCompatibleChanges, NewField2) {
3156   io_delegate_.SetFileContents("old/p/Data.aidl",
3157                                "package p;"
3158                                "parcelable Data {"
3159                                "}");
3160   io_delegate_.SetFileContents("new/p/Data.aidl",
3161                                "package p;"
3162                                "parcelable Data {"
3163                                "  int foo = 0;"
3164                                "}");
3165   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3166 }
3167 
TEST_F(AidlTestCompatibleChanges,NewEnumerator)3168 TEST_F(AidlTestCompatibleChanges, NewEnumerator) {
3169   io_delegate_.SetFileContents("old/p/Enum.aidl",
3170                                "package p;"
3171                                "enum Enum {"
3172                                "  FOO = 1,"
3173                                "}");
3174   io_delegate_.SetFileContents("new/p/Enum.aidl",
3175                                "package p;"
3176                                "enum Enum {"
3177                                "  FOO = 1,"
3178                                "  BAR = 2,"
3179                                "}");
3180   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3181 }
3182 
TEST_F(AidlTestCompatibleChanges,ReorderedEnumerator)3183 TEST_F(AidlTestCompatibleChanges, ReorderedEnumerator) {
3184   io_delegate_.SetFileContents("old/p/Enum.aidl",
3185                                "package p;"
3186                                "enum Enum {"
3187                                "  FOO = 1,"
3188                                "  BAR = 2,"
3189                                "}");
3190   io_delegate_.SetFileContents("new/p/Enum.aidl",
3191                                "package p;"
3192                                "enum Enum {"
3193                                "  BAR = 2,"
3194                                "  FOO = 1,"
3195                                "}");
3196   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3197 }
3198 
TEST_F(AidlTestCompatibleChanges,NewUnionField)3199 TEST_F(AidlTestCompatibleChanges, NewUnionField) {
3200   io_delegate_.SetFileContents("old/p/Union.aidl",
3201                                "package p;"
3202                                "union Union {"
3203                                "  String foo;"
3204                                "}");
3205   io_delegate_.SetFileContents("new/p/Union.aidl",
3206                                "package p;"
3207                                "union Union {"
3208                                "  String foo;"
3209                                "  int num;"
3210                                "}");
3211   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3212 }
3213 
TEST_F(AidlTestCompatibleChanges,NewPackage)3214 TEST_F(AidlTestCompatibleChanges, NewPackage) {
3215   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3216                                "package p;"
3217                                "interface IFoo {"
3218                                "  void foo(int a);"
3219                                "}");
3220   io_delegate_.SetFileContents("old/p/Data.aidl",
3221                                "package p;"
3222                                "parcelable Data {"
3223                                "  int foo;"
3224                                "}");
3225   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3226                                "package p;"
3227                                "interface IFoo {"
3228                                "  void foo(int a);"
3229                                "}");
3230   io_delegate_.SetFileContents("new/p/Data.aidl",
3231                                "package p;"
3232                                "parcelable Data {"
3233                                "  int foo;"
3234                                "}");
3235   io_delegate_.SetFileContents("new/q/IFoo.aidl",
3236                                "package q;"
3237                                "interface IFoo {"
3238                                "  void foo(int a);"
3239                                "}");
3240   io_delegate_.SetFileContents("new/q/Data.aidl",
3241                                "package q;"
3242                                "parcelable Data {"
3243                                "  int foo;"
3244                                "}");
3245   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3246 }
3247 
TEST_F(AidlTestCompatibleChanges,ArgNameChange)3248 TEST_F(AidlTestCompatibleChanges, ArgNameChange) {
3249   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3250                                "package p;"
3251                                "interface IFoo {"
3252                                "  void foo(int a);"
3253                                "}");
3254   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3255                                "package p;"
3256                                "interface IFoo {"
3257                                "  void foo(int b);"
3258                                "}");
3259   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3260 }
3261 
TEST_F(AidlTestCompatibleChanges,AddedConstValue)3262 TEST_F(AidlTestCompatibleChanges, AddedConstValue) {
3263   io_delegate_.SetFileContents("old/p/I.aidl",
3264                                "package p; interface I {"
3265                                "const int A = 1; }");
3266   io_delegate_.SetFileContents("new/p/I.aidl",
3267                                "package p ; interface I {"
3268                                "const int A = 1; const int B = 2;}");
3269   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3270 }
3271 
TEST_F(AidlTestCompatibleChanges,ChangedConstValueOrder)3272 TEST_F(AidlTestCompatibleChanges, ChangedConstValueOrder) {
3273   io_delegate_.SetFileContents("old/p/I.aidl",
3274                                "package p; interface I {"
3275                                "const int A = 1; const int B = 2;}");
3276   io_delegate_.SetFileContents("new/p/I.aidl",
3277                                "package p ; interface I {"
3278                                "const int B = 2; const int A = 1;}");
3279   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3280 }
3281 
TEST_F(AidlTestCompatibleChanges,ReorderedAnnatations)3282 TEST_F(AidlTestCompatibleChanges, ReorderedAnnatations) {
3283   io_delegate_.SetFileContents("old/p/Foo.aidl",
3284                                "package p;"
3285                                "@JavaPassthrough(annotation=\"Alice\")"
3286                                "@JavaPassthrough(annotation=\"Bob\")"
3287                                "parcelable Foo {}");
3288   io_delegate_.SetFileContents("new/p/Foo.aidl",
3289                                "package p;"
3290                                "@JavaPassthrough(annotation=\"Bob\")"
3291                                "@JavaPassthrough(annotation=\"Alice\")"
3292                                "parcelable Foo {}");
3293   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3294 }
3295 
TEST_F(AidlTestCompatibleChanges,OkayToDeprecate)3296 TEST_F(AidlTestCompatibleChanges, OkayToDeprecate) {
3297   io_delegate_.SetFileContents("old/p/Foo.aidl",
3298                                "package p;"
3299                                "parcelable Foo {}");
3300   io_delegate_.SetFileContents("new/p/Foo.aidl",
3301                                "package p;"
3302                                "@JavaPassthrough(annotation=\"@Deprecated\")"
3303                                "parcelable Foo {}");
3304   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3305 }
3306 
TEST_F(AidlTestCompatibleChanges,NewFieldOfNewType)3307 TEST_F(AidlTestCompatibleChanges, NewFieldOfNewType) {
3308   io_delegate_.SetFileContents("old/p/Data.aidl",
3309                                "package p;"
3310                                "parcelable Data {"
3311                                "  int num;"
3312                                "}");
3313   io_delegate_.SetFileContents(
3314       "new/p/Data.aidl",
3315       "package p;"
3316       "parcelable Data {"
3317       "  int num;"
3318       "  p.Enum e;"  // this is considered as valid since 0(enum default) is valid for "Enum" type
3319       "}");
3320   io_delegate_.SetFileContents("new/p/Enum.aidl",
3321                                "package p;"
3322                                "enum Enum {"
3323                                "  FOO = 0,"
3324                                "  BAR = 1,"
3325                                "}");
3326   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3327 }
3328 
TEST_F(AidlTestCompatibleChanges,CompatibleExplicitDefaults)3329 TEST_F(AidlTestCompatibleChanges, CompatibleExplicitDefaults) {
3330   io_delegate_.SetFileContents("old/p/Data.aidl",
3331                                "package p;\n"
3332                                "parcelable Data {\n"
3333                                "  p.Enum e;\n"
3334                                "}");
3335   io_delegate_.SetFileContents("old/p/Enum.aidl",
3336                                "package p;\n"
3337                                "enum Enum {\n"
3338                                "  FOO = 0,\n"
3339                                "  BAR = 1,\n"
3340                                "}");
3341   io_delegate_.SetFileContents("new/p/Data.aidl",
3342                                "package p;\n"
3343                                "parcelable Data {\n"
3344                                "  p.Enum e = p.Enum.FOO;\n"
3345                                "}");
3346   io_delegate_.SetFileContents("new/p/Enum.aidl",
3347                                "package p;\n"
3348                                "enum Enum {\n"
3349                                "  FOO = 0,\n"
3350                                "  BAR = 1,\n"
3351                                "}");
3352   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3353 }
3354 
TEST_F(AidlTestCompatibleChanges,NewNestedTypes)3355 TEST_F(AidlTestCompatibleChanges, NewNestedTypes) {
3356   io_delegate_.SetFileContents("old/p/Data.aidl",
3357                                "package p;\n"
3358                                "parcelable Data {\n"
3359                                "  int n;\n"
3360                                "}");
3361   io_delegate_.SetFileContents("new/p/Data.aidl",
3362                                "package p;\n"
3363                                "parcelable Data {\n"
3364                                "  enum NewEnum { N = 3 }\n"
3365                                "  int n;\n"
3366                                "  NewEnum e = NewEnum.N;\n"
3367                                "}");
3368   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3369 }
3370 
TEST_F(AidlTestCompatibleChanges,NewJavaSuppressLint)3371 TEST_F(AidlTestCompatibleChanges, NewJavaSuppressLint) {
3372   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3373                                "package p;"
3374                                "interface IFoo {"
3375                                "  void foo(int a);"
3376                                "}");
3377   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3378                                "package p;"
3379                                "@JavaSuppressLint({\"NewApi\"})"
3380                                "interface IFoo {"
3381                                "  void foo(int a);"
3382                                "}");
3383   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3384 }
3385 
3386 class AidlTestIncompatibleChanges : public AidlTest {
3387  protected:
3388   Options options_ = Options::From("aidl --checkapi old new");
3389 };
3390 
TEST_F(AidlTestIncompatibleChanges,RemovedType)3391 TEST_F(AidlTestIncompatibleChanges, RemovedType) {
3392   const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
3393   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3394                                "package p;"
3395                                "interface IFoo {"
3396                                "  void foo(in String[] str);"
3397                                "  void bar(@utf8InCpp String str);"
3398                                "}");
3399   CaptureStderr();
3400   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3401   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3402 }
3403 
TEST_F(AidlTestIncompatibleChanges,RemovedMethod)3404 TEST_F(AidlTestIncompatibleChanges, RemovedMethod) {
3405   const string expected_stderr =
3406       "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
3407   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3408                                "package p;"
3409                                "interface IFoo {"
3410                                "  void foo(in String[] str);"
3411                                "  void bar(@utf8InCpp String str);"
3412                                "}");
3413   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3414                                "package p;"
3415                                "interface IFoo {"
3416                                "  void foo(in String[] str);"
3417                                "}");
3418   CaptureStderr();
3419   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3420   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3421 }
3422 
TEST_F(AidlTestIncompatibleChanges,UntypedListInInterface)3423 TEST_F(AidlTestIncompatibleChanges, UntypedListInInterface) {
3424   const string expected_stderr =
3425       "ERROR: new/p/IFoo.aidl:1.61-65: "
3426       "Encountered an untyped List or Map. The use of untyped List/Map is "
3427       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3428       "the receiving side. Consider switching to an array or a generic List/Map.\n"
3429       "ERROR: new/p/IFoo.aidl: Failed to read.\n";
3430   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3431                                "package p;"
3432                                "interface IFoo {"
3433                                "  void foo(in String[] str);"
3434                                "}");
3435   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3436                                "package p;"
3437                                "interface IFoo {"
3438                                "  void foo(in String[] str);"
3439                                "  void bar(in List arg);"
3440                                "}");
3441   CaptureStderr();
3442   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3443   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3444 }
3445 
TEST_F(AidlTestCompatibleChanges,UntypedListInParcelable)3446 TEST_F(AidlTestCompatibleChanges, UntypedListInParcelable) {
3447   const string expected_stderr =
3448       "ERROR: new/p/Data.aidl:1.54-59: "
3449       "Encountered an untyped List or Map. The use of untyped List/Map is "
3450       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3451       "the receiving side. Consider switching to an array or a generic List/Map.\n"
3452       "ERROR: new/p/Data.aidl: Failed to read.\n";
3453   io_delegate_.SetFileContents("old/p/Data.aidl",
3454                                "package p;"
3455                                "parcelable Data {"
3456                                "  int foo;"
3457                                "}");
3458   io_delegate_.SetFileContents("new/p/Data.aidl",
3459                                "package p;"
3460                                "parcelable Data {"
3461                                "  int foo;"
3462                                "  @nullable List list;"
3463                                "}");
3464   CaptureStderr();
3465   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3466   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3467 }
3468 
TEST_F(AidlTestIncompatibleChanges,RemovedField)3469 TEST_F(AidlTestIncompatibleChanges, RemovedField) {
3470   const string expected_stderr =
3471       "ERROR: new/p/Data.aidl:1.21-26: Number of fields in p.Data is reduced from 2 to 1.\n";
3472   io_delegate_.SetFileContents("old/p/Data.aidl",
3473                                "package p;"
3474                                "parcelable Data {"
3475                                "  int foo;"
3476                                "  int bar;"
3477                                "}");
3478   io_delegate_.SetFileContents("new/p/Data.aidl",
3479                                "package p;"
3480                                "parcelable Data {"
3481                                "  int foo;"
3482                                "}");
3483   CaptureStderr();
3484   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3485   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3486 }
3487 
TEST_F(AidlTestIncompatibleChanges,NewFieldWithNoDefault)3488 TEST_F(AidlTestIncompatibleChanges, NewFieldWithNoDefault) {
3489   const string expected_stderr =
3490       "ERROR: new/p/Data.aidl:1.46-50: Field 'str' does not have a useful default in some "
3491       "backends. Please either provide a default value for this field or mark the field as "
3492       "@nullable. This value or a null value will be used automatically when an old version of "
3493       "this parcelable is sent to a process which understands a new version of this parcelable. In "
3494       "order to make sure your code continues to be backwards compatible, make sure the default or "
3495       "null value does not cause a semantic change to this parcelable.\n";
3496   io_delegate_.SetFileContents("old/p/Data.aidl",
3497                                "package p;"
3498                                "parcelable Data {"
3499                                "  int num;"
3500                                "}");
3501   io_delegate_.SetFileContents("new/p/Data.aidl",
3502                                "package p;"
3503                                "parcelable Data {"
3504                                "  int num;"
3505                                "  String str;"
3506                                "}");
3507   CaptureStderr();
3508   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3509   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3510 }
3511 
TEST_F(AidlTestIncompatibleChanges,NewFieldWithNonZeroEnum)3512 TEST_F(AidlTestIncompatibleChanges, NewFieldWithNonZeroEnum) {
3513   const string expected_stderr =
3514       "ERROR: new/p/Data.aidl:1.46-48: Field 'e' of enum 'Enum' can't be initialized as '0'. "
3515       "Please make sure 'Enum' has '0' as a valid value.\n";
3516   io_delegate_.SetFileContents("old/p/Data.aidl",
3517                                "package p;"
3518                                "parcelable Data {"
3519                                "  int num;"
3520                                "}");
3521   io_delegate_.SetFileContents("new/p/Data.aidl",
3522                                "package p;"
3523                                "parcelable Data {"
3524                                "  int num;"
3525                                "  p.Enum e;"
3526                                "}");
3527   io_delegate_.SetFileContents("new/p/Enum.aidl",
3528                                "package p;"
3529                                "enum Enum {"
3530                                "  FOO = 1,"
3531                                "  BAR = 2,"
3532                                "}");
3533   CaptureStderr();
3534   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3535   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3536 }
3537 
TEST_F(AidlTestIncompatibleChanges,RemovedEnumerator)3538 TEST_F(AidlTestIncompatibleChanges, RemovedEnumerator) {
3539   const string expected_stderr =
3540       "ERROR: new/p/Enum.aidl:1.15-20: Removed enumerator from p.Enum: FOO\n";
3541   io_delegate_.SetFileContents("old/p/Enum.aidl",
3542                                "package p;"
3543                                "enum Enum {"
3544                                "  FOO = 1,"
3545                                "  BAR = 2,"
3546                                "}");
3547   io_delegate_.SetFileContents("new/p/Enum.aidl",
3548                                "package p;"
3549                                "enum Enum {"
3550                                "  BAR = 2,"
3551                                "}");
3552   CaptureStderr();
3553   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3554   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3555 }
3556 
TEST_F(AidlTestIncompatibleChanges,RemovedUnionField)3557 TEST_F(AidlTestIncompatibleChanges, RemovedUnionField) {
3558   const string expected_stderr =
3559       "ERROR: new/p/Union.aidl:1.16-22: Number of fields in p.Union is reduced from 2 to 1.\n";
3560   io_delegate_.SetFileContents("old/p/Union.aidl",
3561                                "package p;"
3562                                "union Union {"
3563                                "  String str;"
3564                                "  int num;"
3565                                "}");
3566   io_delegate_.SetFileContents("new/p/Union.aidl",
3567                                "package p;"
3568                                "union Union {"
3569                                "  String str;"
3570                                "}");
3571   CaptureStderr();
3572   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3573   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3574 }
3575 
TEST_F(AidlTestIncompatibleChanges,RenamedMethod)3576 TEST_F(AidlTestIncompatibleChanges, RenamedMethod) {
3577   const string expected_stderr =
3578       "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
3579   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3580                                "package p;"
3581                                "interface IFoo {"
3582                                "  void foo(in String[] str);"
3583                                "  void bar(@utf8InCpp String str);"
3584                                "}");
3585   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3586                                "package p;"
3587                                "interface IFoo {"
3588                                "  void foo(in String[] str);"
3589                                "  void bar2(@utf8InCpp String str);"
3590                                "}");
3591   CaptureStderr();
3592   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3593   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3594 }
3595 
TEST_F(AidlTestIncompatibleChanges,RenamedType)3596 TEST_F(AidlTestIncompatibleChanges, RenamedType) {
3597   const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
3598   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3599                                "package p;"
3600                                "interface IFoo {"
3601                                "  void foo(in String[] str);"
3602                                "  void bar(@utf8InCpp String str);"
3603                                "}");
3604   io_delegate_.SetFileContents("new/p/IFoo2.aidl",
3605                                "package p;"
3606                                "interface IFoo2 {"
3607                                "  void foo(in String[] str);"
3608                                "  void bar(@utf8InCpp String str);"
3609                                "}");
3610   CaptureStderr();
3611   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3612   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3613 }
3614 
TEST_F(AidlTestIncompatibleChanges,ChangedEnumerator)3615 TEST_F(AidlTestIncompatibleChanges, ChangedEnumerator) {
3616   const string expected_stderr =
3617       "ERROR: new/p/Enum.aidl:1.15-20: Changed enumerator value: p.Enum::FOO from 1 to 3.\n";
3618   io_delegate_.SetFileContents("old/p/Enum.aidl",
3619                                "package p;"
3620                                "enum Enum {"
3621                                "  FOO = 1,"
3622                                "  BAR = 2,"
3623                                "}");
3624   io_delegate_.SetFileContents("new/p/Enum.aidl",
3625                                "package p;"
3626                                "enum Enum {"
3627                                "  FOO = 3,"
3628                                "  BAR = 2,"
3629                                "}");
3630   CaptureStderr();
3631   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3632   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3633 }
3634 
TEST_F(AidlTestIncompatibleChanges,ReorderedMethod)3635 TEST_F(AidlTestIncompatibleChanges, ReorderedMethod) {
3636   const string expected_stderr =
3637       "ERROR: new/p/IFoo.aidl:1.67-71: Transaction ID changed: p.IFoo.foo(String[]) is changed "
3638       "from 0 to 1.\n"
3639       "ERROR: new/p/IFoo.aidl:1.33-37: Transaction ID changed: p.IFoo.bar(String) is changed from "
3640       "1 to 0.\n";
3641   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3642                                "package p;"
3643                                "interface IFoo {"
3644                                "  void foo(in String[] str);"
3645                                "  void bar(@utf8InCpp String str);"
3646                                "}");
3647   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3648                                "package p;"
3649                                "interface IFoo {"
3650                                "  void bar(@utf8InCpp String str);"
3651                                "  void foo(in String[] str);"
3652                                "}");
3653   CaptureStderr();
3654   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3655   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3656 }
3657 
TEST_F(AidlTestIncompatibleChanges,ReorderedField)3658 TEST_F(AidlTestIncompatibleChanges, ReorderedField) {
3659   const string expected_stderr =
3660       "ERROR: new/p/Data.aidl:1.33-37: Reordered bar from 1 to 0.\n"
3661       "ERROR: new/p/Data.aidl:1.43-47: Reordered foo from 0 to 1.\n";
3662   io_delegate_.SetFileContents("old/p/Data.aidl",
3663                                "package p;"
3664                                "parcelable Data {"
3665                                "  int foo;"
3666                                "  int bar;"
3667                                "}");
3668   io_delegate_.SetFileContents("new/p/Data.aidl",
3669                                "package p;"
3670                                "parcelable Data {"
3671                                "  int bar;"
3672                                "  int foo;"
3673                                "}");
3674   CaptureStderr();
3675   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3676   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3677 }
3678 
TEST_F(AidlTestIncompatibleChanges,ChangedDirectionSpecifier)3679 TEST_F(AidlTestIncompatibleChanges, ChangedDirectionSpecifier) {
3680   const string expected_stderr = "ERROR: new/p/IFoo.aidl:1.33-37: Direction changed: in to out.\n";
3681   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3682                                "package p;"
3683                                "interface IFoo {"
3684                                "  void foo(in String[] str);"
3685                                "  void bar(@utf8InCpp String str);"
3686                                "}");
3687   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3688                                "package p;"
3689                                "interface IFoo {"
3690                                "  void foo(out String[] str);"
3691                                "  void bar(@utf8InCpp String str);"
3692                                "}");
3693   CaptureStderr();
3694   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3695   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3696 }
3697 
TEST_F(AidlTestIncompatibleChanges,AddedAnnotation)3698 TEST_F(AidlTestIncompatibleChanges, AddedAnnotation) {
3699   const string expected_stderr =
3700       "ERROR: new/p/IFoo.aidl:1.51-58: Changed annotations: (empty) to @utf8InCpp\n";
3701   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3702                                "package p;"
3703                                "interface IFoo {"
3704                                "  void foo(in String[] str);"
3705                                "  void bar(@utf8InCpp String str);"
3706                                "}");
3707   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3708                                "package p;"
3709                                "interface IFoo {"
3710                                "  void foo(in @utf8InCpp String[] str);"
3711                                "  void bar(@utf8InCpp String str);"
3712                                "}");
3713   CaptureStderr();
3714   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3715   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3716 }
3717 
TEST_F(AidlTestIncompatibleChanges,RemovedAnnotation)3718 TEST_F(AidlTestIncompatibleChanges, RemovedAnnotation) {
3719   const string expected_stderr =
3720       "ERROR: new/p/IFoo.aidl:1.66-72: Changed annotations: @utf8InCpp to (empty)\n";
3721   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3722                                "package p;"
3723                                "interface IFoo {"
3724                                "  void foo(in String[] str);"
3725                                "  void bar(@utf8InCpp String str);"
3726                                "}");
3727   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3728                                "package p;"
3729                                "interface IFoo {"
3730                                "  void foo(in String[] str);"
3731                                "  void bar(String str);"
3732                                "}");
3733   CaptureStderr();
3734   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3735   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3736 }
3737 
TEST_F(AidlTestIncompatibleChanges,ChangedFixedSizeArraySize)3738 TEST_F(AidlTestIncompatibleChanges, ChangedFixedSizeArraySize) {
3739   const string expected_stderr =
3740       "ERROR: new/p/Data.aidl:1.28-33: Type changed: int[8] to int[9].\n";
3741   io_delegate_.SetFileContents("old/p/Data.aidl",
3742                                "package p;"
3743                                "parcelable Data {"
3744                                "  int[8] bar;"
3745                                "}");
3746   io_delegate_.SetFileContents("new/p/Data.aidl",
3747                                "package p;"
3748                                "parcelable Data {"
3749                                "  int[9] bar;"
3750                                "}");
3751   CaptureStderr();
3752   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3753   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3754 }
3755 
TEST_F(AidlTestIncompatibleChanges,ChangedAnnatationParams)3756 TEST_F(AidlTestIncompatibleChanges, ChangedAnnatationParams) {
3757   // this is also the test for backing type remaining the same
3758   const string expected_stderr =
3759       "ERROR: new/p/Foo.aidl:1.36-40: Changed annotations: @Backing(type=\"int\") "
3760       "to @Backing(type=\"long\")\n";
3761   io_delegate_.SetFileContents("old/p/Foo.aidl",
3762                                "package p;"
3763                                "@Backing(type=\"int\")"
3764                                "enum Foo {A}");
3765   io_delegate_.SetFileContents("new/p/Foo.aidl",
3766                                "package p;"
3767                                "@Backing(type=\"long\")"
3768                                "enum Foo {A}");
3769 
3770   CaptureStderr();
3771   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3772   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3773 }
3774 
TEST_F(AidlTestIncompatibleChanges,AddedParcelableAnnotation)3775 TEST_F(AidlTestIncompatibleChanges, AddedParcelableAnnotation) {
3776   const string expected_stderr =
3777       "ERROR: new/p/Foo.aidl:1.32-36: Changed annotations: (empty) to @FixedSize\n";
3778   io_delegate_.SetFileContents("old/p/Foo.aidl",
3779                                "package p;"
3780                                "parcelable Foo {"
3781                                "  int A;"
3782                                "}");
3783   io_delegate_.SetFileContents("new/p/Foo.aidl",
3784                                "package p;"
3785                                "@FixedSize parcelable Foo {"
3786                                "  int A;"
3787                                "}");
3788   CaptureStderr();
3789   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3790   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3791 }
3792 
TEST_F(AidlTestIncompatibleChanges,RemovedParcelableAnnotation)3793 TEST_F(AidlTestIncompatibleChanges, RemovedParcelableAnnotation) {
3794   const string expected_stderr =
3795       "ERROR: new/p/Foo.aidl:1.21-25: Changed annotations: @FixedSize to (empty)\n";
3796   io_delegate_.SetFileContents("old/p/Foo.aidl",
3797                                "package p;"
3798                                "@FixedSize parcelable Foo {"
3799                                "  int A;"
3800                                "}");
3801   io_delegate_.SetFileContents("new/p/Foo.aidl",
3802                                "package p;"
3803                                "parcelable Foo {"
3804                                "  int A;"
3805                                "}");
3806   CaptureStderr();
3807   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3808   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3809 }
3810 
TEST_F(AidlTestIncompatibleChanges,RemovedPackage)3811 TEST_F(AidlTestIncompatibleChanges, RemovedPackage) {
3812   const string expected_stderr = "ERROR: old/q/IFoo.aidl:1.11-21: Removed type: q.IFoo\n";
3813   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{}");
3814   io_delegate_.SetFileContents("old/q/IFoo.aidl", "package q; interface IFoo{}");
3815   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{}");
3816   CaptureStderr();
3817   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3818   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3819 }
3820 
TEST_F(AidlTestIncompatibleChanges,ChangedDefaultValue)3821 TEST_F(AidlTestIncompatibleChanges, ChangedDefaultValue) {
3822   const string expected_stderr = "ERROR: new/p/D.aidl:1.30-32: Changed default value: 1 to 2.\n";
3823   io_delegate_.SetFileContents("old/p/D.aidl", "package p; parcelable D { int a = 1; }");
3824   io_delegate_.SetFileContents("new/p/D.aidl", "package p; parcelable D { int a = 2; }");
3825   CaptureStderr();
3826   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3827   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3828 }
3829 
TEST_F(AidlTestIncompatibleChanges,RemovedConstValue)3830 TEST_F(AidlTestIncompatibleChanges, RemovedConstValue) {
3831   const string expected_stderr =
3832       "ERROR: old/p/I.aidl:1.51-53: Removed constant declaration: p.I.B\n";
3833   io_delegate_.SetFileContents("old/p/I.aidl",
3834                                "package p; interface I {"
3835                                "const int A = 1; const int B = 2;}");
3836   io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 1; }");
3837   CaptureStderr();
3838   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3839   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3840 }
3841 
TEST_F(AidlTestIncompatibleChanges,ChangedConstValue)3842 TEST_F(AidlTestIncompatibleChanges, ChangedConstValue) {
3843   const string expected_stderr =
3844       "ERROR: new/p/I.aidl:1.11-21: Changed constant value: p.I.A from 1 to 2.\n";
3845   io_delegate_.SetFileContents("old/p/I.aidl", "package p; interface I { const int A = 1; }");
3846   io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 2; }");
3847   CaptureStderr();
3848   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3849   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3850 }
3851 
TEST_F(AidlTestIncompatibleChanges,FixedSizeAddedField)3852 TEST_F(AidlTestIncompatibleChanges, FixedSizeAddedField) {
3853   const string expected_stderr =
3854       "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is changed from 1 to 2. "
3855       "This is an incompatible change for FixedSize types.\n";
3856   io_delegate_.SetFileContents("old/p/Foo.aidl",
3857                                "package p; @FixedSize parcelable Foo { int A = 1; }");
3858   io_delegate_.SetFileContents("new/p/Foo.aidl",
3859                                "package p; @FixedSize parcelable Foo { int A = 1; int B = 2; }");
3860   CaptureStderr();
3861   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3862   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3863 }
3864 
TEST_F(AidlTestIncompatibleChanges,UidRangeParcelAddedField)3865 TEST_F(AidlTestIncompatibleChanges, UidRangeParcelAddedField) {
3866   const string expected_stderr =
3867       "ERROR: new/android/net/UidRangeParcel.aidl:1.32-47: Number of fields in "
3868       "android.net.UidRangeParcel is changed from 1 to 2. "
3869       "But it is forbidden because of legacy support.\n";
3870   io_delegate_.SetFileContents("old/android/net/UidRangeParcel.aidl",
3871                                "package android.net; parcelable UidRangeParcel { int A = 1; }");
3872   io_delegate_.SetFileContents(
3873       "new/android/net/UidRangeParcel.aidl",
3874       "package android.net; parcelable UidRangeParcel { int A = 1; int B = 2; }");
3875   CaptureStderr();
3876   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3877   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3878 }
3879 
TEST_F(AidlTestIncompatibleChanges,FixedSizeRemovedField)3880 TEST_F(AidlTestIncompatibleChanges, FixedSizeRemovedField) {
3881   const string expected_stderr =
3882       "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is reduced from 2 to 1.\n";
3883   io_delegate_.SetFileContents("old/p/Foo.aidl",
3884                                "package p; @FixedSize parcelable Foo { int A = 1; int B = 1; }");
3885   io_delegate_.SetFileContents("new/p/Foo.aidl",
3886                                "package p; @FixedSize parcelable Foo { int A = 1; }");
3887   CaptureStderr();
3888   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3889   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3890 }
3891 
TEST_F(AidlTestIncompatibleChanges,IncompatibleChangesInNestedType)3892 TEST_F(AidlTestIncompatibleChanges, IncompatibleChangesInNestedType) {
3893   const string expected_stderr =
3894       "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is reduced from 2 to 1.\n";
3895   io_delegate_.SetFileContents("old/p/Foo.aidl",
3896                                "package p;\n"
3897                                "parcelable Foo {\n"
3898                                "  interface IBar {\n"
3899                                "    void foo();"
3900                                "  }\n"
3901                                "}");
3902   io_delegate_.SetFileContents("new/p/Foo.aidl",
3903                                "package p;\n"
3904                                "parcelable Foo {\n"
3905                                "  interface IBar {\n"
3906                                "    void foo(int n);"  // incompatible: signature changed
3907                                "  }\n"
3908                                "}");
3909   CaptureStderr();
3910   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3911   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Removed or changed method: p.Foo.IBar.foo()"));
3912 }
3913 
TEST_P(AidlTest,RejectNonFixedSizeFromFixedSize)3914 TEST_P(AidlTest, RejectNonFixedSizeFromFixedSize) {
3915   const string expected_stderr =
3916       "ERROR: Foo.aidl:2.8-10: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3917       "a.\n"
3918       "ERROR: Foo.aidl:3.6-8: The @FixedSize parcelable 'Foo' has a non-fixed size field named b.\n"
3919       "ERROR: Foo.aidl:4.9-11: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3920       "c.\n"
3921       "ERROR: Foo.aidl:5.23-25: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3922       "d.\n"
3923       "ERROR: Foo.aidl:6.10-12: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3924       "e.\n"
3925       "ERROR: Foo.aidl:7.15-17: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3926       "f.\n"
3927       "ERROR: Foo.aidl:9.23-33: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3928       "nullable1.\n"
3929       "ERROR: Foo.aidl:10.34-44: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3930       "nullable2.\n";
3931 
3932   io_delegate_.SetFileContents("Foo.aidl",
3933                                "@FixedSize parcelable Foo {\n"
3934                                "  int[] a;\n"
3935                                "  Bar b;\n"
3936                                "  String c;\n"
3937                                "  ParcelFileDescriptor d;\n"
3938                                "  IBinder e;\n"
3939                                "  List<String> f;\n"
3940                                "  int isFixedSize;\n"
3941                                "  @nullable OtherFixed nullable1;\n"
3942                                "  @nullable(heap=true) OtherFixed nullable2;\n"
3943                                "  float[16] floats;\n"
3944                                "}");
3945   io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { int a; }");
3946   io_delegate_.SetFileContents("OtherFixed.aidl", "@FixedSize parcelable OtherFixed { int a; }");
3947   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
3948 
3949   CaptureStderr();
3950   EXPECT_FALSE(compile_aidl(options, io_delegate_));
3951   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3952 }
3953 
TEST_P(AidlTest,RejectNonFixedSizeFromFixedSize_Union)3954 TEST_P(AidlTest, RejectNonFixedSizeFromFixedSize_Union) {
3955   const string expected_stderr =
3956       "ERROR: Foo.aidl:2.8-10: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3957       "a.\n"
3958       "ERROR: Foo.aidl:3.6-8: The @FixedSize parcelable 'Foo' has a non-fixed size field named b.\n"
3959       "ERROR: Foo.aidl:4.9-11: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3960       "c.\n"
3961       "ERROR: Foo.aidl:5.23-25: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3962       "d.\n"
3963       "ERROR: Foo.aidl:6.10-12: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3964       "e.\n"
3965       "ERROR: Foo.aidl:7.15-17: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3966       "f.\n"
3967       "ERROR: Foo.aidl:9.23-33: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3968       "nullable1.\n"
3969       "ERROR: Foo.aidl:10.34-44: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3970       "nullable2.\n";
3971 
3972   io_delegate_.SetFileContents("Foo.aidl",
3973                                "@FixedSize union Foo {\n"
3974                                "  int[] a = {};\n"
3975                                "  Bar b;\n"
3976                                "  String c;\n"
3977                                "  ParcelFileDescriptor d;\n"
3978                                "  IBinder e;\n"
3979                                "  List<String> f;\n"
3980                                "  int isFixedSize;\n"
3981                                "  @nullable OtherFixed nullable1;\n"
3982                                "  @nullable(heap=true) OtherFixed nullable2;\n"
3983                                "  float[16] floats;\n"
3984                                "}");
3985   io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { int a; }");
3986   io_delegate_.SetFileContents("OtherFixed.aidl", "@FixedSize parcelable OtherFixed { int a; }");
3987   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
3988 
3989   CaptureStderr();
3990   EXPECT_FALSE(compile_aidl(options, io_delegate_));
3991   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3992 }
3993 
TEST_P(AidlTest,AcceptFixedSizeFromFixedSize)3994 TEST_P(AidlTest, AcceptFixedSizeFromFixedSize) {
3995   const string expected_stderr = "";
3996 
3997   io_delegate_.SetFileContents("Foo.aidl", "@FixedSize parcelable Foo { int a; Bar b; }");
3998   io_delegate_.SetFileContents("Bar.aidl", "@FixedSize parcelable Bar { Val c; }");
3999   io_delegate_.SetFileContents("Val.aidl", "enum Val { A, B, }");
4000   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
4001 
4002   CaptureStderr();
4003   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4004   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4005 }
4006 
TEST_F(AidlTest,RejectAmbiguousImports)4007 TEST_F(AidlTest, RejectAmbiguousImports) {
4008   const string expected_stderr =
4009       "ERROR: p/IFoo.aidl: Duplicate files found for q.IBar from:\n"
4010       "dir1/q/IBar.aidl\n"
4011       "dir2/q/IBar.aidl\n";
4012   Options options = Options::From("aidl --lang=java -o out -I . -I dir1 -I dir2 p/IFoo.aidl");
4013   io_delegate_.SetFileContents("p/IFoo.aidl", "package p; import q.IBar; interface IFoo{}");
4014   io_delegate_.SetFileContents("dir1/q/IBar.aidl", "package q; interface IBar{}");
4015   io_delegate_.SetFileContents("dir2/q/IBar.aidl", "package q; interface IBar{}");
4016 
4017   CaptureStderr();
4018   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4019   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4020 }
4021 
TEST_F(AidlTest,HandleManualIdAssignments)4022 TEST_F(AidlTest, HandleManualIdAssignments) {
4023   const string expected_stderr =
4024       "ERROR: new/p/IFoo.aidl:1.32-36: Transaction ID changed: p.IFoo.foo() is changed from 10 to "
4025       "11.\n";
4026   Options options = Options::From("aidl --checkapi old new");
4027   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
4028   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
4029 
4030   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
4031 
4032   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 11;}");
4033   CaptureStderr();
4034   EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
4035   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4036 }
4037 
TEST_P(AidlTest,ParcelFileDescriptorIsBuiltinType)4038 TEST_P(AidlTest, ParcelFileDescriptorIsBuiltinType) {
4039   Options options =
4040       Options::From("aidl -I . --lang=" + to_string(GetLanguage()) + " -h out -o out p/IFoo.aidl");
4041 
4042   // use without import
4043   io_delegate_.SetFileContents("p/IFoo.aidl",
4044                                "package p; interface IFoo{ void foo(in ParcelFileDescriptor fd);}");
4045   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4046 
4047   // capture output files
4048   map<string, string> outputs = io_delegate_.OutputFiles();
4049 
4050   // use without import but with full name
4051   io_delegate_.SetFileContents(
4052       "p/IFoo.aidl",
4053       "package p; interface IFoo{ void foo(in android.os.ParcelFileDescriptor fd);}");
4054   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4055   // output files should be the same
4056   EXPECT_EQ(outputs, io_delegate_.OutputFiles());
4057 
4058   // use with import (as before)
4059   io_delegate_.SetFileContents("p/IFoo.aidl",
4060                                "package p;"
4061                                "import android.os.ParcelFileDescriptor;"
4062                                "interface IFoo{"
4063                                "  void foo(in ParcelFileDescriptor fd);"
4064                                "}");
4065   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4066   // output files should be the same
4067   EXPECT_EQ(outputs, io_delegate_.OutputFiles());
4068 }
4069 
TEST_P(AidlTest,RejectsOutputParcelFileDescriptor)4070 TEST_P(AidlTest, RejectsOutputParcelFileDescriptor) {
4071   Options options = Options::From("aidl p/IFoo.aidl -I . --lang=" + to_string(GetLanguage()));
4072   CaptureStderr();
4073   io_delegate_.SetFileContents("p/IFoo.aidl",
4074                                "package p;"
4075                                "interface IFoo{"
4076                                "  void foo(out ParcelFileDescriptor fd);"
4077                                "}");
4078   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4079   EXPECT_THAT(GetCapturedStderr(), HasSubstr("can't be an out parameter"));
4080 }
4081 
TEST_P(AidlTest,RejectsArgumentDirectionNotSpecified)4082 TEST_P(AidlTest, RejectsArgumentDirectionNotSpecified) {
4083   Options options = Options::From("aidl p/IFoo.aidl -I . --lang=" + to_string(GetLanguage()));
4084   CaptureStderr();
4085   io_delegate_.SetFileContents("p/IFoo.aidl",
4086                                "package p;"
4087                                "interface IFoo{"
4088                                "  void foo(ParcelFileDescriptor fd);"
4089                                "}");
4090   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4091   EXPECT_THAT(GetCapturedStderr(),
4092               HasSubstr("ParcelFileDescriptor can be an in or inout parameter."));
4093 }
4094 
TEST_F(AidlTest,ManualIds)4095 TEST_F(AidlTest, ManualIds) {
4096   Options options = Options::From("aidl --lang=java -I . -o out IFoo.aidl");
4097   io_delegate_.SetFileContents("IFoo.aidl",
4098                                "interface IFoo {\n"
4099                                "  void foo() = 0;\n"
4100                                "  void bar() = 1;\n"
4101                                "}");
4102   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4103 }
4104 
TEST_F(AidlTest,ManualIdsWithMetaTransactions)4105 TEST_F(AidlTest, ManualIdsWithMetaTransactions) {
4106   Options options = Options::From("aidl --lang=java -I . --version 10 -o out IFoo.aidl");
4107   io_delegate_.SetFileContents("IFoo.aidl",
4108                                "interface IFoo {\n"
4109                                "  void foo() = 0;\n"
4110                                "  void bar() = 1;\n"
4111                                "}");
4112   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4113 }
4114 
TEST_F(AidlTest,FailOnDuplicatedIds)4115 TEST_F(AidlTest, FailOnDuplicatedIds) {
4116   const string expected_stderr =
4117       "ERROR: IFoo.aidl:3.7-11: Found duplicate method id (3) for method bar\n";
4118   Options options = Options::From("aidl --lang=java -I . --version 10 -o out IFoo.aidl");
4119   io_delegate_.SetFileContents("IFoo.aidl",
4120                                "interface IFoo {\n"
4121                                "  void foo() = 3;\n"
4122                                "  void bar() = 3;\n"
4123                                "}");
4124   CaptureStderr();
4125   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4126   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4127 }
4128 
TEST_F(AidlTest,FailOnOutOfRangeIds)4129 TEST_F(AidlTest, FailOnOutOfRangeIds) {
4130   // 16777115 is kLastMetaMethodId + 1
4131   const string expected_stderr =
4132       "ERROR: IFoo.aidl:3.7-11: Found out of bounds id (16777115) for method bar. "
4133       "Value for id must be between 0 and 16777114 inclusive.\n";
4134   Options options = Options::From("aidl --lang=java -I . --version 10 -o out IFoo.aidl");
4135   io_delegate_.SetFileContents("IFoo.aidl",
4136                                "interface IFoo {\n"
4137                                "  void foo() = 3;\n"
4138                                "  void bar() = 16777115;\n"
4139                                "}");
4140   CaptureStderr();
4141   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4142   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4143 }
4144 
TEST_F(AidlTest,FailOnPartiallyAssignedIds)4145 TEST_F(AidlTest, FailOnPartiallyAssignedIds) {
4146   const string expected_stderr =
4147       "ERROR: IFoo.aidl:3.7-11: You must either assign id's to all methods or to none of them.\n";
4148   Options options = Options::From("aidl --lang=java -I . --version 10 -o out IFoo.aidl");
4149   io_delegate_.SetFileContents("IFoo.aidl",
4150                                "interface IFoo {\n"
4151                                "  void foo() = 3;\n"
4152                                "  void bar();\n"
4153                                "}");
4154   CaptureStderr();
4155   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4156   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4157 }
4158 
TEST_F(AidlTest,AssignedIds)4159 TEST_F(AidlTest, AssignedIds) {
4160   CaptureStderr();
4161   EXPECT_NE(nullptr, Parse("IFoo.aidl",
4162                            "interface IFoo {\n"
4163                            "  void foo();\n"
4164                            "  void bar();\n"
4165                            "  interface INested {\n"
4166                            "    void foo();\n"
4167                            "    void bar();\n"
4168                            "  }\n"
4169                            "}",
4170                            typenames_, Options::Language::JAVA));
4171   EXPECT_EQ("", GetCapturedStderr());
4172   auto foo = typenames_.ResolveTypename("IFoo").defined_type;
4173   ASSERT_EQ(2u, foo->GetMethods().size());
4174   EXPECT_EQ(0, foo->GetMethods()[0]->GetId());
4175   EXPECT_EQ(1, foo->GetMethods()[1]->GetId());
4176   auto nested = typenames_.ResolveTypename("IFoo.INested").defined_type;
4177   ASSERT_EQ(2u, nested->GetMethods().size());
4178   EXPECT_EQ(0, nested->GetMethods()[0]->GetId());
4179   EXPECT_EQ(1, nested->GetMethods()[1]->GetId());
4180 }
4181 
TEST_F(AidlTest,AllowDuplicatedImportPaths)4182 TEST_F(AidlTest, AllowDuplicatedImportPaths) {
4183   Options options = Options::From("aidl --lang=java -I . -I dir -I dir IFoo.aidl");
4184   io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
4185   io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
4186   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4187 }
4188 
TEST_F(AidlTest,UnusedImportDoesNotContributeInclude)4189 TEST_F(AidlTest, UnusedImportDoesNotContributeInclude) {
4190   io_delegate_.SetFileContents("a/b/IFoo.aidl",
4191                                "package a.b;\n"
4192                                "import a.b.IBar;\n"
4193                                "import a.b.IQux;\n"
4194                                "interface IFoo { IQux foo(); }\n");
4195   io_delegate_.SetFileContents("a/b/IBar.aidl", "package a.b; interface IBar { void foo(); }");
4196   io_delegate_.SetFileContents("a/b/IQux.aidl", "package a.b; interface IQux { void foo(); }");
4197 
4198   Options options = Options::From("aidl --lang=ndk a/b/IFoo.aidl -I . -o out -h out/include");
4199   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4200 
4201   string output;
4202   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/include/aidl/a/b/IFoo.h", &output));
4203   // IBar was imported but wasn't used. include is not expected.
4204   EXPECT_THAT(output, Not(testing::HasSubstr("#include <aidl/a/b/IBar.h>")));
4205   // IBar was imported and used. include is expected.
4206   EXPECT_THAT(output, (testing::HasSubstr("#include <aidl/a/b/IQux.h>")));
4207 }
4208 
TEST_F(AidlTest,BasePathAsImportPath)4209 TEST_F(AidlTest, BasePathAsImportPath) {
4210   Options options = Options::From("aidl --lang=java -I some -I other some/dir/pkg/name/IFoo.aidl");
4211   io_delegate_.SetFileContents("some/dir/pkg/name/IFoo.aidl",
4212       "package pkg.name; interface IFoo { void foo(); }");
4213   const string expected_stderr =
4214       "ERROR: some/dir/pkg/name/IFoo.aidl:1.18-28: directory some/dir/ is not found in any of "
4215       "the import paths:\n - other/\n - some/\n";
4216   CaptureStderr();
4217   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4218   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4219 }
4220 
TEST_F(AidlTest,ParseJavaPassthroughAnnotation)4221 TEST_F(AidlTest, ParseJavaPassthroughAnnotation) {
4222   io_delegate_.SetFileContents("a/IFoo.aidl", R"--(package a;
4223     import a.MyEnum;
4224     @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
4225     @JavaPassthrough(annotation="@com.android.AliceTwo")
4226     interface IFoo {
4227         @JavaPassthrough(annotation="@com.android.Bob")
4228         void foo(@JavaPassthrough(annotation="@com.android.Cat") int x, MyEnum y);
4229         const @JavaPassthrough(annotation="@com.android.David") int A = 3;
4230     })--");
4231   // JavaPassthrough should work with other types as well (e.g. enum)
4232   io_delegate_.SetFileContents("a/MyEnum.aidl", R"--(package a;
4233     @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
4234     @JavaPassthrough(annotation="@com.android.AliceTwo")
4235     @Backing(type="byte")
4236     enum MyEnum {
4237       a, b, c
4238     })--");
4239 
4240   Options java_options = Options::From("aidl -I . --lang=java -o out a/IFoo.aidl a/MyEnum.aidl");
4241   EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
4242 
4243   string java_out;
4244   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/IFoo.java", &java_out));
4245   // type-decl-level annotations with newline at the end
4246   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
4247   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
4248   // member-decl-level annotations with newline at the end
4249   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Bob\n"));
4250   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.David\n"));
4251   // inline annotations with space at the end
4252   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Cat "));
4253 
4254   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/MyEnum.java", &java_out));
4255   // type-decl-level annotations with newline at the end
4256   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
4257   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
4258 
4259   // Other backends shouldn't be bothered
4260   Options cpp_options =
4261       Options::From("aidl -I . --lang=cpp -o out -h out a/IFoo.aidl a/MyEnum.aidl");
4262   EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
4263 
4264   Options ndk_options =
4265       Options::From("aidl -I . --lang=ndk -o out -h out a/IFoo.aidl a/MyEnum.aidl");
4266   EXPECT_TRUE(compile_aidl(ndk_options, io_delegate_));
4267 
4268   Options rust_options = Options::From("aidl -I . --lang=rust -o out a/IFoo.aidl a/MyEnum.aidl");
4269   EXPECT_TRUE(compile_aidl(rust_options, io_delegate_));
4270 }
4271 
TEST_F(AidlTest,ParseRustDerive)4272 TEST_F(AidlTest, ParseRustDerive) {
4273   io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
4274     @RustDerive(Clone=true, Copy=false)
4275     parcelable Foo {
4276         int a;
4277     })");
4278 
4279   Options rust_options = Options::From("aidl -I . --lang=rust -o out a/Foo.aidl");
4280   EXPECT_TRUE(compile_aidl(rust_options, io_delegate_));
4281 
4282   string rust_out;
4283   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.rs", &rust_out));
4284   EXPECT_THAT(rust_out, testing::HasSubstr("#[derive(Debug, Clone)]"));
4285 
4286   // Other backends shouldn't be bothered
4287   Options cpp_options = Options::From("aidl --lang=cpp -I . -o out -h out a/Foo.aidl");
4288   EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
4289 
4290   Options ndk_options = Options::From("aidl --lang=ndk -I . -o out -h out a/Foo.aidl");
4291   EXPECT_TRUE(compile_aidl(ndk_options, io_delegate_));
4292 
4293   Options java_options = Options::From("aidl --lang=java -I . -o out a/Foo.aidl");
4294   EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
4295 }
4296 
TEST_P(AidlTest,TypesShouldHaveRustDerive)4297 TEST_P(AidlTest, TypesShouldHaveRustDerive) {
4298   CaptureStderr();
4299   string code =
4300       "@RustDerive(PartialEq=true)\n"
4301       "parcelable Foo {\n"
4302       "  parcelable Bar {}\n"
4303       "  Bar bar;\n"
4304       "}";
4305   EXPECT_EQ(nullptr, Parse("Foo.aidl", code, typenames_, GetLanguage(), nullptr, {}));
4306   EXPECT_THAT(
4307       GetCapturedStderr(),
4308       testing::HasSubstr("Field bar of type with @RustDerive PartialEq also needs to derive this"));
4309 }
4310 
TEST_F(AidlTest,EmptyEnforceAnnotation)4311 TEST_F(AidlTest, EmptyEnforceAnnotation) {
4312   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4313     interface IFoo {
4314         @EnforcePermission()
4315         void Protected();
4316     })");
4317 
4318   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4319   CaptureStderr();
4320   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4321   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Unable to parse @EnforcePermission annotation"));
4322 }
4323 
TEST_F(AidlTest,InterfaceEnforceCondition)4324 TEST_F(AidlTest, InterfaceEnforceCondition) {
4325   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4326     @EnforcePermission("INTERNET")
4327     interface IFoo {
4328         void Protected();
4329     })");
4330 
4331   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4332   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4333 }
4334 
TEST_F(AidlTest,EnforceConditionAny)4335 TEST_F(AidlTest, EnforceConditionAny) {
4336   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4337     interface IFoo {
4338         @EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"})
4339         void Protected();
4340     })");
4341 
4342   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4343   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4344 }
4345 
TEST_F(AidlTest,EnforceConditionAll)4346 TEST_F(AidlTest, EnforceConditionAll) {
4347   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4348     interface IFoo {
4349         @EnforcePermission(allOf={"INTERNET", "READ_PHONE_STATE"})
4350         void Protected();
4351     })");
4352 
4353   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4354   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4355 }
4356 
TEST_F(AidlTest,InterfaceAndMethodEnforceCondition)4357 TEST_F(AidlTest, InterfaceAndMethodEnforceCondition) {
4358   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4359     @EnforcePermission("INTERNET")
4360     interface IFoo {
4361         @EnforcePermission("SYSTEM_UID")
4362         void Protected();
4363     })");
4364 
4365   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4366   CaptureStderr();
4367   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4368   EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4369                                              "the method Protected is also annotated"));
4370 }
4371 
TEST_F(AidlTest,NoPermissionInterfaceEnforceMethod)4372 TEST_F(AidlTest, NoPermissionInterfaceEnforceMethod) {
4373   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4374     @RequiresNoPermission
4375     interface IFoo {
4376         @EnforcePermission("INTERNET")
4377         void Protected();
4378     })");
4379 
4380   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4381   CaptureStderr();
4382   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4383   EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4384                                              "the method Protected is also annotated"));
4385 }
4386 
TEST_F(AidlTest,ManualPermissionInterfaceEnforceMethod)4387 TEST_F(AidlTest, ManualPermissionInterfaceEnforceMethod) {
4388   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4389     @PermissionManuallyEnforced
4390     interface IFoo {
4391         @EnforcePermission("INTERNET")
4392         void Protected();
4393     })");
4394 
4395   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4396   CaptureStderr();
4397   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4398   EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4399                                              "the method Protected is also annotated"));
4400 }
4401 
TEST_F(AidlTest,EnforceInterfaceNoPermissionsMethod)4402 TEST_F(AidlTest, EnforceInterfaceNoPermissionsMethod) {
4403   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4404     @EnforcePermission("INTERNET")
4405     interface IFoo {
4406         @RequiresNoPermission
4407         void Protected();
4408     })");
4409 
4410   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4411   CaptureStderr();
4412   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4413   EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4414                                              "the method Protected is also annotated"));
4415 }
4416 
TEST_F(AidlTest,EnforceInterfaceManualPermissionMethod)4417 TEST_F(AidlTest, EnforceInterfaceManualPermissionMethod) {
4418   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4419     @EnforcePermission("INTERNET")
4420     interface IFoo {
4421         @PermissionManuallyEnforced
4422         void Protected();
4423     })");
4424 
4425   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4426   CaptureStderr();
4427   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4428   EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4429                                              "the method Protected is also annotated"));
4430 }
4431 
TEST_F(AidlTest,JavaSuppressLint)4432 TEST_F(AidlTest, JavaSuppressLint) {
4433   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4434     @JavaSuppressLint({"NewApi"})
4435     interface IFoo {
4436     })");
4437 
4438   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4439   CaptureStderr();
4440   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4441   EXPECT_EQ(GetCapturedStderr(), "");
4442   string code;
4443   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/IFoo.java", &code));
4444   EXPECT_THAT(code, HasSubstr("@android.annotation.SuppressLint(value = {\"NewApi\"})"));
4445 }
4446 
4447 class AidlOutputPathTest : public AidlTest {
4448  protected:
SetUp()4449   void SetUp() override {
4450     AidlTest::SetUp();
4451     io_delegate_.SetFileContents("sub/dir/foo/bar/IFoo.aidl", "package foo.bar; interface IFoo {}");
4452   }
4453 
Test(const Options & options,const std::string expected_output_path)4454   void Test(const Options& options, const std::string expected_output_path) {
4455     EXPECT_TRUE(compile_aidl(options, io_delegate_));
4456     // check the existence
4457     EXPECT_TRUE(io_delegate_.GetWrittenContents(expected_output_path, nullptr));
4458   }
4459 };
4460 
TEST_F(AidlOutputPathTest,OutDirWithNoOutputFile)4461 TEST_F(AidlOutputPathTest, OutDirWithNoOutputFile) {
4462   // <out_dir> / <package_name> / <type_name>.java
4463   Test(Options::From("aidl -I sub/dir -o out sub/dir/foo/bar/IFoo.aidl"), "out/foo/bar/IFoo.java");
4464 }
4465 
TEST_F(AidlOutputPathTest,OutDirWithOutputFile)4466 TEST_F(AidlOutputPathTest, OutDirWithOutputFile) {
4467   // when output file is explicitly set, it is always respected. -o option is
4468   // ignored.
4469   Test(Options::From("aidl -I sub/dir -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"),
4470        "output/IFoo.java");
4471 }
4472 
TEST_F(AidlOutputPathTest,NoOutDirWithOutputFile)4473 TEST_F(AidlOutputPathTest, NoOutDirWithOutputFile) {
4474   Test(Options::From("aidl -I sub/dir -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"),
4475        "output/IFoo.java");
4476 }
4477 
TEST_F(AidlOutputPathTest,NoOutDirWithNoOutputFile)4478 TEST_F(AidlOutputPathTest, NoOutDirWithNoOutputFile) {
4479   // output is the same as the input file except for the suffix
4480   Test(Options::From("aidl -I sub/dir sub/dir/foo/bar/IFoo.aidl"), "sub/dir/foo/bar/IFoo.java");
4481 }
4482 
TEST_P(AidlTest,PassOnValidUnsignedInt32Int)4483 TEST_P(AidlTest, PassOnValidUnsignedInt32Int) {
4484   EvaluateValidAssignment(
4485       R"(package a; interface IFoo { const int UINT32_VALUE = 2147483650u32; })", "", typenames_,
4486       GetLanguage());
4487 }
4488 
TEST_P(AidlTest,FailOnOutOfBoundsUInt32MaxConstInt)4489 TEST_P(AidlTest, FailOnOutOfBoundsUInt32MaxConstInt) {
4490   AidlError error;
4491   const string expected_stderr =
4492       "ERROR: p/IFoo.aidl:3.59-73: Could not parse integer: 4294967300u32\n";
4493   CaptureStderr();
4494   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4495                            R"(package p;
4496                               interface IFoo {
4497                                 const int uint32_max_oob = 4294967300u32;
4498                               }
4499                              )",
4500                            typenames_, GetLanguage(), &error));
4501   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4502   EXPECT_EQ(AidlError::PARSE_ERROR, error);
4503 }
4504 
TEST_P(AidlTest,PassOnValidUnsignedInt64Int)4505 TEST_P(AidlTest, PassOnValidUnsignedInt64Int) {
4506   EvaluateValidAssignment(
4507       R"(package a; interface IFoo { const long UINT64_VALUE = 18446744073709551615u64; })", "",
4508       typenames_, GetLanguage());
4509 }
4510 
TEST_P(AidlTest,FailOnOutOfBoundsUInt64MaxConstInt)4511 TEST_P(AidlTest, FailOnOutOfBoundsUInt64MaxConstInt) {
4512   AidlError error;
4513   const string expected_stderr =
4514       "ERROR: p/IFoo.aidl:3.60-84: Could not parse integer: 18446744073709551620u64\n";
4515   CaptureStderr();
4516   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4517                            R"(package p;
4518                               interface IFoo {
4519                                 const long uint64_max_oob = 18446744073709551620u64;
4520                               }
4521                              )",
4522                            typenames_, GetLanguage(), &error));
4523   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4524   EXPECT_EQ(AidlError::PARSE_ERROR, error);
4525 }
4526 
TEST_P(AidlTest,PassOnValidUnsignedInt32Hex)4527 TEST_P(AidlTest, PassOnValidUnsignedInt32Hex) {
4528   EvaluateValidAssignment(
4529       R"(package a; interface IFoo { const int UINT32_VALUE = 0xffffffffu32; })", "", typenames_,
4530       GetLanguage());
4531 }
4532 
TEST_P(AidlTest,FailOnOutOfBoundsUInt32MaxConstHex)4533 TEST_P(AidlTest, FailOnOutOfBoundsUInt32MaxConstHex) {
4534   AidlError error;
4535   const string expected_stderr =
4536       "ERROR: p/IFoo.aidl:3.59-74: Invalid type specifier for an int64 literal: int "
4537       "(0xfffffffffu32).\n";
4538   CaptureStderr();
4539   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4540                            R"(package p;
4541                               interface IFoo {
4542                                 const int uint32_max_oob = 0xfffffffffu32;
4543                               }
4544                              )",
4545                            typenames_, GetLanguage(), &error));
4546   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4547   EXPECT_EQ(AidlError::BAD_TYPE, error);
4548 }
4549 
TEST_P(AidlTest,PassOnValidUnsignedInt64Hex)4550 TEST_P(AidlTest, PassOnValidUnsignedInt64Hex) {
4551   EvaluateValidAssignment(
4552       R"(package a; interface IFoo { const int UINT64_VALUE = 0xffffffffffffffffu64; })", "",
4553       typenames_, GetLanguage());
4554 }
4555 
TEST_P(AidlTest,FailOnOutOfBoundsUInt64MaxConstHex)4556 TEST_P(AidlTest, FailOnOutOfBoundsUInt64MaxConstHex) {
4557   AidlError error;
4558   const string expected_stderr =
4559       "ERROR: p/IFoo.aidl:3.59-82: Could not parse hexvalue: 0xfffffffffffffffffu64\n";
4560   CaptureStderr();
4561   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4562                            R"(package p;
4563                               interface IFoo {
4564                                 const int uint64_max_oob = 0xfffffffffffffffffu64;
4565                               }
4566                              )",
4567                            typenames_, GetLanguage(), &error));
4568   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4569   EXPECT_EQ(AidlError::PARSE_ERROR, error);
4570 }
4571 
TEST_P(AidlTest,FailOnOutOfBoundsInt32MaxConstInt)4572 TEST_P(AidlTest, FailOnOutOfBoundsInt32MaxConstInt) {
4573   AidlError error;
4574   const string expected_stderr =
4575       "ERROR: p/IFoo.aidl:3.58-69: Invalid type specifier for an int64 literal: int "
4576       "(2147483650). Did you mean: 2147483650u32?\n";
4577   CaptureStderr();
4578   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4579                            R"(package p;
4580                               interface IFoo {
4581                                 const int int32_max_oob = 2147483650;
4582                               }
4583                              )",
4584                            typenames_, GetLanguage(), &error));
4585   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4586   EXPECT_EQ(AidlError::BAD_TYPE, error);
4587 }
4588 
TEST_P(AidlTest,FailOnOutOfBoundsInt32MinConstInt)4589 TEST_P(AidlTest, FailOnOutOfBoundsInt32MinConstInt) {
4590   AidlError error;
4591   const string expected_stderr =
4592       "ERROR: p/IFoo.aidl:3.58-60: Invalid type specifier for an int64 literal: int "
4593       "(-2147483650).\n";
4594   CaptureStderr();
4595   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4596                            R"(package p;
4597                               interface IFoo {
4598                                 const int int32_min_oob = -2147483650;
4599                               }
4600                              )",
4601                            typenames_, GetLanguage(), &error));
4602   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4603   EXPECT_EQ(AidlError::BAD_TYPE, error);
4604 }
4605 
TEST_P(AidlTest,FailOnOutOfBoundsInt64MaxConstInt)4606 TEST_P(AidlTest, FailOnOutOfBoundsInt64MaxConstInt) {
4607   AidlError error;
4608   const string expected_stderr =
4609       "ERROR: p/IFoo.aidl:3.59-86: Could not parse integer: 21474836509999999999999999\n";
4610   CaptureStderr();
4611   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4612                            R"(package p;
4613                               interface IFoo {
4614                                 const long int64_max_oob = 21474836509999999999999999;
4615                               }
4616                              )",
4617                            typenames_, GetLanguage(), &error));
4618   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4619   EXPECT_EQ(AidlError::PARSE_ERROR, error);
4620 }
4621 
TEST_P(AidlTest,FailOnOutOfBoundsInt64MinConstInt)4622 TEST_P(AidlTest, FailOnOutOfBoundsInt64MinConstInt) {
4623   AidlError error;
4624   const string expected_stderr =
4625       "ERROR: p/IFoo.aidl:3.61-87: Could not parse integer: 21474836509999999999999999\n";
4626   CaptureStderr();
4627   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4628                            R"(package p;
4629                               interface IFoo {
4630                                 const long int64_min_oob = -21474836509999999999999999;
4631                               }
4632                              )",
4633                            typenames_, GetLanguage(), &error));
4634   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4635   EXPECT_EQ(AidlError::PARSE_ERROR, error);
4636 }
4637 
TEST_P(AidlTest,FailOnOutOfBoundsAutofilledEnum)4638 TEST_P(AidlTest, FailOnOutOfBoundsAutofilledEnum) {
4639   AidlError error;
4640   const string expected_stderr =
4641       "ERROR: p/TestEnum.aidl:5.1-36: Invalid type specifier for an int32 literal: byte (FOO+1).\n"
4642       "ERROR: p/TestEnum.aidl:5.1-36: Enumerator type differs from enum backing type.\n";
4643   CaptureStderr();
4644   EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
4645                            R"(package p;
4646                               @Backing(type="byte")
4647                               enum TestEnum {
4648                                 FOO = 127,
4649                                 BAR,
4650                               }
4651                              )",
4652                            typenames_, GetLanguage(), &error));
4653   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4654   EXPECT_EQ(AidlError::BAD_TYPE, error);
4655 }
4656 
TEST_P(AidlTest,FailOnUnsupportedBackingType)4657 TEST_P(AidlTest, FailOnUnsupportedBackingType) {
4658   AidlError error;
4659   const string expected_stderr =
4660       "ERROR: p/TestEnum.aidl:3.35-44: Invalid backing type: boolean. Backing type must be one of: "
4661       "byte, int, long\n";
4662   CaptureStderr();
4663   EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
4664                            R"(package p;
4665                               @Backing(type="boolean")
4666                               enum TestEnum {
4667                                 FOO = 0,
4668                                 BAR = 1,
4669                               }
4670                              )",
4671                            typenames_, GetLanguage(), &error));
4672   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4673   EXPECT_EQ(AidlError::BAD_TYPE, error);
4674 }
4675 
TEST_P(AidlTest,UnsupportedBackingAnnotationParam)4676 TEST_P(AidlTest, UnsupportedBackingAnnotationParam) {
4677   AidlError error;
4678   const string expected_stderr =
4679       "ERROR: p/TestEnum.aidl:2.1-51: Parameter foo not supported for annotation Backing. It must "
4680       "be one of: type\n";
4681   CaptureStderr();
4682   EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
4683                            R"(package p;
4684                               @Backing(foo="byte")
4685                               enum TestEnum {
4686                                 FOO = 1,
4687                                 BAR,
4688                               }
4689                              )",
4690                            typenames_, GetLanguage(), &error));
4691   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4692   EXPECT_EQ(AidlError::BAD_TYPE, error);
4693 }
4694 
TEST_P(AidlTest,BackingAnnotationRequireTypeParameter)4695 TEST_P(AidlTest, BackingAnnotationRequireTypeParameter) {
4696   const string expected_stderr = "ERROR: Enum.aidl:1.1-9: Missing 'type' on @Backing.\n";
4697   CaptureStderr();
4698   EXPECT_EQ(nullptr, Parse("Enum.aidl", "@Backing enum Enum { FOO }", typenames_, GetLanguage()));
4699   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4700 }
4701 
TEST_F(AidlTest,SupportJavaOnlyImmutableAnnotation)4702 TEST_F(AidlTest, SupportJavaOnlyImmutableAnnotation) {
4703   io_delegate_.SetFileContents("Foo.aidl",
4704                                "@JavaOnlyImmutable parcelable Foo { int a; Bar b; List<Bar> c; "
4705                                "Map<String, Baz> d; Bar[] e; }");
4706   io_delegate_.SetFileContents("Bar.aidl", "@JavaOnlyImmutable parcelable Bar { String a; }");
4707   io_delegate_.SetFileContents("Baz.aidl",
4708                                "@JavaOnlyImmutable @JavaOnlyStableParcelable parcelable Baz;");
4709   Options options = Options::From("aidl --lang=java -I . Foo.aidl");
4710   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4711 }
4712 
TEST_F(AidlTest,RejectMutableParcelableFromJavaOnlyImmutableParcelable)4713 TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableParcelable) {
4714   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { Bar bar; }");
4715   io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
4716   string expected_error =
4717       "ERROR: Foo.aidl:1.40-44: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
4718       "named 'bar'.\n";
4719   CaptureStderr();
4720   Options options = Options::From("aidl --lang=java Foo.aidl -I .");
4721   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4722   EXPECT_EQ(expected_error, GetCapturedStderr());
4723 }
4724 
TEST_F(AidlTest,JavaOnlyImmutableParcelableWithEnumFields)4725 TEST_F(AidlTest, JavaOnlyImmutableParcelableWithEnumFields) {
4726   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { Bar bar; }");
4727   io_delegate_.SetFileContents("Bar.aidl", "enum Bar { FOO }");
4728   CaptureStderr();
4729   Options options = Options::From("aidl --lang=java Foo.aidl -I .");
4730   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4731   EXPECT_EQ("", GetCapturedStderr());
4732 }
4733 
TEST_F(AidlTest,RejectMutableParcelableFromJavaOnlyImmutableUnion)4734 TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableUnion) {
4735   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable union Foo { Bar bar; }");
4736   io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
4737   string expected_error =
4738       "ERROR: Foo.aidl:1.35-39: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
4739       "named 'bar'.\n";
4740   CaptureStderr();
4741   Options options = Options::From("aidl --lang=java Foo.aidl -I .");
4742   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4743   EXPECT_EQ(expected_error, GetCapturedStderr());
4744 }
4745 
TEST_F(AidlTest,ImmutableParcelableCannotBeInOut)4746 TEST_F(AidlTest, ImmutableParcelableCannotBeInOut) {
4747   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
4748   io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(inout Foo foo); }");
4749   string expected_error =
4750       "ERROR: IBar.aidl:1.35-39: 'foo' can't be an inout parameter because @JavaOnlyImmutable can "
4751       "only be an in parameter.\n";
4752   CaptureStderr();
4753   Options options = Options::From("aidl --lang=java IBar.aidl -I .");
4754   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4755   EXPECT_EQ(expected_error, GetCapturedStderr());
4756 }
4757 
TEST_F(AidlTest,ImmutableParcelableCannotBeOut)4758 TEST_F(AidlTest, ImmutableParcelableCannotBeOut) {
4759   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
4760   io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(out Foo foo); }");
4761   string expected_error =
4762       "ERROR: IBar.aidl:1.33-37: 'foo' can't be an out parameter because @JavaOnlyImmutable can "
4763       "only be an in parameter.\n";
4764   CaptureStderr();
4765   Options options = Options::From("aidl --lang=java IBar.aidl -I .");
4766   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4767   EXPECT_EQ(expected_error, GetCapturedStderr());
4768 }
4769 
TEST_F(AidlTest,ImmutableParcelableFieldNameRestriction)4770 TEST_F(AidlTest, ImmutableParcelableFieldNameRestriction) {
4771   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; int A; }");
4772   Options options = Options::From("aidl -I . --lang=java Foo.aidl");
4773   const string expected_stderr =
4774       "ERROR: Foo.aidl:1.47-49: 'Foo' has duplicate field name 'A' after capitalizing the first "
4775       "letter\n";
4776   CaptureStderr();
4777   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4778   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4779 }
4780 
TEST_P(AidlTest,UnionInUnion)4781 TEST_P(AidlTest, UnionInUnion) {
4782   import_paths_.insert(".");
4783   io_delegate_.SetFileContents("Bar.aidl", "union Bar { int n = 42; long l; }");
4784   CaptureStderr();
4785   EXPECT_NE(nullptr, Parse("Foo.aidl", "union Foo { Bar b; int n; }", typenames_, GetLanguage()));
4786   EXPECT_THAT("", GetCapturedStderr());
4787 }
4788 
TEST_P(AidlTest,UnionRejectsEmptyDecl)4789 TEST_P(AidlTest, UnionRejectsEmptyDecl) {
4790   const string method = "package a; union Foo {}";
4791   const string expected_stderr = "ERROR: a/Foo.aidl:1.17-21: The union 'Foo' has no fields.\n";
4792   CaptureStderr();
4793   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
4794   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
4795 }
4796 
TEST_P(AidlTest,UnionRejectsParcelableHolder)4797 TEST_P(AidlTest, UnionRejectsParcelableHolder) {
4798   const string method = "package a; union Foo { ParcelableHolder x; }";
4799   const string expected_stderr =
4800       "ERROR: a/Foo.aidl:1.40-42: A union can't have a member of ParcelableHolder 'x'\n";
4801   CaptureStderr();
4802   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
4803   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
4804 }
4805 
TEST_P(AidlTest,UnionRejectsFirstEnumWithNoDefaults)4806 TEST_P(AidlTest, UnionRejectsFirstEnumWithNoDefaults) {
4807   import_paths_.insert(".");
4808   io_delegate_.SetFileContents("a/Enum.aidl", "package a; enum Enum { FOO, BAR }");
4809   const string expected_err = "The union's first member should have a useful default value.";
4810   CaptureStderr();
4811   EXPECT_EQ(nullptr,
4812             Parse("a/Foo.aidl", "package a; union Foo { a.Enum e; }", typenames_, GetLanguage()));
4813   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_err));
4814 }
4815 
TEST_P(AidlTest,GenericStructuredParcelable)4816 TEST_P(AidlTest, GenericStructuredParcelable) {
4817   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T, U> { int a; int A; }");
4818   Options options = Options::From("aidl -I . Foo.aidl --lang=" + to_string(GetLanguage()));
4819   const string expected_stderr = "";
4820   CaptureStderr();
4821   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4822   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4823 }
4824 
TEST_F(AidlTest,GenericStructuredParcelableWithStringConstants_Cpp)4825 TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Cpp) {
4826   io_delegate_.SetFileContents("Foo.aidl",
4827                                "parcelable Foo<T, U> { int a; const String s = \"\"; }");
4828   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(Options::Language::CPP) +
4829                                   " -o out -h out");
4830   const string expected_stderr = "";
4831   CaptureStderr();
4832   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4833   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4834 
4835   string code;
4836   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
4837   EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
4838 const ::android::String16& Foo<T,U>::s() {
4839   static const ::android::String16 value(::android::String16(""));
4840   return value;
4841 })--"));
4842 }
4843 
TEST_F(AidlTest,GenericStructuredParcelableWithStringConstants_Ndk)4844 TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Ndk) {
4845   io_delegate_.SetFileContents("Foo.aidl",
4846                                "parcelable Foo<T, U> { int a; const String s = \"\"; }");
4847   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(Options::Language::NDK) +
4848                                   " -o out -h out");
4849   const string expected_stderr = "";
4850   CaptureStderr();
4851   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4852   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4853 
4854   string code;
4855   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
4856   EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
4857 const char* Foo<T, U>::s = "";
4858 )--"));
4859 }
4860 
TEST_F(AidlTest,NestedTypeArgs)4861 TEST_F(AidlTest, NestedTypeArgs) {
4862   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<A> { }");
4863   io_delegate_.SetFileContents("a/Baz.aidl", "package a; parcelable Baz<A, B> { }");
4864 
4865   io_delegate_.SetFileContents("a/Foo.aidl",
4866                                "package a; import a.Bar; import a.Baz; parcelable Foo { "
4867                                "Baz<Bar<Bar<String[]>>[], Bar<String>> barss; }");
4868   Options options = Options::From("aidl a/Foo.aidl -I . -o out --lang=java");
4869   const string expected_stderr = "";
4870   CaptureStderr();
4871   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4872   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4873 
4874   string code;
4875   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
4876   EXPECT_THAT(code,
4877               testing::HasSubstr(
4878                   "a.Baz<a.Bar<a.Bar<java.lang.String[]>>[],a.Bar<java.lang.String>> barss;"));
4879 }
4880 
TEST_F(AidlTest,AcceptMultiDimensionalFixedSizeArray)4881 TEST_F(AidlTest, AcceptMultiDimensionalFixedSizeArray) {
4882   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[2][3] a; }");
4883 
4884   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=ndk");
4885   CaptureStderr();
4886   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4887   EXPECT_EQ("", GetCapturedStderr());
4888 }
4889 
TEST_F(AidlTest,AcceptBinarySizeArray)4890 TEST_F(AidlTest, AcceptBinarySizeArray) {
4891   io_delegate_.SetFileContents(
4892       "a/Bar.aidl", "package a; parcelable Bar { const int CONST = 3; String[CONST + 1] a; }");
4893 
4894   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=ndk");
4895   CaptureStderr();
4896   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4897   EXPECT_EQ("", GetCapturedStderr());
4898 }
4899 
TEST_F(AidlTest,AcceptRefSizeArray)4900 TEST_F(AidlTest, AcceptRefSizeArray) {
4901   io_delegate_.SetFileContents(
4902       "a/Bar.aidl", "package a; parcelable Bar { const int CONST = 3; String[CONST] a; }");
4903 
4904   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=ndk");
4905   CaptureStderr();
4906   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4907   EXPECT_EQ("", GetCapturedStderr());
4908 }
4909 
TEST_F(AidlTest,RejectArrayOfFixedSizeArray)4910 TEST_F(AidlTest, RejectArrayOfFixedSizeArray) {
4911   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[2][] a; }");
4912 
4913   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4914   CaptureStderr();
4915   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4916   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Multi-dimensional arrays must be fixed size."));
4917 }
4918 
TEST_F(AidlTest,RejectFixedSizeArrayOfDynamicArray)4919 TEST_F(AidlTest, RejectFixedSizeArrayOfDynamicArray) {
4920   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[][3] a; }");
4921 
4922   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4923   CaptureStderr();
4924   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4925   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Multi-dimensional arrays must be fixed size."));
4926 }
4927 
TEST_F(AidlTest,RejectArrayOfArray)4928 TEST_F(AidlTest, RejectArrayOfArray) {
4929   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[][] a; }");
4930 
4931   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4932   CaptureStderr();
4933   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4934   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Multi-dimensional arrays must be fixed size."));
4935 }
4936 
TEST_F(AidlTest,RejectInvalidArraySize_Negative)4937 TEST_F(AidlTest, RejectInvalidArraySize_Negative) {
4938   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[-1] a; }");
4939 
4940   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4941   CaptureStderr();
4942   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4943   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Array size must be a positive number"));
4944 }
4945 
TEST_F(AidlTest,RejectInvalidArraySize_WrongType)4946 TEST_F(AidlTest, RejectInvalidArraySize_WrongType) {
4947   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[\"3\"] a; }");
4948 
4949   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4950   CaptureStderr();
4951   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4952   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Array size must be a positive number"));
4953 }
4954 
TEST_F(AidlTest,DoubleGenericError)4955 TEST_F(AidlTest, DoubleGenericError) {
4956   io_delegate_.SetFileContents("a/Bar.aidl",
4957                                "package a; parcelable Bar { List<String><String> a; }");
4958 
4959   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4960   const string expected_stderr =
4961       "ERROR: a/Bar.aidl:1.28-33: Can only specify one set of type parameters.\n";
4962   CaptureStderr();
4963   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4964   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4965 }
4966 
TEST_F(AidlTest,ArrayBeforeGenericError)4967 TEST_F(AidlTest, ArrayBeforeGenericError) {
4968   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { List[]<String> a; }");
4969 
4970   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4971   CaptureStderr();
4972   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4973   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("syntax error, unexpected '<'"));
4974 }
4975 
TEST_F(AidlTest,NullableArraysAreNotSupported)4976 TEST_F(AidlTest, NullableArraysAreNotSupported) {
4977   io_delegate_.SetFileContents("a/Bar.aidl",
4978                                "package a; parcelable Bar { String @nullable [] a; }");
4979 
4980   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4981   CaptureStderr();
4982   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4983   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("Annotations for arrays are not supported."));
4984 }
4985 
TEST_F(AidlTest,ListOfNullablesAreNotSupported)4986 TEST_F(AidlTest, ListOfNullablesAreNotSupported) {
4987   io_delegate_.SetFileContents("a/Bar.aidl",
4988                                "package a; parcelable Bar { List<@nullable String> a; }");
4989 
4990   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4991   CaptureStderr();
4992   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4993   EXPECT_THAT(GetCapturedStderr(),
4994               testing::HasSubstr("Annotations for type arguments are not supported."));
4995 }
4996 
TEST_F(AidlTest,DefaultShouldMatchWithFixedSizeArray)4997 TEST_F(AidlTest, DefaultShouldMatchWithFixedSizeArray) {
4998   io_delegate_.SetFileContents("a/Bar.aidl",
4999                                "package a;\n"
5000                                "parcelable Bar {\n"
5001                                "  int[2][3] a = {{1,2,3}, {4,5,6}};\n"
5002                                "}");
5003 
5004   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=ndk");
5005   CaptureStderr();
5006   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5007   EXPECT_EQ("", GetCapturedStderr());
5008 }
5009 
TEST_F(AidlTest,FixedSizeArrayWithWrongTypeDefaultValue)5010 TEST_F(AidlTest, FixedSizeArrayWithWrongTypeDefaultValue) {
5011   io_delegate_.SetFileContents("a/Bar.aidl",
5012                                "package a;\n"
5013                                "parcelable Bar {\n"
5014                                "  int[2][3] a = {{\"1\",\"2\",\"3\"}, {4,5,6}};\n"
5015                                "}");
5016 
5017   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
5018   CaptureStderr();
5019   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5020   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Invalid type specifier for a literal string: int"));
5021 }
5022 
TEST_F(AidlTest,FixedSizeArrayWithMoreElements)5023 TEST_F(AidlTest, FixedSizeArrayWithMoreElements) {
5024   io_delegate_.SetFileContents("a/Bar.aidl",
5025                                "package a;\n"
5026                                "parcelable Bar {\n"
5027                                "  int[2][3] a = {{1,2,3,4}, {4,5,6}};\n"
5028                                "}");
5029 
5030   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
5031   CaptureStderr();
5032   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5033   EXPECT_THAT(GetCapturedStderr(),
5034               HasSubstr("Expected an array of 3 elements, but found one with 4 elements"));
5035 }
5036 
TEST_F(AidlTest,FixedSizeArrayWithFewerElements)5037 TEST_F(AidlTest, FixedSizeArrayWithFewerElements) {
5038   io_delegate_.SetFileContents("a/Bar.aidl",
5039                                "package a;\n"
5040                                "parcelable Bar {\n"
5041                                "  int[2][3] a = {};\n"
5042                                "}");
5043 
5044   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
5045   CaptureStderr();
5046   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5047   EXPECT_THAT(GetCapturedStderr(),
5048               HasSubstr("Expected an array of 2 elements, but found one with 0 elements"));
5049 }
5050 
5051 struct GenericAidlTest : ::testing::Test {
5052   FakeIoDelegate io_delegate_;
Compileandroid::aidl::GenericAidlTest5053   void Compile(string cmd) {
5054     io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { Bar<Baz<Qux>> x; }");
5055     io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar<T> {  }");
5056     io_delegate_.SetFileContents("Baz.aidl", "parcelable Baz<T> {  }");
5057     io_delegate_.SetFileContents("Qux.aidl", "parcelable Qux {  }");
5058 
5059     Options options = Options::From(cmd);
5060     CaptureStderr();
5061     EXPECT_TRUE(compile_aidl(options, io_delegate_));
5062     EXPECT_EQ("", GetCapturedStderr());
5063   }
5064 };
5065 
TEST_F(GenericAidlTest,ImportGenericParameterTypesCPP)5066 TEST_F(GenericAidlTest, ImportGenericParameterTypesCPP) {
5067   Compile("aidl Foo.aidl --lang=cpp -I . -o out -h out");
5068   string code;
5069   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
5070   EXPECT_THAT(code, testing::HasSubstr("#include <Bar.h>"));
5071   EXPECT_THAT(code, testing::HasSubstr("#include <Baz.h>"));
5072   EXPECT_THAT(code, testing::HasSubstr("#include <Qux.h>"));
5073 }
5074 
TEST_F(GenericAidlTest,ImportGenericParameterTypesNDK)5075 TEST_F(GenericAidlTest, ImportGenericParameterTypesNDK) {
5076   Compile("aidl Foo.aidl --lang=ndk -I . -o out -h out");
5077   string code;
5078   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
5079   EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Bar.h>"));
5080   EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Baz.h>"));
5081   EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Qux.h>"));
5082 }
5083 
TEST_P(AidlTest,RejectGenericStructuredParcelabelRepeatedParam)5084 TEST_P(AidlTest, RejectGenericStructuredParcelabelRepeatedParam) {
5085   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { int a; int A; }");
5086   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
5087   const string expected_stderr =
5088       "ERROR: Foo.aidl:1.11-15: Every type parameter should be unique.\n";
5089   CaptureStderr();
5090   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5091   EXPECT_EQ(expected_stderr, GetCapturedStderr());
5092 }
5093 
TEST_P(AidlTest,RejectGenericStructuredParcelableField)5094 TEST_P(AidlTest, RejectGenericStructuredParcelableField) {
5095   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { T a; int A; }");
5096   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
5097   const string expected_stderr =
5098       "ERROR: Foo.aidl: Couldn't find import for class T. Searched here:\n - ./\nERROR: "
5099       "Foo.aidl:1.22-24: Failed to resolve 'T'\n";
5100   CaptureStderr();
5101   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5102   EXPECT_EQ(expected_stderr, GetCapturedStderr());
5103 }
5104 
TEST_P(AidlTest,LongCommentWithinConstExpression)5105 TEST_P(AidlTest, LongCommentWithinConstExpression) {
5106   io_delegate_.SetFileContents("Foo.aidl", "enum Foo { FOO = (1 << 1) /* comment */ | 0x0 }");
5107   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
5108   CaptureStderr();
5109   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5110   EXPECT_EQ("", GetCapturedStderr());
5111 }
5112 
TEST_F(AidlTest,RejectUntypdeListAndMapInUnion)5113 TEST_F(AidlTest, RejectUntypdeListAndMapInUnion) {
5114   io_delegate_.SetFileContents("a/Foo.aidl", "package a; union Foo { List l; Map m; }");
5115   Options options = Options::From("aidl a/Foo.aidl -I . --lang=java -o out");
5116   std::string expectedErr =
5117       "ERROR: a/Foo.aidl:1.28-30: "
5118       "Encountered an untyped List or Map. The use of untyped List/Map is "
5119       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
5120       "the receiving side. Consider switching to an array or a generic List/Map.\n"
5121       "ERROR: a/Foo.aidl:1.35-37: "
5122       "Encountered an untyped List or Map. The use of untyped List/Map is "
5123       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
5124       "the receiving side. Consider switching to an array or a generic List/Map.\n";
5125   CaptureStderr();
5126   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5127   EXPECT_EQ(expectedErr, GetCapturedStderr());
5128 }
5129 
TEST_F(AidlTest,RejectUntypdeListAndMapInUnstructuredParcelable)5130 TEST_F(AidlTest, RejectUntypdeListAndMapInUnstructuredParcelable) {
5131   io_delegate_.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { List l; Map m; }");
5132   Options options = Options::From("aidl a/Foo.aidl -I . --lang=java -o out");
5133   std::string expectedErr =
5134       "ERROR: a/Foo.aidl:1.33-35: "
5135       "Encountered an untyped List or Map. The use of untyped List/Map is "
5136       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
5137       "the receiving side. Consider switching to an array or a generic List/Map.\n"
5138       "ERROR: a/Foo.aidl:1.40-42: "
5139       "Encountered an untyped List or Map. The use of untyped List/Map is "
5140       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
5141       "the receiving side. Consider switching to an array or a generic List/Map.\n";
5142   CaptureStderr();
5143   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5144   EXPECT_EQ(expectedErr, GetCapturedStderr());
5145 }
5146 
TEST_F(AidlTest,RejectNestedUntypedListAndMap)5147 TEST_F(AidlTest, RejectNestedUntypedListAndMap) {
5148   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<T>;");
5149   io_delegate_.SetFileContents(
5150       "a/Foo.aidl", "package a; import a.Bar; parcelable Foo { Bar<List> a; Bar<Map> b; }");
5151   Options options = Options::From("aidl a/Foo.aidl -I . --lang=java -o out");
5152   std::string expectedErr =
5153       "ERROR: a/Foo.aidl:1.52-54: "
5154       "Encountered an untyped List or Map. The use of untyped List/Map is "
5155       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
5156       "the receiving side. Consider switching to an array or a generic List/Map.\n"
5157       "ERROR: a/Foo.aidl:1.64-66: "
5158       "Encountered an untyped List or Map. The use of untyped List/Map is "
5159       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
5160       "the receiving side. Consider switching to an array or a generic List/Map.\n";
5161   CaptureStderr();
5162   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5163   EXPECT_EQ(expectedErr, GetCapturedStderr());
5164 }
5165 
TEST_F(AidlTest,EnumWithDefaults_Java)5166 TEST_F(AidlTest, EnumWithDefaults_Java) {
5167   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
5168   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5169 package p;
5170 import p.Enum;
5171 parcelable Foo {
5172   Enum e = Enum.BAR;
5173 })");
5174   CaptureStderr();
5175   auto options = Options::From("aidl -I a --lang java -o out a/p/Foo.aidl");
5176   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5177   auto err = GetCapturedStderr();
5178   EXPECT_EQ("", err);
5179 
5180   string code;
5181   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.java", &code));
5182   EXPECT_THAT(code, testing::HasSubstr("byte e = p.Enum.BAR"));
5183 }
5184 
TEST_F(AidlTest,EnumWithDefaults_Cpp)5185 TEST_F(AidlTest, EnumWithDefaults_Cpp) {
5186   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
5187   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5188 package p;
5189 import p.Enum;
5190 parcelable Foo {
5191   Enum e = Enum.BAR;
5192 })");
5193   CaptureStderr();
5194   auto options = Options::From("aidl -I a --lang cpp -o out -h out a/p/Foo.aidl");
5195   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5196   auto err = GetCapturedStderr();
5197   EXPECT_EQ("", err);
5198 
5199   string code;
5200   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.h", &code));
5201   EXPECT_THAT(code, testing::HasSubstr("::p::Enum e = ::p::Enum::BAR;"));
5202 }
5203 
TEST_F(AidlTest,EnumWithDefaults_Ndk)5204 TEST_F(AidlTest, EnumWithDefaults_Ndk) {
5205   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
5206   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5207 package p;
5208 import p.Enum;
5209 parcelable Foo {
5210   Enum e = Enum.BAR;
5211 })");
5212   CaptureStderr();
5213   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5214   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5215   auto err = GetCapturedStderr();
5216   EXPECT_EQ("", err);
5217 
5218   string code;
5219   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
5220   EXPECT_THAT(code, testing::HasSubstr("::aidl::p::Enum e = ::aidl::p::Enum::BAR;"));
5221 }
5222 
TEST_F(AidlTest,EnumWithDefaults_Rust)5223 TEST_F(AidlTest, EnumWithDefaults_Rust) {
5224   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
5225   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5226 package p;
5227 import p.Enum;
5228 parcelable Foo {
5229   int  n = 42;
5230   Enum e = Enum.BAR;
5231 })");
5232   CaptureStderr();
5233   auto options = Options::From("aidl -I a --lang rust -o out -h out a/p/Foo.aidl");
5234   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5235   auto err = GetCapturedStderr();
5236   EXPECT_EQ("", err);
5237 
5238   string code;
5239   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.rs", &code));
5240   EXPECT_THAT(code, testing::HasSubstr(R"(
5241   fn default() -> Self {
5242     Self {
5243       r#n: 42,
5244       r#e: crate::mangled::_1_p_4_Enum::BAR,
5245     }
5246   })"));
5247 }
5248 
TEST_P(AidlTest,EnumeratorIsConstantValue_DefaultValue)5249 TEST_P(AidlTest, EnumeratorIsConstantValue_DefaultValue) {
5250   import_paths_.insert("a");
5251   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
5252   CaptureStderr();
5253   const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
5254 package p;
5255 import p.Enum;
5256 parcelable Foo {
5257   int e = Enum.FOO | Enum.BAR;
5258 })",
5259                                       typenames_, GetLanguage());
5260   auto err = GetCapturedStderr();
5261   EXPECT_EQ("", err);
5262   EXPECT_TRUE(type);
5263   const auto& fields = type->AsStructuredParcelable()->GetFields();
5264   EXPECT_EQ("int e = 3", fields[0]->ToString());
5265 }
5266 
TEST_F(AidlTest,EnumeratorIsConstantValue_CanDefineOtherEnumerator)5267 TEST_F(AidlTest, EnumeratorIsConstantValue_CanDefineOtherEnumerator) {
5268   CaptureStderr();
5269   const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
5270 package a.p;
5271 @Backing(type="int")
5272 enum Foo {
5273       STANDARD_SHIFT = 16,
5274       STANDARD_BT709 = 1 << STANDARD_SHIFT,
5275       STANDARD_BT601_625 = 2 << STANDARD_SHIFT,
5276 }
5277 )",
5278                                       typenames_, Options::Language::JAVA);
5279   auto err = GetCapturedStderr();
5280   EXPECT_EQ("", err);
5281   ASSERT_NE(type, nullptr);
5282   const auto& enum_type = type->AsEnumDeclaration();
5283   string code;
5284   auto writer = CodeWriter::ForString(&code);
5285   DumpVisitor visitor(*writer, /*inline_constants=*/true);
5286   visitor.Visit(*enum_type);
5287   writer->Close();
5288   EXPECT_EQ(R"--(@Backing(type="int")
5289 enum Foo {
5290   STANDARD_SHIFT = 16,
5291   STANDARD_BT709 = 65536,
5292   STANDARD_BT601_625 = 131072,
5293 }
5294 )--",
5295             code);
5296 }
5297 
TEST_F(AidlTest,DumpApiWithConstantReferences)5298 TEST_F(AidlTest, DumpApiWithConstantReferences) {
5299   io_delegate_.SetFileContents("foo/bar/Foo.aidl", R"(
5300 package foo.bar;
5301 import foo.bar.Bar;
5302 import foo.bar.Enum;
5303 parcelable Foo {
5304   int n = Bar.A + 1;
5305   int[] ns = {1, Bar.A, Bar.B + 1};
5306   Enum e = Enum.A;
5307   Enum[] es = {Enum.A, Enum.B};
5308 }
5309 )");
5310   io_delegate_.SetFileContents("foo/bar/Bar.aidl", R"(
5311 package foo.bar;
5312 parcelable Bar {
5313   const int A = 1;
5314   const int B = A + 1;
5315 }
5316 )");
5317   io_delegate_.SetFileContents("foo/bar/Enum.aidl", R"(
5318 package foo.bar;
5319 enum Enum {
5320   A,
5321   B = A + 2,
5322 }
5323 )");
5324   vector<string> args = {"aidl",
5325                          "--dumpapi",
5326                          "--out=dump",
5327                          "--include=.",
5328                          "foo/bar/Foo.aidl",
5329                          "foo/bar/Bar.aidl",
5330                          "foo/bar/Enum.aidl"};
5331   ASSERT_TRUE(dump_api(Options::From(args), io_delegate_));
5332 
5333   string actual;
5334   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
5335   EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
5336 parcelable Foo {
5337   int n = (foo.bar.Bar.A + 1) /* 2 */;
5338   int[] ns = {1, foo.bar.Bar.A /* 1 */, (foo.bar.Bar.B + 1) /* 3 */};
5339   foo.bar.Enum e = foo.bar.Enum.A;
5340   foo.bar.Enum[] es = {foo.bar.Enum.A, foo.bar.Enum.B};
5341 }
5342 )"),
5343             actual);
5344   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Bar.aidl", &actual));
5345   EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
5346 parcelable Bar {
5347   const int A = 1;
5348   const int B = (A + 1) /* 2 */;
5349 }
5350 )"),
5351             actual);
5352   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Enum.aidl", &actual));
5353   EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
5354 enum Enum {
5355   A,
5356   B = (A + 2) /* 2 */,
5357 }
5358 )"),
5359             actual);
5360 }
5361 
TEST_F(AidlTest,EnumDefaultShouldBeEnumerators)5362 TEST_F(AidlTest, EnumDefaultShouldBeEnumerators) {
5363   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
5364   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5365 package p;
5366 import p.Enum;
5367 parcelable Foo {
5368   Enum e = Enum.FOO | Enum.BAR;
5369 })");
5370   CaptureStderr();
5371   auto options = Options::From("aidl -I a --lang java -o out -h out a/p/Foo.aidl");
5372   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5373   auto err = GetCapturedStderr();
5374   EXPECT_EQ("ERROR: a/p/Foo.aidl:5.11-20: Invalid value (Enum.FOO|Enum.BAR) for enum p.Enum\n",
5375             err);
5376 }
5377 
TEST_F(AidlTest,EnumDefaultShouldBeEnumerators_RejectsNumericValue)5378 TEST_F(AidlTest, EnumDefaultShouldBeEnumerators_RejectsNumericValue) {
5379   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
5380   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5381 package p;
5382 import p.Enum;
5383 parcelable Foo {
5384   Enum e = 1;
5385 })");
5386   CaptureStderr();
5387   auto options = Options::From("aidl -I a --lang java -o out -h out a/p/Foo.aidl");
5388   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5389   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Invalid value (1) for enum p.Enum"));
5390 }
5391 
TEST_P(AidlTest,DefaultWithEmptyArray)5392 TEST_P(AidlTest, DefaultWithEmptyArray) {
5393   io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; parcelable Foo { p.Bar[] bars = {}; }");
5394   io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; parcelable Bar { }");
5395   CaptureStderr();
5396   auto options =
5397       Options::From("aidl -I a --lang " + to_string(GetLanguage()) + " -o out -h out a/p/Foo.aidl");
5398   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5399   auto err = GetCapturedStderr();
5400   EXPECT_EQ("", err);
5401 }
5402 
TEST_P(AidlTest,RejectRefsInAnnotation)5403 TEST_P(AidlTest, RejectRefsInAnnotation) {
5404   io_delegate_.SetFileContents("a/p/IFoo.aidl",
5405                                "package p; interface IFoo {\n"
5406                                "  const String ANNOTATION = \"@Annotation\";\n"
5407                                "  @JavaPassthrough(annotation=ANNOTATION) void foo();\n"
5408                                "}");
5409   CaptureStderr();
5410   auto options = Options::From("aidl -I a --lang " + to_string(GetLanguage()) +
5411                                " -o out -h out a/p/IFoo.aidl");
5412   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5413   auto err = GetCapturedStderr();
5414   EXPECT_EQ(
5415       "ERROR: a/p/IFoo.aidl:3.31-41: Value must be a constant expression but contains reference to "
5416       "ANNOTATION.\n",
5417       err);
5418 }
5419 
TEST_F(AidlTest,DefaultWithEnumValues)5420 TEST_F(AidlTest, DefaultWithEnumValues) {
5421   io_delegate_.SetFileContents(
5422       "a/p/Foo.aidl",
5423       "package p; import p.Bar; parcelable Foo { Bar[] bars = { Bar.FOO, Bar.FOO }; }");
5424   io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; enum Bar { FOO, BAR }");
5425   CaptureStderr();
5426   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5427   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5428   auto err = GetCapturedStderr();
5429   EXPECT_EQ("", err);
5430   string code;
5431   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
5432   EXPECT_THAT(
5433       code, testing::HasSubstr(
5434                 "std::vector<::aidl::p::Bar> bars = {::aidl::p::Bar::FOO, ::aidl::p::Bar::FOO};"));
5435 }
5436 
TEST_F(AidlTest,RejectsCircularReferencingEnumerators)5437 TEST_F(AidlTest, RejectsCircularReferencingEnumerators) {
5438   io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; enum Foo { A = B, B }");
5439   CaptureStderr();
5440   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5441   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5442   auto err = GetCapturedStderr();
5443   EXPECT_EQ("ERROR: a/p/Foo.aidl:1.26-28: Found a circular reference: B -> A -> B\n", err);
5444 }
5445 
TEST_F(AidlTest,RejectsCircularReferencingConsts)5446 TEST_F(AidlTest, RejectsCircularReferencingConsts) {
5447   io_delegate_.SetFileContents("a/p/Foo.aidl",
5448                                "package p; parcelable Foo { const int A = A + 1; }");
5449   CaptureStderr();
5450   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5451   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5452   auto err = GetCapturedStderr();
5453   EXPECT_EQ("ERROR: a/p/Foo.aidl:1.42-44: Found a circular reference: A -> A\n", err);
5454 }
5455 
TEST_F(AidlTest,RecursiveReferences)5456 TEST_F(AidlTest, RecursiveReferences) {
5457   io_delegate_.SetFileContents("a/p/Foo.aidl",
5458                                "package p; parcelable Foo { const int A = p.Bar.A + 1; }");
5459   io_delegate_.SetFileContents("a/p/Bar.aidl",
5460                                "package p; parcelable Bar { const int A = p.Baz.A + 1; }");
5461   io_delegate_.SetFileContents("a/p/Baz.aidl", "package p; parcelable Baz { const int A = 1; }");
5462   CaptureStderr();
5463   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5464   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5465   EXPECT_EQ("", GetCapturedStderr());
5466 }
5467 
TEST_P(AidlTest,CircularReferenceWithFullyQualified)5468 TEST_P(AidlTest, CircularReferenceWithFullyQualified) {
5469   io_delegate_.SetFileContents("Foo.aidl", "enum Foo { A = Foo.A }");
5470   auto options =
5471       Options::From("aidl --lang " + to_string(GetLanguage()) + " -I . -o out -h out Foo.aidl");
5472   const string err = "ERROR: Foo.aidl:1.15-21: Found a circular reference: Foo.A -> Foo.A\n";
5473   CaptureStderr();
5474   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5475   EXPECT_EQ(err, GetCapturedStderr());
5476 }
5477 
TEST_P(AidlTest,ConstRefsCanPointToTheSameValue)5478 TEST_P(AidlTest, ConstRefsCanPointToTheSameValue) {
5479   io_delegate_.SetFileContents("Foo.aidl", "enum Foo { A = 0 }");
5480   // this demonstrates the case that "Foo.A" const-ref node is visited twice by B and C.
5481   io_delegate_.SetFileContents("Bar.aidl", "enum Bar { A = Foo.A, B = A, C = A }");
5482   auto options =
5483       Options::From("aidl --lang " + to_string(GetLanguage()) + " -I . -o out -h out Bar.aidl");
5484   CaptureStderr();
5485   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5486   EXPECT_EQ("", GetCapturedStderr());
5487 }
5488 
TEST_P(AidlTest,UnknownConstReference)5489 TEST_P(AidlTest, UnknownConstReference) {
5490   io_delegate_.SetFileContents("Foo.aidl", " parcelable Foo { int field = UNKNOWN_REF; }");
5491   auto options =
5492       Options::From("aidl -I . --lang " + to_string(GetLanguage()) + " -o out -h out Foo.aidl");
5493   const string err =
5494       "ERROR: Foo.aidl:1.30-42: Can't find UNKNOWN_REF in Foo\n"
5495       "ERROR: Foo.aidl:1.30-42: Unknown reference 'UNKNOWN_REF'\n";
5496   CaptureStderr();
5497   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5498   EXPECT_EQ(err, GetCapturedStderr());
5499 }
5500 
TEST_P(AidlTest,JavaCompatibleBuiltinTypes)5501 TEST_P(AidlTest, JavaCompatibleBuiltinTypes) {
5502   string contents = R"(
5503 import android.os.IBinder;
5504 import android.os.IInterface;
5505 interface IFoo {}
5506   )";
5507   EXPECT_NE(nullptr, Parse("IFoo.aidl", contents, typenames_, GetLanguage()));
5508 }
5509 
TEST_P(AidlTest,WarningInterfaceName)5510 TEST_P(AidlTest, WarningInterfaceName) {
5511   io_delegate_.SetFileContents("p/Foo.aidl", "package p; interface Foo {}");
5512   auto options = Options::From("aidl -I . --lang " + to_string(GetLanguage()) +
5513                                " -Winterface-name -o out -h out p/Foo.aidl");
5514   CaptureStderr();
5515   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5516   EXPECT_EQ(
5517       "WARNING: p/Foo.aidl:1.11-21: Interface names should start with I. [-Winterface-name]\n",
5518       GetCapturedStderr());
5519 }
5520 
TEST_P(AidlTest,ErrorInterfaceName)5521 TEST_P(AidlTest, ErrorInterfaceName) {
5522   io_delegate_.SetFileContents("p/Foo.aidl", "package p; interface Foo {}");
5523   auto options = Options::From("aidl -I . --lang " + to_string(GetLanguage()) +
5524                                " -Winterface-name -Werror -o out -h out p/Foo.aidl");
5525   CaptureStderr();
5526   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5527   EXPECT_EQ("ERROR: p/Foo.aidl:1.11-21: Interface names should start with I. [-Winterface-name]\n",
5528             GetCapturedStderr());
5529 }
5530 
TEST_F(AidlTest,RejectsIncorrectOutputFilePathOnLegacyCppInput)5531 TEST_F(AidlTest, RejectsIncorrectOutputFilePathOnLegacyCppInput) {
5532   const std::string input_file = "base/p/q/IFoo.aidl";
5533   const std::string header_dir = "out/";
5534   const std::string output_file = "out/base/p/q/IFoo.cpp";
5535   io_delegate_.SetFileContents(input_file, "package p.q; interface IFoo {}");
5536 
5537   auto options = Options::From({"aidl-cpp", "-I base", input_file, header_dir, output_file});
5538   CaptureStderr();
5539   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5540   EXPECT_THAT(
5541       GetCapturedStderr(),
5542       testing::StartsWith(
5543           "ERROR: base/p/q/IFoo.aidl:1.13-23: Output file is expected to be at out/p/q/IFoo.cpp, "
5544           "but is out/base/p/q/IFoo.cpp."));
5545 }
5546 
TEST_F(AidlTest,FormatCommentsForJava)5547 TEST_F(AidlTest, FormatCommentsForJava) {
5548   using android::aidl::FormatCommentsForJava;
5549 
5550   struct TestCase {
5551     vector<Comment> comments;
5552     string formatted;
5553   };
5554   vector<TestCase> testcases = {
5555       {{}, ""},
5556       {{{"// line comments\n"}}, "// line comments\n"},
5557       {{{"// @hide \n"}}, "// @hide \n"},
5558       // Transform the last block comment as Javadoc.
5559       {{{"/*\n"
5560          " * Hello, world!\n"
5561          " */"}},
5562        "/** Hello, world! */\n"},
5563       {{{"/* @hide */"}}, "/** @hide */\n"},
5564       {{{"/**\n"
5565          "   @param foo ...\n"
5566          "*/"}},
5567        "/** @param foo ... */\n"},
5568       {{{"/* @hide */"}, {"/* @hide */"}}, "/* @hide */\n/** @hide */\n"},
5569       {{{"/* @deprecated first */"}, {"/* @deprecated second */"}},
5570        "/* @deprecated first */\n/** @deprecated second */\n"},
5571       {{{"/* @deprecated */"}, {"/** @param foo */"}}, "/* @deprecated */\n/** @param foo */\n"},
5572       // Line comments are printed as they are
5573       {{{"/* @deprecated */"}, {"// line comments\n"}}, "/* @deprecated */\n// line comments\n"},
5574   };
5575   for (const auto& [input, formatted] : testcases) {
5576     EXPECT_EQ(formatted, FormatCommentsForJava(input));
5577   }
5578 }
5579 
TEST_F(AidlTest,SuppressWarningsIsNotForArgs)5580 TEST_F(AidlTest, SuppressWarningsIsNotForArgs) {
5581   io_delegate_.SetFileContents(
5582       "IFoo.aidl",
5583       "interface IFoo {\n"
5584       "  void foo(in @SuppressWarnings(value={\"inout-parameter\"}) int x);\n"
5585       "}");
5586   auto options = Options::From("aidl -I . --lang=java IFoo.aidl");
5587   CaptureStderr();
5588   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5589   EXPECT_THAT(GetCapturedStderr(), HasSubstr("@SuppressWarnings is not available"));
5590 }
5591 
TEST_F(AidlTest,VoidCantBeUsedInMethodParameterType)5592 TEST_F(AidlTest, VoidCantBeUsedInMethodParameterType) {
5593   io_delegate_.SetFileContents("p/IFoo.aidl", "package p; interface IFoo{ void j(void n);}");
5594   auto options = Options::From("aidl -I . --lang=java -o out p/IFoo.aidl");
5595   CaptureStderr();
5596   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5597   EXPECT_THAT(GetCapturedStderr(), HasSubstr("'void' is an invalid type for the parameter 'n'"));
5598 }
5599 
TEST_F(AidlTest,InterfaceVectorIsAvailableAfterTiramisu)5600 TEST_F(AidlTest, InterfaceVectorIsAvailableAfterTiramisu) {
5601   io_delegate_.SetFileContents("p/IFoo.aidl",
5602                                "package p;\n"
5603                                "interface IFoo{\n"
5604                                "  void foo(in IFoo[] n);\n"
5605                                "  void bar(in List<IFoo> n);\n"
5606                                "}");
5607   CaptureStderr();
5608   EXPECT_FALSE(
5609       compile_aidl(Options::From("aidl -I . --lang=java --min_sdk_version 30 -o out p/IFoo.aidl"),
5610                    io_delegate_));
5611   auto captured_stderr = GetCapturedStderr();
5612   EXPECT_THAT(captured_stderr, HasSubstr("Array of interfaces is available since"));
5613   EXPECT_THAT(captured_stderr, HasSubstr("List of interfaces is available since"));
5614 
5615   CaptureStderr();
5616   EXPECT_TRUE(compile_aidl(
5617       Options::From("aidl -I . --lang=java --min_sdk_version Tiramisu -o out p/IFoo.aidl"),
5618       io_delegate_));
5619   EXPECT_EQ(GetCapturedStderr(), "");
5620 }
5621 
TEST_F(AidlTest,RustNameOf_PfdFixedArray)5622 TEST_F(AidlTest, RustNameOf_PfdFixedArray) {
5623   auto pfd = typenames_.MakeResolvedType(AIDL_LOCATION_HERE, "ParcelFileDescriptor", false);
5624   ASSERT_TRUE(pfd->MakeArray(FixedSizeArray{
5625       std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(AIDL_LOCATION_HERE, "2"))}));
5626   ASSERT_TRUE(pfd->MakeArray(FixedSizeArray{
5627       std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(AIDL_LOCATION_HERE, "3"))}));
5628   EXPECT_EQ(
5629       rust::RustNameOf(*pfd, typenames_, rust::StorageMode::PARCELABLE_FIELD, rust::Lifetime::NONE),
5630       "[[Option<binder::ParcelFileDescriptor>; 3]; 2]");
5631   EXPECT_EQ(
5632       rust::RustNameOf(*pfd, typenames_, rust::StorageMode::DEFAULT_VALUE, rust::Lifetime::NONE),
5633       "[[Option<binder::ParcelFileDescriptor>; 3]; 2]");
5634   EXPECT_EQ(
5635       rust::RustNameOf(*pfd, typenames_, rust::StorageMode::IN_ARGUMENT, rust::Lifetime::NONE),
5636       "&[[binder::ParcelFileDescriptor; 3]; 2]");
5637   EXPECT_EQ(rust::RustNameOf(*pfd, typenames_, rust::StorageMode::VALUE, rust::Lifetime::NONE),
5638             "[[binder::ParcelFileDescriptor; 3]; 2]");
5639 }
5640 
TEST_F(AidlTest,RustNameOf_PfdDynamicArray)5641 TEST_F(AidlTest, RustNameOf_PfdDynamicArray) {
5642   auto pfd = typenames_.MakeResolvedType(AIDL_LOCATION_HERE, "ParcelFileDescriptor", true);
5643   EXPECT_EQ(
5644       rust::RustNameOf(*pfd, typenames_, rust::StorageMode::PARCELABLE_FIELD, rust::Lifetime::NONE),
5645       "Vec<binder::ParcelFileDescriptor>");
5646   EXPECT_EQ(
5647       rust::RustNameOf(*pfd, typenames_, rust::StorageMode::DEFAULT_VALUE, rust::Lifetime::NONE),
5648       "Vec<Option<binder::ParcelFileDescriptor>>");
5649   // we use UNSIZED_ARGUMENT mode for input argument of dynamic array
5650   EXPECT_EQ(
5651       rust::RustNameOf(*pfd, typenames_, rust::StorageMode::UNSIZED_ARGUMENT, rust::Lifetime::NONE),
5652       "&[binder::ParcelFileDescriptor]");
5653   EXPECT_EQ(rust::RustNameOf(*pfd, typenames_, rust::StorageMode::VALUE, rust::Lifetime::NONE),
5654             "Vec<binder::ParcelFileDescriptor>");
5655 }
5656 
5657 struct TypeParam {
5658   string kind;
5659   string literal;
5660 };
5661 
5662 const TypeParam kTypeParams[] = {
5663     {"primitive", "int"},
5664     {"primitiveArray", "int[]"},
5665     {"primitiveFixedArray", "int[3]"},
5666     {"String", "String"},
5667     {"StringArray", "String[]"},
5668     {"IBinder", "IBinder"},
5669     {"ParcelFileDescriptor", "ParcelFileDescriptor"},
5670     {"parcelable", "a.Foo"},
5671     {"enum", "a.Enum"},
5672     {"union", "a.Union"},
5673     {"interface", "a.IBar"},
5674 };
5675 
5676 struct ExpectedResult {
5677   string expected_error;
5678   string expected_error_for_nullable;
5679 };
5680 
5681 const std::map<std::string, ExpectedResult> kListSupportExpectations = {
5682     {"cpp_primitive", {"A generic type cannot", "A generic type cannot"}},
5683     {"java_primitive", {"A generic type cannot", "A generic type cannot"}},
5684     {"ndk_primitive", {"A generic type cannot", "A generic type cannot"}},
5685     {"rust_primitive", {"A generic type cannot", "A generic type cannot"}},
5686     {"cpp_primitiveArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5687     {"java_primitiveArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5688     {"ndk_primitiveArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5689     {"rust_primitiveArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5690     {"cpp_primitiveFixedArray",
5691      {"List of arrays is not supported", "List of arrays is not supported"}},
5692     {"java_primitiveFixedArray",
5693      {"List of arrays is not supported", "List of arrays is not supported"}},
5694     {"ndk_primitiveFixedArray",
5695      {"List of arrays is not supported", "List of arrays is not supported"}},
5696     {"rust_primitiveFixedArray",
5697      {"List of arrays is not supported", "List of arrays is not supported"}},
5698     {"cpp_String", {"", ""}},
5699     {"java_String", {"", ""}},
5700     {"ndk_String", {"", ""}},
5701     {"rust_String", {"", ""}},
5702     {"cpp_StringArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5703     {"java_StringArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5704     {"ndk_StringArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5705     {"rust_StringArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5706     {"cpp_IBinder", {"", ""}},
5707     {"java_IBinder", {"", ""}},
5708     {"ndk_IBinder", {"", ""}},
5709     {"rust_IBinder", {"", ""}},
5710     {"cpp_ParcelFileDescriptor", {"", ""}},
5711     {"java_ParcelFileDescriptor", {"", ""}},
5712     {"ndk_ParcelFileDescriptor", {"", ""}},
5713     {"rust_ParcelFileDescriptor", {"", ""}},
5714     {"cpp_interface", {"", ""}},
5715     {"java_interface", {"", ""}},
5716     {"ndk_interface", {"", ""}},
5717     {"rust_interface", {"", ""}},
5718     {"cpp_parcelable", {"", ""}},
5719     {"java_parcelable", {"", ""}},
5720     {"ndk_parcelable", {"", ""}},
5721     {"rust_parcelable", {"", ""}},
5722     {"cpp_enum", {"A generic type cannot", "A generic type cannot"}},
5723     {"java_enum", {"A generic type cannot", "A generic type cannot"}},
5724     {"ndk_enum", {"A generic type cannot", "A generic type cannot"}},
5725     {"rust_enum", {"A generic type cannot", "A generic type cannot"}},
5726     {"cpp_union", {"", ""}},
5727     {"java_union", {"", ""}},
5728     {"ndk_union", {"", ""}},
5729     {"rust_union", {"", ""}},
5730 };
5731 
5732 const std::map<std::string, ExpectedResult> kArraySupportExpectations = {
5733     {"cpp_primitive", {"", ""}},
5734     {"java_primitive", {"", ""}},
5735     {"ndk_primitive", {"", ""}},
5736     {"rust_primitive", {"", ""}},
5737     {"cpp_primitiveArray",
5738      {"Multi-dimensional arrays must be fixed size.",
5739       "Multi-dimensional arrays must be fixed size."}},
5740     {"java_primitiveArray",
5741      {"Multi-dimensional arrays must be fixed size.",
5742       "Multi-dimensional arrays must be fixed size."}},
5743     {"ndk_primitiveArray",
5744      {"Multi-dimensional arrays must be fixed size.",
5745       "Multi-dimensional arrays must be fixed size."}},
5746     {"rust_primitiveArray",
5747      {"Multi-dimensional arrays must be fixed size.",
5748       "Multi-dimensional arrays must be fixed size."}},
5749     {"cpp_primitiveFixedArray",
5750      {"Multi-dimensional arrays must be fixed size.",
5751       "Multi-dimensional arrays must be fixed size."}},
5752     {"java_primitiveFixedArray",
5753      {"Multi-dimensional arrays must be fixed size.",
5754       "Multi-dimensional arrays must be fixed size."}},
5755     {"ndk_primitiveFixedArray",
5756      {"Multi-dimensional arrays must be fixed size.",
5757       "Multi-dimensional arrays must be fixed size."}},
5758     {"rust_primitiveFixedArray",
5759      {"Multi-dimensional arrays must be fixed size.",
5760       "Multi-dimensional arrays must be fixed size."}},
5761     {"cpp_String", {"", ""}},
5762     {"java_String", {"", ""}},
5763     {"ndk_String", {"", ""}},
5764     {"rust_String", {"", ""}},
5765     {"cpp_StringArray",
5766      {"Multi-dimensional arrays must be fixed size.",
5767       "Multi-dimensional arrays must be fixed size."}},
5768     {"java_StringArray",
5769      {"Multi-dimensional arrays must be fixed size.",
5770       "Multi-dimensional arrays must be fixed size."}},
5771     {"ndk_StringArray",
5772      {"Multi-dimensional arrays must be fixed size.",
5773       "Multi-dimensional arrays must be fixed size."}},
5774     {"rust_StringArray",
5775      {"Multi-dimensional arrays must be fixed size.",
5776       "Multi-dimensional arrays must be fixed size."}},
5777     {"cpp_IBinder", {"", ""}},
5778     {"java_IBinder", {"", ""}},
5779     {"ndk_IBinder", {"", ""}},
5780     {"rust_IBinder", {"", ""}},
5781     {"cpp_ParcelFileDescriptor", {"", ""}},
5782     {"java_ParcelFileDescriptor", {"", ""}},
5783     {"ndk_ParcelFileDescriptor", {"", ""}},
5784     {"rust_ParcelFileDescriptor", {"", ""}},
5785     {"cpp_interface", {"", ""}},
5786     {"java_interface", {"", ""}},
5787     {"ndk_interface", {"", ""}},
5788     {"rust_interface", {"", ""}},
5789     {"cpp_parcelable", {"", ""}},
5790     {"java_parcelable", {"", ""}},
5791     {"ndk_parcelable", {"", ""}},
5792     {"rust_parcelable", {"", ""}},
5793     {"cpp_enum", {"", ""}},
5794     {"java_enum", {"", ""}},
5795     {"ndk_enum", {"", ""}},
5796     {"rust_enum", {"", ""}},
5797     {"cpp_union", {"", ""}},
5798     {"java_union", {"", ""}},
5799     {"ndk_union", {"", ""}},
5800     {"rust_union", {"", ""}},
5801 };
5802 
5803 const std::map<std::string, ExpectedResult> kFieldSupportExpectations = {
5804     {"cpp_primitive", {"", "cannot get nullable annotation"}},
5805     {"java_primitive", {"", "cannot get nullable annotation"}},
5806     {"ndk_primitive", {"", "cannot get nullable annotation"}},
5807     {"rust_primitive", {"", "cannot get nullable annotation"}},
5808     {"cpp_primitiveArray", {"", ""}},
5809     {"java_primitiveArray", {"", ""}},
5810     {"ndk_primitiveArray", {"", ""}},
5811     {"rust_primitiveArray", {"", ""}},
5812     {"cpp_primitiveFixedArray", {"", ""}},
5813     {"java_primitiveFixedArray", {"", ""}},
5814     {"ndk_primitiveFixedArray", {"", ""}},
5815     {"rust_primitiveFixedArray", {"", ""}},
5816     {"cpp_String", {"", ""}},
5817     {"java_String", {"", ""}},
5818     {"ndk_String", {"", ""}},
5819     {"rust_String", {"", ""}},
5820     {"cpp_StringArray", {"", ""}},
5821     {"java_StringArray", {"", ""}},
5822     {"ndk_StringArray", {"", ""}},
5823     {"rust_StringArray", {"", ""}},
5824     {"cpp_IBinder", {"", ""}},
5825     {"java_IBinder", {"", ""}},
5826     {"ndk_IBinder", {"", ""}},
5827     {"rust_IBinder", {"", ""}},
5828     {"cpp_ParcelFileDescriptor", {"", ""}},
5829     {"java_ParcelFileDescriptor", {"", ""}},
5830     {"ndk_ParcelFileDescriptor", {"", ""}},
5831     {"rust_ParcelFileDescriptor", {"", ""}},
5832     {"cpp_interface", {"", ""}},
5833     {"java_interface", {"", ""}},
5834     {"ndk_interface", {"", ""}},
5835     {"rust_interface", {"", ""}},
5836     {"cpp_parcelable", {"", ""}},
5837     {"java_parcelable", {"", ""}},
5838     {"ndk_parcelable", {"", ""}},
5839     {"rust_parcelable", {"", ""}},
5840     {"cpp_enum", {"", "cannot get nullable annotation"}},
5841     {"java_enum", {"", "cannot get nullable annotation"}},
5842     {"ndk_enum", {"", "cannot get nullable annotation"}},
5843     {"rust_enum", {"", "cannot get nullable annotation"}},
5844     {"cpp_union", {"", ""}},
5845     {"java_union", {"", ""}},
5846     {"ndk_union", {"", ""}},
5847     {"rust_union", {"", ""}},
5848 };
5849 
5850 class AidlTypeParamTest
5851     : public testing::TestWithParam<std::tuple<Options::Language, TypeParam, bool>> {
5852  public:
Run(const std::string & generic_type_decl,const std::map<std::string,ExpectedResult> & expectations)5853   void Run(const std::string& generic_type_decl,
5854            const std::map<std::string, ExpectedResult>& expectations) {
5855     const auto& param = GetParam();
5856     const auto& lang = to_string(std::get<0>(param));
5857     const auto& kind = std::get<1>(param).kind;
5858     const bool nullable = std::get<2>(param);
5859 
5860     FakeIoDelegate io;
5861     io.SetFileContents("a/IBar.aidl", "package a; interface IBar { }");
5862     io.SetFileContents("a/Enum.aidl", "package a; enum Enum { A }");
5863     io.SetFileContents("a/Union.aidl", "package a; union Union { int a; }");
5864     io.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { int a; }");
5865     std::string decl = fmt::format(fmt::runtime(generic_type_decl), std::get<1>(param).literal);
5866     if (nullable) {
5867       decl = "@nullable " + decl;
5868     }
5869     io.SetFileContents("a/Target.aidl", "package a; parcelable Target { " + decl + " f; }");
5870 
5871     const auto options = Options::From(fmt::format(
5872         "aidl -I . --min_sdk_version current --lang={} a/Target.aidl -o out -h out", lang));
5873     CaptureStderr();
5874     compile_aidl(options, io);
5875     auto it = expectations.find(lang + "_" + kind);
5876     ASSERT_TRUE(it != expectations.end()) << "missing expectation for " << lang << "_" << kind;
5877     const string err = GetCapturedStderr();
5878     const string expected_error =
5879         nullable ? it->second.expected_error_for_nullable : it->second.expected_error;
5880     if (expected_error.empty()) {
5881       EXPECT_EQ("", err);
5882     } else {
5883       EXPECT_THAT(err, testing::HasSubstr(expected_error));
5884     }
5885   }
5886 };
5887 
5888 INSTANTIATE_TEST_SUITE_P(
5889     AidlTestSuite, AidlTypeParamTest,
5890     testing::Combine(testing::Values(Options::Language::CPP, Options::Language::JAVA,
5891                                      Options::Language::NDK, Options::Language::RUST),
5892                      testing::ValuesIn(kTypeParams), testing::Values(true, false)),
__anon52baf79a0702(const testing::TestParamInfo<std::tuple<Options::Language, TypeParam, bool>>& info) 5893     [](const testing::TestParamInfo<std::tuple<Options::Language, TypeParam, bool>>& info) {
5894       string name = to_string(std::get<0>(info.param)) + "_" + std::get<1>(info.param).kind;
5895       if (std::get<2>(info.param)) {
5896         name += "_nullable";
5897       }
5898       return name;
5899     });
5900 
TEST_P(AidlTypeParamTest,ListSupportedTypes)5901 TEST_P(AidlTypeParamTest, ListSupportedTypes) {
5902   Run("List<{}>", kListSupportExpectations);
5903 }
5904 
TEST_P(AidlTypeParamTest,ArraySupportedTypes)5905 TEST_P(AidlTypeParamTest, ArraySupportedTypes) {
5906   Run("{}[]", kArraySupportExpectations);
5907 }
5908 
TEST_P(AidlTypeParamTest,ParcelableFieldTypes)5909 TEST_P(AidlTypeParamTest, ParcelableFieldTypes) {
5910   Run("{}", kFieldSupportExpectations);
5911 }
5912 
5913 }  // namespace aidl
5914 }  // namespace android
5915