• 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/stringprintf.h>
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 
23 #include <format>
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),
__anon078f757c0202(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",
858                                "package one; "
859                                "interface IBar {}");
860   preprocessed_files_.push_back("preprocessed");
861   import_paths_.emplace("");
862   auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
863                             typenames_, GetLanguage());
864   EXPECT_NE(nullptr, parse_result);
865 
866   // We expect to know about both kinds of IBar
867   EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
868   EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
869   // But if we request just "IBar" we should get our imported one.
870   AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", /*array=*/std::nullopt, nullptr, {});
871   ambiguous_type.Resolve(typenames_, parse_result);
872   EXPECT_EQ("one.IBar", ambiguous_type.GetName());
873 }
874 
875 // Special case of PreferImportToPreprocessed. Imported type should be preferred
876 // even when the preprocessed file already has the same type.
TEST_P(AidlTest,B147918827)877 TEST_P(AidlTest, B147918827) {
878   io_delegate_.SetFileContents("preprocessed", "interface another.IBar;\ninterface one.IBar;");
879   io_delegate_.SetFileContents("one/IBar.aidl",
880                                "package one; "
881                                "interface IBar {}");
882   preprocessed_files_.push_back("preprocessed");
883   import_paths_.emplace("");
884   auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
885                             typenames_, GetLanguage());
886   EXPECT_NE(nullptr, parse_result);
887 
888   // We expect to know about both kinds of IBar
889   EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").is_resolved);
890   EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").is_resolved);
891   // But if we request just "IBar" we should get our imported one.
892   AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", /*array=*/std::nullopt, nullptr, {});
893   ambiguous_type.Resolve(typenames_, parse_result);
894   EXPECT_EQ("one.IBar", ambiguous_type.GetName());
895 }
896 
TEST_F(AidlTest,WritePreprocessedFile)897 TEST_F(AidlTest, WritePreprocessedFile) {
898   io_delegate_.SetFileContents("p/Outer.aidl", "package p; parcelable Outer.Inner;");
899   io_delegate_.SetFileContents("one/IBar.aidl",
900                                "package one; import p.Outer;"
901                                "interface IBar {}");
902 
903   vector<string> args{"aidl", "--preprocess", "preprocessed",
904                       "-I.",  "p/Outer.aidl", "one/IBar.aidl"};
905   Options options = Options::From(args);
906   EXPECT_TRUE(::android::aidl::Preprocess(options, io_delegate_));
907 
908   std::map<std::string, std::string> expected = {{"preprocessed",
909                                                   "parcelable p.Outer.Inner;\n"
910                                                   "interface one.IBar {\n"
911                                                   "}\n"}};
912   EXPECT_THAT(io_delegate_.OutputFiles(), testing::Eq(expected));
913 }
914 
TEST_F(AidlTest,PreprocessVariousThings)915 TEST_F(AidlTest, PreprocessVariousThings) {
916   io_delegate_.SetFileContents("foo/bar/IFoo.aidl",
917                                "package foo.bar;\n"
918                                "interface IFoo {\n"
919                                "    int foo();\n"
920                                "    const int FOO = foo.bar.Bar.BAR + 1; // should be 44\n"
921                                "}\n");
922   io_delegate_.SetFileContents("foo/bar/Bar.aidl",
923                                "package foo.bar;\n"
924                                "parcelable Bar {\n"
925                                "    const int BAR = imported.Foo.FOO + 1; // should be 43\n"
926                                "    imported.Foo foo;\n"
927                                "}\n");
928   io_delegate_.SetFileContents("foo/bar/Gen.aidl",
929                                "package foo.bar;\n"
930                                "parcelable Gen<T> {\n"
931                                "}\n");
932   io_delegate_.SetFileContents("foo/bar/Enum.aidl",
933                                "package foo.bar;\n"
934                                "enum Enum {\n"
935                                "    FOO = 3, BAR = FOO + 3, // should be 3, 6\n"
936                                "}\n");
937   io_delegate_.SetFileContents("sub/imported/Foo.aidl",
938                                "package imported;\n"
939                                "parcelable Foo {\n"
940                                "    const int FOO = 42;\n"
941                                "}\n");
942 
943   vector<string> args = {
944       "aidl",
945       "--preprocess",
946       "preprocessed",
947       "-Isub",
948       "-I.",
949       "foo/bar/IFoo.aidl",
950       "foo/bar/Bar.aidl",
951       "foo/bar/Gen.aidl",
952       "foo/bar/Enum.aidl",
953   };
954   ASSERT_TRUE(Preprocess(Options::From(args), io_delegate_));
955   std::string preprocessed =
956       "interface foo.bar.IFoo {\n"
957       "  const int FOO = 44;\n"
958       "}\n"
959       "parcelable foo.bar.Bar {\n"
960       "  const int BAR = 43;\n"
961       "}\n"
962       "parcelable foo.bar.Gen<T> {\n"
963       "}\n"
964       "enum foo.bar.Enum {\n"
965       "  FOO = 3,\n"
966       "  BAR = 6,\n"
967       "}\n";
968   std::map<std::string, std::string> expected = {{"preprocessed", preprocessed}};
969   EXPECT_THAT(io_delegate_.OutputFiles(), testing::Eq(expected));
970 
971   // use preprocessed
972   io_delegate_.SetFileContents("a/Foo.aidl",
973                                "package a; parcelable Foo { const int y = foo.bar.Bar.BAR; }");
974   io_delegate_.SetFileContents("preprocessed", preprocessed);
975   CaptureStderr();
976   auto options = Options::From("aidl --lang java -I . -o out a/Foo.aidl -ppreprocessed");
977   EXPECT_TRUE(compile_aidl(options, io_delegate_));
978   EXPECT_EQ("", GetCapturedStderr());
979   string code;
980   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
981   EXPECT_THAT(code, testing::HasSubstr("public static final int y = 43;"));
982 }
983 
TEST_F(AidlTest,AllowMultipleUnstructuredNestedParcelablesInASingleDocument)984 TEST_F(AidlTest, AllowMultipleUnstructuredNestedParcelablesInASingleDocument) {
985   io_delegate_.SetFileContents("p/IFoo.aidl",
986                                "package p;\n"
987                                "import x.Outer;\n"
988                                "interface IFoo {\n"
989                                "  void foo(in Outer.Inner1 in1, in Outer.Inner2 in2);\n"
990                                "}");
991   io_delegate_.SetFileContents("imported/x/Outer.aidl",
992                                "package x;\n"
993                                "parcelable Outer.Inner1;\n"
994                                "parcelable Outer.Inner2;\n");
995   auto opt = Options::From("aidl -I . -Iimported --lang=java p/IFoo.aidl");
996   CaptureStderr();
997   EXPECT_TRUE(compile_aidl(opt, io_delegate_));
998   EXPECT_EQ("", GetCapturedStderr());
999 }
1000 
TEST_F(AidlTest,StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlLater)1001 TEST_F(AidlTest,
1002        StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlLater) {
1003   // Main doc(Foo.aidl) is loaded
1004   // And then framework.aidl is loaded as preprocessed. (conflict)
1005   io_delegate_.SetFileContents("sdk/framework.aidl", "parcelable x.Foo.Inner;\n");
1006   io_delegate_.SetFileContents("x/Foo.aidl",
1007                                "package x;\n"
1008                                "parcelable Foo.Inner;\n");
1009   auto opt = Options::From("aidl -psdk/framework.aidl -I. x/Foo.aidl");
1010   CaptureStderr();
1011   EXPECT_TRUE(compile_aidl(opt, io_delegate_));
1012   EXPECT_EQ("", GetCapturedStderr());
1013 }
1014 
TEST_F(AidlTest,StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlFirst)1015 TEST_F(AidlTest,
1016        StubsSourceIsGeneratedFromDuplicateDefinitionWithFrameworkAidl_FrameworkAidlFirst) {
1017   // Main doc(IBar.aidl) is loaded first.
1018   // Framework.aidl is loaded as preprocessed.
1019   // And then import(Foo.aidl) is loaded. (conflict)
1020   io_delegate_.SetFileContents("sdk/framework.aidl", "parcelable x.Foo.Inner;\n");
1021   io_delegate_.SetFileContents("x/IBar.aidl",
1022                                "package x;\n"
1023                                "import x.Foo;\n"
1024                                "interface IBar {\n"
1025                                "  void bar(in Foo.Inner inner);\n"
1026                                "}");
1027   io_delegate_.SetFileContents("x/Foo.aidl",
1028                                "package x;\n"
1029                                "parcelable Foo.Inner;\n");
1030   auto opt = Options::From("aidl -psdk/framework.aidl -I. x/IBar.aidl");
1031   CaptureStderr();
1032   EXPECT_TRUE(compile_aidl(opt, io_delegate_));
1033   EXPECT_EQ("", GetCapturedStderr());
1034 }
1035 
TEST_F(AidlTest,PreprocessedFileCantDeclarePackage)1036 TEST_F(AidlTest, PreprocessedFileCantDeclarePackage) {
1037   string simple_content = "package xxx; parcelable a.Foo;";
1038   io_delegate_.SetFileContents("path", simple_content);
1039   CaptureStderr();
1040   EXPECT_FALSE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
1041   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Preprocessed file can't declare package."));
1042 }
1043 
TEST_F(AidlTest,RejectQualifiedTypeNameUnlessPreprocessed)1044 TEST_F(AidlTest, RejectQualifiedTypeNameUnlessPreprocessed) {
1045   string simple_content = "parcelable a.Foo {}";
1046   io_delegate_.SetFileContents("path", simple_content);
1047   CaptureStderr();
1048   EXPECT_FALSE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/false));
1049   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Type name can't be qualified"));
1050 }
1051 
TEST_P(AidlTest,PreprocessedCanDeclareJavaStyleBuiltinTypes)1052 TEST_P(AidlTest, PreprocessedCanDeclareJavaStyleBuiltinTypes) {
1053   string contents = R"(
1054     interface android.os.IBinder;
1055     interface android.os.IInterface;
1056     parcelable android.os.ParcelFileDescriptor;
1057   )";
1058   io_delegate_.SetFileContents("path", contents);
1059   CaptureStderr();
1060   EXPECT_TRUE(Parser::Parse("path", io_delegate_, typenames_, /*is_preprocessed=*/true));
1061   EXPECT_THAT(GetCapturedStderr(), "");
1062 }
1063 
TEST_P(AidlTest,SupportDeprecated)1064 TEST_P(AidlTest, SupportDeprecated) {
1065   struct TestCase {
1066     std::string output_file;
1067     std::string annotation;
1068   };
1069 
1070   auto CheckDeprecated = [&](const std::string& filename, const std::string& contents,
1071                              std::vector<std::pair<Options::Language, TestCase>> expectations) {
1072     io_delegate_.SetFileContents(filename, contents);
1073 
1074     auto options = Options::From("aidl -I . --lang=" + to_string(GetLanguage()) + " " + filename +
1075                                  " --out=out --header_out=out");
1076     EXPECT_TRUE(compile_aidl(options, io_delegate_));
1077     for (const auto& [lang, test_case] : expectations) {
1078       if (lang != GetLanguage()) continue;
1079       string output;
1080       EXPECT_TRUE(io_delegate_.GetWrittenContents(test_case.output_file, &output));
1081       EXPECT_THAT(output, HasSubstr(test_case.annotation));
1082     }
1083   };
1084 
1085   // Emit escaped string for notes
1086   CheckDeprecated(
1087       "IFoo.aidl",
1088       R"(interface IFoo {
1089            /**
1090             * @note asdf
1091             * @deprecated a really long deprecation message
1092             *
1093             *    which is really long
1094             * @param foo bar
1095             */
1096            List<String> foo();
1097         })",
1098       {
1099           {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1100           {Options::Language::CPP,
1101            {"out/IFoo.h",
1102             R"(__attribute__((deprecated("a really long deprecation message which is really long"))))"}},
1103           {Options::Language::NDK,
1104            {"out/aidl/IFoo.h",
1105             R"(__attribute__((deprecated("a really long deprecation message which is really long"))))"}},
1106           {Options::Language::RUST,
1107            {"out/IFoo.rs",
1108             R"(#[deprecated = "a really long deprecation message which is really long"])"}},
1109       });
1110 
1111   // In AIDL @deprecated can be in block comments as well as javadoc style
1112   CheckDeprecated(
1113       "IFoo.aidl",
1114       "interface IFoo {\n"
1115       "  /* @deprecated use bar() */\n"
1116       "  List<String> foo();\n"
1117       "}",
1118       {
1119           {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1120           {Options::Language::JAVA, {"out/IFoo.java", "/** @deprecated use bar() */"}},
1121           {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated(\"use bar()\")))"}},
1122           {Options::Language::NDK,
1123            {"out/aidl/IFoo.h", "__attribute__((deprecated(\"use bar()\")))"}},
1124           {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated = \"use bar()\"]"}},
1125       });
1126 
1127   // but not in line comments
1128   auto parsed = Parse("IFoo.aidl", "// @deprecated\ninterface IFoo {}", typenames_, GetLanguage());
1129   EXPECT_FALSE(parsed->IsDeprecated());
1130 
1131   // parcelable
1132   CheckDeprecated("Foo.aidl",
1133                   "parcelable Foo {\n"
1134                   "  /** @deprecated use bar*/\n"
1135                   "  int foo = 0;\n"
1136                   "}",
1137                   {
1138                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1139                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1140                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1141                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1142                   });
1143 
1144   // interface constants
1145   CheckDeprecated("IFoo.aidl",
1146                   "interface IFoo {\n"
1147                   "  /** @deprecated use bar*/\n"
1148                   "  const int FOO = 0;\n"
1149                   "}",
1150                   {
1151                       {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1152                       {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
1153                       {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
1154                       {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
1155                   });
1156 
1157   // union fields
1158   CheckDeprecated("Foo.aidl",
1159                   "union Foo {\n"
1160                   "  int bar = 0;\n"
1161                   "  /** @deprecated use bar*/\n"
1162                   "  int foo;\n"
1163                   "}",
1164                   {
1165                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1166                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1167                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1168                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1169                   });
1170 
1171   CheckDeprecated("Foo.aidl",
1172                   "/** @deprecated use Bar */\n"
1173                   "parcelable Foo {}",
1174                   {
1175                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1176                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1177                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1178                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1179                   });
1180 
1181   CheckDeprecated("Foo.aidl",
1182                   "/** @deprecated use Bar */\n"
1183                   "union Foo { int foo = 0; }",
1184                   {
1185                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1186                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1187                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1188                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1189                   });
1190 
1191   CheckDeprecated("IFoo.aidl",
1192                   "/** @deprecated use IBar */\n"
1193                   "interface IFoo {}",
1194                   {
1195                       {Options::Language::JAVA, {"out/IFoo.java", "@Deprecated"}},
1196                       {Options::Language::CPP, {"out/IFoo.h", "__attribute__((deprecated"}},
1197                       {Options::Language::NDK, {"out/aidl/IFoo.h", "__attribute__((deprecated"}},
1198                       {Options::Language::RUST, {"out/IFoo.rs", "#[deprecated"}},
1199                   });
1200 
1201   CheckDeprecated("Foo.aidl",
1202                   "/** @deprecated use IBar */\n"
1203                   "enum Foo { FOO }",
1204                   {
1205                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1206                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1207                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1208                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1209                   });
1210 
1211   CheckDeprecated("Foo.aidl",
1212                   "enum Foo {\n"
1213                   " /** @deprecated */\n"
1214                   " FOO,\n"
1215                   " BAR,\n"
1216                   "}",
1217                   {
1218                       {Options::Language::JAVA, {"out/Foo.java", "@Deprecated"}},
1219                       {Options::Language::CPP, {"out/Foo.h", "__attribute__((deprecated"}},
1220                       {Options::Language::NDK, {"out/aidl/Foo.h", "__attribute__((deprecated"}},
1221                       {Options::Language::RUST, {"out/Foo.rs", "#[deprecated"}},
1222                   });
1223 }
1224 
TEST_P(AidlTest,RequireOuterClass)1225 TEST_P(AidlTest, RequireOuterClass) {
1226   const string expected_stderr =
1227       "ERROR: p/IFoo.aidl: Couldn't find import for class Inner. Searched here:\n - ./\nERROR: "
1228       "p/IFoo.aidl:1.54-60: Failed to resolve 'Inner'\n";
1229   io_delegate_.SetFileContents("p/Outer.aidl", "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 =
1799       "package p; import p.Outer; interface IFoo"
1800       " { Outer.Inner get(); }";
1801 
1802   auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1803   EXPECT_NE(nullptr, parse_result);
1804 
1805   EXPECT_TRUE(typenames_.ResolveTypename("p.Outer.Inner").is_resolved);
1806   // C++ uses "::" instead of "." to refer to a inner class.
1807   AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.Outer.Inner", /*array=*/std::nullopt,
1808                                 nullptr, {});
1809   EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
1810 }
1811 
TEST_P(AidlTest,UnderstandsNestedUnstructuredParcelablesWithoutImports)1812 TEST_P(AidlTest, UnderstandsNestedUnstructuredParcelablesWithoutImports) {
1813   io_delegate_.SetFileContents("p/Outer.aidl",
1814                                "package p; parcelable Outer.Inner cpp_header \"baz/header\" "
1815                                "ndk_header \"ndk/baz/header\" rust_type \"baz::Inner\";");
1816   import_paths_.emplace("");
1817   const string input_path = "p/IFoo.aidl";
1818   const string input = "package p; interface IFoo { p.Outer.Inner get(); }";
1819 
1820   auto parse_result = Parse(input_path, input, typenames_, GetLanguage());
1821   EXPECT_NE(nullptr, parse_result);
1822 
1823   EXPECT_TRUE(typenames_.ResolveTypename("p.Outer.Inner").is_resolved);
1824   // C++ uses "::" instead of "." to refer to a inner class.
1825   AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.Outer.Inner", /*array=*/std::nullopt,
1826                                 nullptr, {});
1827   EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
1828 }
1829 
TEST_F(AidlTest,UnderstandsNestedTypes)1830 TEST_F(AidlTest, UnderstandsNestedTypes) {
1831   io_delegate_.SetFileContents("p/IOuter.aidl",
1832                                "package p;\n"
1833                                "interface IOuter {\n"
1834                                "  parcelable Inner {}\n"
1835                                "}");
1836   import_paths_.emplace("");
1837   const string input_path = "p/IFoo.aidl";
1838   const string input =
1839       "package p;\n"
1840       "import p.IOuter;\n"
1841       "interface IFoo {\n"
1842       "  IOuter.Inner get();\n"
1843       "}";
1844   CaptureStderr();
1845   EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1846   EXPECT_EQ(GetCapturedStderr(), "");
1847 
1848   EXPECT_TRUE(typenames_.ResolveTypename("p.IOuter.Inner").is_resolved);
1849   // C++ uses "::" instead of "." to refer to a inner class.
1850   AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.IOuter.Inner", /*array=*/std::nullopt,
1851                                 nullptr, {});
1852   EXPECT_EQ("::p::IOuter::Inner", cpp::CppNameOf(nested_type, typenames_));
1853 }
1854 
TEST_F(AidlTest,DefinedTypeKnowsItsParentScope)1855 TEST_F(AidlTest, DefinedTypeKnowsItsParentScope) {
1856   const string input_path = "p/IFoo.aidl";
1857   const string input =
1858       "package p;\n"
1859       "interface IFoo {\n"
1860       "  parcelable Inner {\n"
1861       "    enum Enum { A }\n"
1862       "  }\n"
1863       "}";
1864   CaptureStderr();
1865   EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1866   EXPECT_EQ(GetCapturedStderr(), "");
1867 
1868   auto enum_type = typenames_.ResolveTypename("p.IFoo.Inner.Enum");
1869   auto inner_type = typenames_.ResolveTypename("p.IFoo.Inner");
1870   auto ifoo_type = typenames_.ResolveTypename("p.IFoo");
1871   EXPECT_TRUE(enum_type.is_resolved);
1872   EXPECT_TRUE(inner_type.is_resolved);
1873   EXPECT_TRUE(ifoo_type.is_resolved);
1874   // GetParentType()
1875   EXPECT_EQ(inner_type.defined_type, enum_type.defined_type->GetParentType());
1876   EXPECT_EQ(ifoo_type.defined_type, inner_type.defined_type->GetParentType());
1877   EXPECT_EQ(nullptr, ifoo_type.defined_type->GetParentType());
1878   // GetRootType()
1879   EXPECT_EQ(ifoo_type.defined_type, enum_type.defined_type->GetRootType());
1880   EXPECT_EQ(ifoo_type.defined_type, inner_type.defined_type->GetRootType());
1881   EXPECT_EQ(ifoo_type.defined_type, ifoo_type.defined_type->GetRootType());
1882   // GetDocument()
1883   auto main_document = &typenames_.MainDocument();
1884   EXPECT_EQ(main_document, &enum_type.defined_type->GetDocument());
1885   EXPECT_EQ(main_document, &inner_type.defined_type->GetDocument());
1886   EXPECT_EQ(main_document, &ifoo_type.defined_type->GetDocument());
1887 }
1888 
TEST_F(AidlTest,UnderstandsNestedTypesViaFullyQualifiedName)1889 TEST_F(AidlTest, UnderstandsNestedTypesViaFullyQualifiedName) {
1890   io_delegate_.SetFileContents("p/IOuter.aidl",
1891                                "package p;\n"
1892                                "interface IOuter {\n"
1893                                "  parcelable Inner {}\n"
1894                                "}");
1895   import_paths_.emplace("");
1896   const string input_path = "p/IFoo.aidl";
1897   const string input =
1898       "package p;\n"
1899       "interface IFoo {\n"
1900       "  p.IOuter.Inner get();\n"
1901       "}";
1902   CaptureStderr();
1903   EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1904   EXPECT_EQ(GetCapturedStderr(), "");
1905 
1906   EXPECT_TRUE(typenames_.ResolveTypename("p.IOuter.Inner").is_resolved);
1907 }
1908 
TEST_F(AidlTest,IncludeParentsRawHeaderForNestedInterface)1909 TEST_F(AidlTest, IncludeParentsRawHeaderForNestedInterface) {
1910   CaptureStderr();
1911   EXPECT_NE(nullptr, Parse("p/Outer.aidl",
1912                            "package p;\n"
1913                            "parcelable Outer {\n"
1914                            "  interface IInner {}\n"
1915                            "}",
1916                            typenames_, Options::Language::CPP));
1917 
1918   EXPECT_EQ(GetCapturedStderr(), "");
1919   auto resolved = typenames_.ResolveTypename("p.Outer.IInner");
1920   ASSERT_TRUE(resolved.defined_type);
1921   EXPECT_EQ(cpp::HeaderFile(*resolved.defined_type, cpp::ClassNames::CLIENT), "p/Outer.h");
1922 }
1923 
TEST_F(AidlTest,UnderstandsNestedTypesViaFullyQualifiedImport)1924 TEST_F(AidlTest, UnderstandsNestedTypesViaFullyQualifiedImport) {
1925   io_delegate_.SetFileContents("p/IOuter.aidl",
1926                                "package p;\n"
1927                                "interface IOuter {\n"
1928                                "  parcelable Inner {}\n"
1929                                "}");
1930   import_paths_.emplace("");
1931   const string input_path = "p/IFoo.aidl";
1932   const string input =
1933       "package p;\n"
1934       "import p.IOuter.Inner;"
1935       "interface IFoo {\n"
1936       "  Inner get();\n"
1937       "}";
1938   CaptureStderr();
1939   EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1940   EXPECT_EQ(GetCapturedStderr(), "");
1941 
1942   EXPECT_TRUE(typenames_.ResolveTypename("p.IOuter.Inner").is_resolved);
1943 }
1944 
TEST_F(AidlTest,UnderstandsNestedTypesInTheSameScope)1945 TEST_F(AidlTest, UnderstandsNestedTypesInTheSameScope) {
1946   const string input_path = "p/IFoo.aidl";
1947   const string input =
1948       "package p;\n"
1949       "interface IFoo {\n"
1950       "  parcelable Result {}\n"
1951       "  Result get();\n"
1952       "}";
1953   CaptureStderr();
1954   EXPECT_NE(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
1955   EXPECT_EQ(GetCapturedStderr(), "");
1956 
1957   EXPECT_TRUE(typenames_.ResolveTypename("p.IFoo.Result").is_resolved);
1958 }
1959 
1960 // Finding the type of nested named member.
1961 struct TypeFinder : AidlVisitor {
1962   string name;
1963   const AidlTypeSpecifier* type = nullptr;
TypeFinderandroid::aidl::TypeFinder1964   TypeFinder(std::string name) : name(name) {}
Visitandroid::aidl::TypeFinder1965   void Visit(const AidlVariableDeclaration& v) override {
1966     if (v.GetName() == name) {
1967       type = &v.GetType();
1968     }
1969   }
Visitandroid::aidl::TypeFinder1970   void Visit(const AidlMethod& m) override {
1971     if (m.GetName() == name) {
1972       type = &m.GetType();
1973     }
1974   }
Getandroid::aidl::TypeFinder1975   static string Get(const AidlDefinedType& type, const string& name) {
1976     TypeFinder v(name);
1977     VisitTopDown(v, type);
1978     return v.type ? v.type->Signature() : "(null)";
1979   };
1980 };
1981 
TEST_F(AidlTest,UnderstandsNestedTypesViaQualifiedInTheSameScope)1982 TEST_F(AidlTest, UnderstandsNestedTypesViaQualifiedInTheSameScope) {
1983   io_delegate_.SetFileContents("q/IBar.aidl",
1984                                "package q;\n"
1985                                "interface IBar {\n"
1986                                "  parcelable Baz {}\n"
1987                                "}");
1988   import_paths_.emplace("");
1989   const string input_path = "p/IFoo.aidl";
1990   const string input =
1991       "package p;\n"
1992       "import q.IBar;\n"
1993       "interface IFoo {\n"
1994       "  parcelable Nested {\n"
1995       "    Baz t1;\n"
1996       "  }\n"
1997       "  parcelable Baz { }\n"
1998       "  IBar.Baz t2();\n"
1999       "  Baz t3();\n"
2000       "}";
2001   CaptureStderr();
2002   auto foo = Parse(input_path, input, typenames_, Options::Language::CPP);
2003   EXPECT_EQ(GetCapturedStderr(), "");
2004   ASSERT_NE(nullptr, foo);
2005 
2006   EXPECT_EQ(TypeFinder::Get(*foo, "t1"), "p.IFoo.Baz");
2007   EXPECT_EQ(TypeFinder::Get(*foo, "t2"), "q.IBar.Baz");
2008   EXPECT_EQ(TypeFinder::Get(*foo, "t3"), "p.IFoo.Baz");
2009 }
2010 
TEST_F(AidlTest,NestedTypeResolutionWithNoPackage)2011 TEST_F(AidlTest, NestedTypeResolutionWithNoPackage) {
2012   const string input_path = "Foo.aidl";
2013   const string input =
2014       "parcelable Foo {\n"
2015       "  parcelable Bar {\n"
2016       "    enum Baz { BAZ }\n"
2017       "    Baz baz = Baz.BAZ;\n"
2018       "  }\n"
2019       "  Bar bar;\n"
2020       "}";
2021   CaptureStderr();
2022   auto foo = Parse(input_path, input, typenames_, Options::Language::CPP);
2023   EXPECT_EQ(GetCapturedStderr(), "");
2024   ASSERT_NE(nullptr, foo);
2025 
2026   EXPECT_EQ(TypeFinder::Get(*foo, "bar"), "Foo.Bar");
2027   EXPECT_EQ(TypeFinder::Get(*foo, "baz"), "Foo.Bar.Baz");
2028 }
2029 
TEST_F(AidlTest,RejectsNestedTypesWithParentsName)2030 TEST_F(AidlTest, RejectsNestedTypesWithParentsName) {
2031   const string input_path = "p/Foo.aidl";
2032   const string input =
2033       "package p;\n"
2034       "parcelable Foo {\n"
2035       "  parcelable Foo {}\n"
2036       "}";
2037   CaptureStderr();
2038   EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
2039   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Nested type 'Foo' has the same name as its parent."));
2040 }
2041 
TEST_F(AidlTest,RejectUnstructuredParcelableAsNestedTypes)2042 TEST_F(AidlTest, RejectUnstructuredParcelableAsNestedTypes) {
2043   const string input_path = "p/IFoo.aidl";
2044   const string input =
2045       "package p;\n"
2046       "interface IFoo {\n"
2047       "  parcelable Bar cpp_header \"Bar.h\";\n"
2048       "}";
2049   CaptureStderr();
2050   EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
2051   EXPECT_THAT(GetCapturedStderr(),
2052               HasSubstr("Unstructured parcelables should be at the root scope"));
2053 }
2054 
TEST_F(AidlTest,RejectGenericTypeWithNestedTypes)2055 TEST_F(AidlTest, RejectGenericTypeWithNestedTypes) {
2056   const string input_path = "p/Foo.aidl";
2057   const string input =
2058       "package p;\n"
2059       "parcelable Foo<T> {\n"
2060       "  parcelable Bar {}\n"
2061       "}";
2062   CaptureStderr();
2063   EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
2064   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Generic types can't have nested types."));
2065 }
2066 
TEST_F(AidlTest,HandleSyntaxErrorsInNestedDecl)2067 TEST_F(AidlTest, HandleSyntaxErrorsInNestedDecl) {
2068   const string input_path = "p/IFoo.aidl";
2069   const string input =
2070       "package p;\n"
2071       "interface IFoo {\n"
2072       "  parcelable;\n"  // missing identifier
2073       "}";
2074   CaptureStderr();
2075   EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
2076   EXPECT_THAT(GetCapturedStderr(), HasSubstr("expecting identifier"));
2077 }
2078 
TEST_F(AidlTest,RejectsNestedTypesWithDuplicateNames)2079 TEST_F(AidlTest, RejectsNestedTypesWithDuplicateNames) {
2080   const string input_path = "p/Foo.aidl";
2081   const string input =
2082       "package p;\n"
2083       "interface Foo {\n"
2084       "  parcelable Bar {}\n"
2085       "  parcelable Bar {}\n"
2086       "}";
2087   CaptureStderr();
2088   EXPECT_EQ(nullptr, Parse(input_path, input, typenames_, Options::Language::CPP));
2089   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Redefinition of 'Bar'"));
2090 }
2091 
TEST_F(AidlTest,TypeResolutionWithMultipleLevelsOfNesting)2092 TEST_F(AidlTest, TypeResolutionWithMultipleLevelsOfNesting) {
2093   struct Failure {
2094     string err;
2095   };
2096   struct TestCase {
2097     string type;
2098     variant<string, Failure> expected;  // success<0> or failure<1>
2099   };
2100   vector<TestCase> cases = {
2101       {"foo.A", "foo.A"},
2102       {"foo.A.B", "foo.A.B"},
2103       {"@nullable(heap=true) A", "foo.A.B.A"},
2104       // In the scope of foo.A.B.A, B is resolved to A.B.A.B first.
2105       {"B.A", Failure{"Failed to resolve 'B.A'"}},
2106       {"B", "foo.A.B.A.B"},
2107       {"A.B", "foo.A.B.A.B"},
2108   };
2109   const string input_path = "foo/A.aidl";
2110   for (auto& [type, expected] : cases) {
2111     AidlTypenames typenames;
2112     // clang-format off
2113     const string input =
2114         "package foo;\n"
2115         "parcelable A {\n"
2116         "  parcelable B {\n"
2117         "    parcelable A {\n"
2118         "      parcelable B {\n"
2119         "      }\n"
2120         "      " + type + " m;\n"
2121         "    }\n"
2122         "  }\n"
2123         "}";
2124     // clang-format on
2125     CaptureStderr();
2126     auto foo = Parse(input_path, input, typenames, Options::Language::CPP);
2127     if (auto failure = std::get_if<Failure>(&expected); failure) {
2128       ASSERT_EQ(nullptr, foo);
2129       EXPECT_THAT(GetCapturedStderr(), HasSubstr(failure->err));
2130     } else {
2131       EXPECT_EQ(GetCapturedStderr(), "");
2132       ASSERT_NE(nullptr, foo);
2133       EXPECT_EQ(TypeFinder::Get(*foo, "m"), std::get<string>(expected));
2134     }
2135   }
2136 }
2137 
TEST_F(AidlTest,HeaderForNestedTypeShouldPointToTopMostParent)2138 TEST_F(AidlTest, HeaderForNestedTypeShouldPointToTopMostParent) {
2139   const string input_path = "p/IFoo.aidl";
2140   const string input =
2141       "package p;\n"
2142       "interface IFoo {\n"
2143       "  parcelable Result {}\n"
2144       "}";
2145   CaptureStderr();
2146   auto foo = Parse(input_path, input, typenames_, Options::Language::CPP);
2147   ASSERT_NE(nullptr, foo);
2148   EXPECT_EQ(GetCapturedStderr(), "");
2149 
2150   auto result = typenames_.ResolveTypename("p.IFoo.Result").defined_type;
2151   ASSERT_NE(nullptr, result);
2152   EXPECT_EQ("p/IFoo.h", cpp::CppHeaderForType(*result));
2153 }
2154 
TEST_F(AidlTest,ReorderNestedTypesForCppOutput)2155 TEST_F(AidlTest, ReorderNestedTypesForCppOutput) {
2156   const string input_path = "p/IFoo.aidl";
2157   const string input = R"(
2158     package p;
2159     interface IFoo {
2160       // partial orderings for [A, D, G]:
2161       //   D - A
2162       //   A - G
2163       parcelable A {
2164         // partial orderings for [B, C]:
2165         //   C - B
2166         parcelable B {
2167           C c;
2168           D.E d;
2169         }
2170         parcelable C {}
2171       }
2172       parcelable D {
2173         // partial orderings for [E, F]:
2174         //   F - E
2175         parcelable E {
2176           F f;
2177         }
2178         parcelable F {}
2179       }
2180       parcelable G {
2181         A.B b;
2182       }
2183     }
2184   )";
2185   Options options = Options::From("aidl --lang cpp -I. -oout -hout p/IFoo.aidl");
2186   io_delegate_.SetFileContents(input_path, input);
2187   CaptureStderr();
2188   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2189   EXPECT_EQ(GetCapturedStderr(), "");
2190 
2191   string code;
2192   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/IFoo.h", &code));
2193   // check partial orderings: a should comes before b
2194   EXPECT_LE(code.find("class D"), code.find("class A"));
2195   EXPECT_LE(code.find("class A"), code.find("class G"));
2196   EXPECT_LE(code.find("class C"), code.find("class B"));
2197   EXPECT_LE(code.find("class F"), code.find("class E"));
2198 }
2199 
TEST_F(AidlTest,RejectsNestedTypesWithCyclicDeps)2200 TEST_F(AidlTest, RejectsNestedTypesWithCyclicDeps) {
2201   const string input_path = "p/IFoo.aidl";
2202   const string input = R"(
2203     package p;
2204     interface IFoo {
2205       // Cycles:
2206       //   D - A
2207       //   A - G
2208       //   G - D
2209       parcelable A {
2210         parcelable B {
2211           C c;
2212         }
2213       }
2214       parcelable C {
2215         parcelable D {
2216           E e;
2217         }
2218       }
2219       parcelable E {
2220         parcelable F {
2221           A a;
2222         }
2223       }
2224     }
2225   )";
2226   Options options = Options::From("aidl --lang cpp -I. -oout -hout p/IFoo.aidl");
2227   io_delegate_.SetFileContents(input_path, input);
2228   CaptureStderr();
2229   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2230   EXPECT_THAT(GetCapturedStderr(), HasSubstr("IFoo has nested types with cyclic references."));
2231 }
2232 
TEST_F(AidlTest,RejectsCyclicNestedInterfaces)2233 TEST_F(AidlTest, RejectsCyclicNestedInterfaces) {
2234   Options options = Options::From(
2235       "aidl --lang cpp -I. -oout -hout "
2236       "p/IFoo.aidl p/IBar.aidl p/IQux.aidl");
2237   io_delegate_.SetFileContents("p/IFoo.aidl",
2238                                "package p; import p.IBar; "
2239                                "interface IFoo { IBar getBar(); }");
2240   io_delegate_.SetFileContents("p/IBar.aidl",
2241                                "package p; import p.IQux; "
2242                                "interface IBar { IQux.Inner getQux(); }");
2243   io_delegate_.SetFileContents("p/IQux.aidl",
2244                                "package p; import p.IFoo; "
2245                                "interface IQux { interface Inner { IFoo getFoo(); } }");
2246   CaptureStderr();
2247   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2248   EXPECT_THAT(GetCapturedStderr(),
2249               HasSubstr("ERROR: p/IQux.aidl:1.43-53: has cyclic references to nested types."));
2250 }
2251 
TEST_F(AidlTest,RejectsCyclicNestedInterfacesAndParcelables)2252 TEST_F(AidlTest, RejectsCyclicNestedInterfacesAndParcelables) {
2253   Options options = Options::From(
2254       "aidl --lang cpp -I. -oout -hout "
2255       "p/IFoo.aidl p/Bar.aidl");
2256   io_delegate_.SetFileContents("p/IFoo.aidl",
2257                                "package p; import p.Bar; "
2258                                "interface IFoo { interface Inner { Bar getBar(); } }");
2259   io_delegate_.SetFileContents("p/Bar.aidl",
2260                                "package p; import p.IFoo; "
2261                                "parcelable Bar { IFoo.Inner foo; }");
2262   CaptureStderr();
2263   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2264   EXPECT_THAT(GetCapturedStderr(),
2265               HasSubstr("ERROR: p/IFoo.aidl:1.42-52: has cyclic references to nested types."));
2266 }
2267 
TEST_F(AidlTest,CppNameOf_GenericType)2268 TEST_F(AidlTest, CppNameOf_GenericType) {
2269   const string input_path = "p/Wrapper.aidl";
2270   const string input = "package p; parcelable Wrapper<T> {}";
2271 
2272   auto parse_result = Parse(input_path, input, typenames_, Options::Language::CPP);
2273   EXPECT_NE(nullptr, parse_result);
2274 
2275   auto type = [](std::string name, auto&&... type_params) -> std::unique_ptr<AidlTypeSpecifier> {
2276     auto params = new std::vector<std::unique_ptr<AidlTypeSpecifier>>;
2277     (..., params->emplace_back(std::move(type_params)));
2278     return std::make_unique<AidlTypeSpecifier>(AIDL_LOCATION_HERE, name, std::nullopt, params,
2279                                                Comments{});
2280   };
2281 
2282   auto set_nullable = [](std::unique_ptr<AidlTypeSpecifier>&& type) {
2283     std::vector<std::unique_ptr<AidlAnnotation>> annotations;
2284     annotations.emplace_back(std::unique_ptr<AidlAnnotation>(
2285         AidlAnnotation::Parse(AIDL_LOCATION_HERE, "nullable", {}, {})));
2286     type->Annotate(std::move(annotations));
2287     return std::move(type);
2288   };
2289 
2290   auto set_array = [](std::unique_ptr<AidlTypeSpecifier>&& type) {
2291     (void)type->MakeArray(DynamicArray{});
2292     return std::move(type);
2293   };
2294 
2295   auto w = type("p.Wrapper", type("String"));
2296   EXPECT_EQ("::p::Wrapper<::android::String16>", cpp::CppNameOf(*w, typenames_));
2297 
2298   auto nullable_w = set_nullable(type("p.Wrapper", type("String")));
2299   EXPECT_EQ("::std::optional<::p::Wrapper<::android::String16>>",
2300             cpp::CppNameOf(*nullable_w, typenames_));
2301 
2302   auto array_w = set_array(type("p.Wrapper", type("String")));
2303   EXPECT_EQ("::std::vector<::p::Wrapper<::android::String16>>",
2304             cpp::CppNameOf(*array_w, typenames_));
2305 
2306   auto nullable_array_w = set_nullable(set_array(type("p.Wrapper", type("String"))));
2307   EXPECT_EQ("::std::optional<::std::vector<::std::optional<::p::Wrapper<::android::String16>>>>",
2308             cpp::CppNameOf(*nullable_array_w, typenames_));
2309 
2310   auto list_w = type("List", type("p.Wrapper", type("String")));
2311   EXPECT_EQ("::std::vector<::p::Wrapper<::android::String16>>",
2312             cpp::CppNameOf(*list_w, typenames_));
2313 
2314   auto nullable_list_w = set_nullable(type("List", type("p.Wrapper", type("String"))));
2315   EXPECT_EQ("::std::optional<::std::vector<::std::optional<::p::Wrapper<::android::String16>>>>",
2316             cpp::CppNameOf(*nullable_list_w, typenames_));
2317 }
2318 
TEST_P(AidlTest,UnderstandsNativeParcelables)2319 TEST_P(AidlTest, UnderstandsNativeParcelables) {
2320   io_delegate_.SetFileContents("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",
2560                          "--include=.", "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("foo/bar/IFoo.aidl",
2602                                "package foo.bar;\n"
2603                                "interface IFoo {\n"
2604                                "    int foo() = 1;\n"
2605                                "    int bar() = 2;\n"
2606                                "    int baz() = 10;\n"
2607                                "}\n");
2608 
2609   vector<string> args = {"aidl", "-I . ", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
2610   Options options = Options::From(args);
2611   bool result = dump_api(options, io_delegate_);
2612   ASSERT_TRUE(result);
2613   string actual;
2614   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
2615   EXPECT_EQ(actual, string(kPreamble).append(R"(package foo.bar;
2616 interface IFoo {
2617   int foo() = 1;
2618   int bar() = 2;
2619   int baz() = 10;
2620 }
2621 )"));
2622 }
2623 
TEST_F(AidlTest,ApiDumpWithManualIdsOnlyOnSomeMethods)2624 TEST_F(AidlTest, ApiDumpWithManualIdsOnlyOnSomeMethods) {
2625   const string expected_stderr =
2626       "ERROR: foo/bar/IFoo.aidl:4.8-12: You must either assign id's to all methods or to none of "
2627       "them.\n";
2628   io_delegate_.SetFileContents("foo/bar/IFoo.aidl",
2629                                "package foo.bar;\n"
2630                                "interface IFoo {\n"
2631                                "    int foo() = 1;\n"
2632                                "    int bar();\n"
2633                                "    int baz() = 10;\n"
2634                                "}\n");
2635 
2636   vector<string> args = {"aidl", "-I . ", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
2637   Options options = Options::From(args);
2638   CaptureStderr();
2639   EXPECT_FALSE(dump_api(options, io_delegate_));
2640   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2641 }
2642 
TEST_F(AidlTest,ApiDumpConstWithAnnotation)2643 TEST_F(AidlTest, ApiDumpConstWithAnnotation) {
2644   io_delegate_.SetFileContents("foo/bar/IFoo.aidl",
2645                                "package foo.bar;\n"
2646                                "interface IFoo {\n"
2647                                "    @utf8InCpp String foo();\n"
2648                                "    const @utf8InCpp String bar = \"bar\";\n"
2649                                "}\n");
2650 
2651   vector<string> args = {"aidl", "-I . ", "--dumpapi", "-o dump", "foo/bar/IFoo.aidl"};
2652   Options options = Options::From(args);
2653   CaptureStderr();
2654   EXPECT_TRUE(dump_api(options, io_delegate_));
2655   EXPECT_EQ("", GetCapturedStderr());
2656   string actual;
2657   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/IFoo.aidl", &actual));
2658   EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
2659 interface IFoo {
2660   @utf8InCpp String foo();
2661   const @utf8InCpp String bar = "bar";
2662 }
2663 )"),
2664             actual);
2665 }
2666 
TEST_F(AidlTest,ApiDumpWithEnums)2667 TEST_F(AidlTest, ApiDumpWithEnums) {
2668   io_delegate_.SetFileContents("foo/bar/Enum.aidl",
2669                                "package foo.bar;\n"
2670                                "enum Enum {\n"
2671                                "    FOO,\n"
2672                                "    BAR = FOO + 1,\n"
2673                                "}\n");
2674 
2675   vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Enum.aidl"};
2676   Options options = Options::From(args);
2677   CaptureStderr();
2678   EXPECT_TRUE(dump_api(options, io_delegate_));
2679   EXPECT_EQ("", GetCapturedStderr());
2680   string actual;
2681   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Enum.aidl", &actual));
2682   EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
2683                                      "enum Enum {\n"
2684                                      "  FOO,\n"
2685                                      "  BAR = (FOO + 1) /* 1 */,\n"
2686                                      "}\n"),
2687             actual);
2688 }
2689 
TEST_F(AidlTest,ApiDumpWithEnumDefaultValues)2690 TEST_F(AidlTest, ApiDumpWithEnumDefaultValues) {
2691   io_delegate_.SetFileContents("foo/bar/Enum.aidl",
2692                                "package foo.bar;\n"
2693                                "enum Enum {\n"
2694                                "    FOO,\n"
2695                                "}\n");
2696   io_delegate_.SetFileContents("foo/bar/Foo.aidl",
2697                                "package foo.bar;\n"
2698                                "import foo.bar.Enum;\n"
2699                                "parcelable Foo {\n"
2700                                "    Enum e = Enum.FOO;\n"
2701                                "    int n = Enum.FOO;\n"
2702                                "}\n");
2703 
2704   vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Foo.aidl"};
2705   Options options = Options::From(args);
2706   CaptureStderr();
2707   EXPECT_TRUE(dump_api(options, io_delegate_));
2708   EXPECT_EQ("", GetCapturedStderr());
2709   string actual;
2710   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
2711   EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
2712                                      "parcelable Foo {\n"
2713                                      "  foo.bar.Enum e = foo.bar.Enum.FOO;\n"
2714                                      "  int n = foo.bar.Enum.FOO /* 0 */;\n"
2715                                      "}\n"),
2716             actual);
2717 }
2718 
TEST_F(AidlTest,ApiDumpWithGenerics)2719 TEST_F(AidlTest, ApiDumpWithGenerics) {
2720   io_delegate_.SetFileContents("foo/bar/Foo.aidl",
2721                                "package foo.bar;\n"
2722                                "parcelable Foo<T, U> {\n"
2723                                "}\n");
2724 
2725   vector<string> args = {"aidl", "--dumpapi", "-I . ", "-o dump", "foo/bar/Foo.aidl"};
2726   Options options = Options::From(args);
2727   CaptureStderr();
2728   EXPECT_TRUE(dump_api(options, io_delegate_));
2729   EXPECT_EQ("", GetCapturedStderr());
2730   string actual;
2731   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
2732   EXPECT_EQ(string(kPreamble).append("package foo.bar;\n"
2733                                      "parcelable Foo<T, U> {\n"
2734                                      "}\n"),
2735             actual);
2736 }
2737 
TEST_F(AidlTest,ImportedDocumentHasDuplicateDefinitions)2738 TEST_F(AidlTest, ImportedDocumentHasDuplicateDefinitions) {
2739   io_delegate_.SetFileContents("IFoo.aidl", "interface IFoo; interface IFoo;\n");
2740   io_delegate_.SetFileContents("Bar.aidl", "enum Bar { CONST = IFoo.NONE }\n");
2741 
2742   vector<string> args = {"aidl", "--dumpapi", "-I.", "-o out", "Bar.aidl"};
2743   Options options = Options::From(args);
2744   CaptureStderr();
2745   EXPECT_FALSE(dump_api(options, io_delegate_));
2746   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Can't find NONE in IFoo"));
2747 }
2748 
TEST_F(AidlTest,CheckNumGenericTypeSecifier)2749 TEST_F(AidlTest, CheckNumGenericTypeSecifier) {
2750   const string expected_list_stderr =
2751       "ERROR: p/IFoo.aidl:1.37-41: List can only have one type parameter, but got: "
2752       "'List<String,String>'\n";
2753   const string expected_map_stderr =
2754       "ERROR: p/IFoo.aidl:1.37-40: Map must have 0 or 2 type parameters, but got 'Map<String>'\n";
2755   Options options = Options::From("aidl -I . p/IFoo.aidl IFoo.java");
2756   io_delegate_.SetFileContents(options.InputFiles().front(),
2757                                "package p; interface IFoo {"
2758                                "void foo(List<String, String> a);}");
2759   CaptureStderr();
2760   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2761   EXPECT_EQ(expected_list_stderr, GetCapturedStderr());
2762 
2763   io_delegate_.SetFileContents(options.InputFiles().front(),
2764                                "package p; interface IFoo {"
2765                                "void foo(Map<String> a);}");
2766   CaptureStderr();
2767   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2768   EXPECT_EQ(expected_map_stderr, GetCapturedStderr());
2769 }
2770 
TEST_F(AidlTest,CheckTypeParameterInMapType)2771 TEST_F(AidlTest, CheckTypeParameterInMapType) {
2772   const string expected_stderr =
2773       "ERROR: p/IFoo.aidl:1.28-31: The type of key in map must be String, but it is 'p.Bar'\n";
2774   Options options = Options::From("aidl -I . p/IFoo.aidl");
2775   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar { String s; }");
2776 
2777   io_delegate_.SetFileContents("p/IFoo.aidl",
2778                                "package p; interface IFoo {"
2779                                "Map<String, p.Bar> foo();}");
2780   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2781 
2782   io_delegate_.SetFileContents("p/IFoo.aidl",
2783                                "package p; interface IFoo {"
2784                                "Map<p.Bar, p.Bar> foo();}");
2785   CaptureStderr();
2786   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2787   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2788 
2789   io_delegate_.SetFileContents("p/IFoo.aidl",
2790                                "package p; interface IFoo {"
2791                                "Map<String, String> foo();}");
2792   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2793 
2794   io_delegate_.SetFileContents("p/IFoo.aidl",
2795                                "package p; interface IFoo {"
2796                                "Map<String, ParcelFileDescriptor> foo();}");
2797   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2798 }
2799 
TEST_F(AidlTest,WrongGenericType)2800 TEST_F(AidlTest, WrongGenericType) {
2801   const string expected_stderr = "ERROR: p/IFoo.aidl:1.28-34: String is not a generic type.\n";
2802   Options options = Options::From("aidl -I . p/IFoo.aidl IFoo.java");
2803   io_delegate_.SetFileContents(options.InputFiles().front(),
2804                                "package p; interface IFoo {"
2805                                "String<String> foo(); }");
2806   CaptureStderr();
2807   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2808   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2809 }
2810 
TEST_F(AidlTest,UserDefinedUnstructuredGenericParcelableType)2811 TEST_F(AidlTest, UserDefinedUnstructuredGenericParcelableType) {
2812   Options optionsForParcelable = Options::From("aidl -I . p/Bar.aidl");
2813   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, T>;");
2814   CaptureStderr();
2815   EXPECT_FALSE(compile_aidl(optionsForParcelable, io_delegate_));
2816   EXPECT_EQ("ERROR: p/Bar.aidl:1.22-26: Every type parameter should be unique.\n",
2817             GetCapturedStderr());
2818 
2819   Options options = Options::From("aidl -I . p/IFoo.aidl");
2820   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar;");
2821   io_delegate_.SetFileContents("p/IFoo.aidl",
2822                                "package p; interface IFoo {"
2823                                "p.Bar<String, String> foo();}");
2824   CaptureStderr();
2825   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2826   EXPECT_THAT(GetCapturedStderr(), HasSubstr("p.Bar is not a generic type"));
2827   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T>;");
2828   CaptureStderr();
2829   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2830   EXPECT_THAT(GetCapturedStderr(), HasSubstr("p.Bar must have 1 type parameters, but got 2"));
2831   io_delegate_.SetFileContents("p/Bar.aidl", "package p; parcelable Bar<T, V>;");
2832   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2833   io_delegate_.SetFileContents("p/IFoo.aidl",
2834                                "package p; interface IFoo {"
2835                                "p.Bar<String, ParcelFileDescriptor> foo();}");
2836   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2837 
2838   io_delegate_.SetFileContents("p/IFoo.aidl",
2839                                "package p; interface IFoo {"
2840                                "p.Bar<int, long> foo();}");
2841 
2842   io_delegate_.SetFileContents("p/IFoo.aidl",
2843                                "package p; interface IFoo {"
2844                                "p.Bar<int[], long[]> foo();}");
2845 
2846   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2847 }
2848 
TEST_F(AidlTest,FailOnMultipleTypesInSingleFile)2849 TEST_F(AidlTest, FailOnMultipleTypesInSingleFile) {
2850   std::vector<std::string> rawOptions{"aidl --lang=java -I . -o out foo/bar/Foo.aidl",
2851                                       "aidl --lang=cpp -I . -o out -h out/include foo/bar/Foo.aidl",
2852                                       "aidl --lang=rust -I . -o out foo/bar/Foo.aidl"};
2853   for (const auto& rawOption : rawOptions) {
2854     string expected_stderr =
2855         "ERROR: foo/bar/Foo.aidl:3.1-10: You must declare only one type per file.\n";
2856     Options options = Options::From(rawOption);
2857     io_delegate_.SetFileContents(options.InputFiles().front(),
2858                                  "package foo.bar;\n"
2859                                  "interface IFoo1 { int foo(); }\n"
2860                                  "interface IFoo2 { int foo(); }\n"
2861                                  "parcelable Data1 { int a; int b;}\n"
2862                                  "parcelable Data2 { int a; int b;}\n");
2863     CaptureStderr();
2864     EXPECT_FALSE(compile_aidl(options, io_delegate_));
2865     EXPECT_EQ(expected_stderr, GetCapturedStderr());
2866 
2867     io_delegate_.SetFileContents(options.InputFiles().front(),
2868                                  "package foo.bar;\n"
2869                                  "interface IFoo1 { int foo(); }\n"
2870                                  "interface IFoo2 { int foo(); }\n");
2871     CaptureStderr();
2872     EXPECT_FALSE(compile_aidl(options, io_delegate_));
2873     EXPECT_EQ(expected_stderr, GetCapturedStderr());
2874 
2875     expected_stderr = "ERROR: foo/bar/Foo.aidl:3.11-17: You must declare only one type per file.\n";
2876     io_delegate_.SetFileContents(options.InputFiles().front(),
2877                                  "package foo.bar;\n"
2878                                  "parcelable Data1 { int a; int b;}\n"
2879                                  "parcelable Data2 { int a; int b;}\n");
2880     CaptureStderr();
2881     EXPECT_FALSE(compile_aidl(options, io_delegate_));
2882     EXPECT_EQ(expected_stderr, GetCapturedStderr());
2883   }
2884 }
2885 
TEST_P(AidlTest,FailParseOnEmptyFile)2886 TEST_P(AidlTest, FailParseOnEmptyFile) {
2887   const string contents = "";
2888   const string expected_stderr = "ERROR: a/IFoo.aidl:1.1-1: syntax error, unexpected $end\n";
2889   const string expected_stderr_newbison =
2890       "ERROR: a/IFoo.aidl:1.1-1: syntax error, unexpected end of file\n";
2891   CaptureStderr();
2892   EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", contents, typenames_, GetLanguage()));
2893   EXPECT_THAT(GetCapturedStderr(),
2894               testing::AnyOf(testing::Eq(expected_stderr), testing::Eq(expected_stderr_newbison)));
2895 }
2896 
TEST_F(AidlTest,MultipleInputFiles)2897 TEST_F(AidlTest, MultipleInputFiles) {
2898   Options options =
2899       Options::From("aidl --lang=java -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
2900 
2901   io_delegate_.SetFileContents(options.InputFiles().at(0),
2902                                "package foo.bar;\n"
2903                                "import foo.bar.Data;\n"
2904                                "interface IFoo { Data getData(); }\n");
2905 
2906   io_delegate_.SetFileContents(options.InputFiles().at(1),
2907                                "package foo.bar;\n"
2908                                "import foo.bar.IFoo;\n"
2909                                "parcelable Data { IFoo foo; }\n");
2910 
2911   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2912 
2913   string content;
2914   for (const auto file : {"out/foo/bar/IFoo.java", "out/foo/bar/Data.java"}) {
2915     content.clear();
2916     EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
2917     EXPECT_FALSE(content.empty());
2918   }
2919 }
2920 
TEST_F(AidlTest,MultipleInputFilesCpp)2921 TEST_F(AidlTest, MultipleInputFilesCpp) {
2922   Options options = Options::From(
2923       "aidl --lang=cpp -I . -o out -h out/include "
2924       "-I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
2925 
2926   io_delegate_.SetFileContents(options.InputFiles().at(0),
2927                                "package foo.bar;\n"
2928                                "import foo.bar.Data;\n"
2929                                "interface IFoo { Data getData(); }\n");
2930 
2931   io_delegate_.SetFileContents(options.InputFiles().at(1),
2932                                "package foo.bar;\n"
2933                                "import foo.bar.IFoo;\n"
2934                                "parcelable Data { IFoo foo; }\n");
2935 
2936   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2937 
2938   string content;
2939   for (const auto file :
2940        {"out/foo/bar/IFoo.cpp", "out/foo/bar/Data.cpp", "out/include/foo/bar/IFoo.h",
2941         "out/include/foo/bar/Data.h", "out/include/foo/bar/BpFoo.h", "out/include/foo/bar/BpData.h",
2942         "out/include/foo/bar/BnFoo.h", "out/include/foo/bar/BnData.h"}) {
2943     content.clear();
2944     EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
2945     EXPECT_FALSE(content.empty());
2946   }
2947 }
2948 
TEST_F(AidlTest,MultipleInputFilesRust)2949 TEST_F(AidlTest, MultipleInputFilesRust) {
2950   Options options =
2951       Options::From("aidl --lang=rust -o out -I . foo/bar/IFoo.aidl foo/bar/Data.aidl");
2952 
2953   io_delegate_.SetFileContents(options.InputFiles().at(0),
2954                                "package foo.bar;\n"
2955                                "import foo.bar.Data;\n"
2956                                "interface IFoo { Data getData(); }\n");
2957 
2958   io_delegate_.SetFileContents(options.InputFiles().at(1),
2959                                "package foo.bar;\n"
2960                                "import foo.bar.IFoo;\n"
2961                                "parcelable Data { IFoo foo; }\n");
2962 
2963   EXPECT_TRUE(compile_aidl(options, io_delegate_));
2964 
2965   string content;
2966   for (const auto file : {"out/foo/bar/IFoo.rs", "out/foo/bar/Data.rs"}) {
2967     content.clear();
2968     EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
2969     EXPECT_FALSE(content.empty());
2970   }
2971 }
2972 
TEST_F(AidlTest,ConflictWithMetaTransactionGetVersion)2973 TEST_F(AidlTest, ConflictWithMetaTransactionGetVersion) {
2974   const string expected_stderr =
2975       "ERROR: p/IFoo.aidl:1.31-51:  method getInterfaceVersion() is reserved for internal use.\n";
2976   Options options = Options::From("aidl --lang=java -I . -o place/for/output p/IFoo.aidl");
2977   // int getInterfaceVersion() is one of the meta transactions
2978   io_delegate_.SetFileContents(options.InputFiles().front(),
2979                                "package p; interface IFoo {"
2980                                "int getInterfaceVersion(); }");
2981   CaptureStderr();
2982   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2983   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2984 }
2985 
TEST_F(AidlTest,ConflictWithSimilarMetaTransaction)2986 TEST_F(AidlTest, ConflictWithSimilarMetaTransaction) {
2987   // boolean getInterfaceVersion() is not a meta transaction, but should be
2988   // prevented because return type is not part of a method signature
2989   const string expected_stderr =
2990       "ERROR: p/IFoo.aidl:1.35-55:  method getInterfaceVersion() is reserved for internal use.\n";
2991   Options options = Options::From("aidl --lang=java -I . -o place/for/output p/IFoo.aidl");
2992   io_delegate_.SetFileContents(options.InputFiles().front(),
2993                                "package p; interface IFoo {"
2994                                "boolean getInterfaceVersion(); }");
2995   CaptureStderr();
2996   EXPECT_FALSE(compile_aidl(options, io_delegate_));
2997   EXPECT_EQ(expected_stderr, GetCapturedStderr());
2998 }
2999 
TEST_F(AidlTest,ConflictWithMetaTransactionGetName)3000 TEST_F(AidlTest, ConflictWithMetaTransactionGetName) {
3001   // this is another reserved name
3002   const string expected_stderr =
3003       "ERROR: p/IFoo.aidl:1.34-53:  method getTransactionName(int) is reserved for internal use.\n";
3004   Options options = Options::From("aidl --lang=java -I . -o place/for/output p/IFoo.aidl");
3005   io_delegate_.SetFileContents(options.InputFiles().front(),
3006                                "package p; interface IFoo {"
3007                                "String getTransactionName(int code); }");
3008   CaptureStderr();
3009   EXPECT_FALSE(compile_aidl(options, io_delegate_));
3010   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3011 
3012   // this is not a meta interface method as it differs type arguments
3013   io_delegate_.SetFileContents(options.InputFiles().front(),
3014                                "package p; interface IFoo {"
3015                                "String getTransactionName(); }");
3016   EXPECT_TRUE(compile_aidl(options, io_delegate_));
3017 }
3018 
TEST_F(AidlTest,CheckApiForEquality)3019 TEST_F(AidlTest, CheckApiForEquality) {
3020   CaptureStderr();
3021   Options options = Options::From("aidl --checkapi=equal old new");
3022 
3023   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3024                                "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
3025   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3026                                "package p; interface IFoo{ @utf8InCpp String foo();}");
3027 
3028   EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
3029   EXPECT_THAT(GetCapturedStderr(), HasSubstr("+  @utf8InCpp String foo();"));
3030 }
3031 
TEST_F(AidlTest,DifferentOrderAnnotationsInCheckAPI)3032 TEST_F(AidlTest, DifferentOrderAnnotationsInCheckAPI) {
3033   Options options = Options::From("aidl --checkapi old new");
3034   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3035                                "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
3036   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3037                                "package p; interface IFoo{ @nullable @utf8InCpp String foo();}");
3038 
3039   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3040 }
3041 
TEST_F(AidlTest,JavaPassthroughAnnotationAddedInCheckApi)3042 TEST_F(AidlTest, JavaPassthroughAnnotationAddedInCheckApi) {
3043   Options options = Options::From("aidl --checkapi old new");
3044   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{}");
3045   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3046                                "package p; @JavaPassthrough(annotation=\"@foo\") interface IFoo{}");
3047 
3048   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3049 }
3050 
TEST_F(AidlTest,SuccessOnIdenticalApiDumps)3051 TEST_F(AidlTest, SuccessOnIdenticalApiDumps) {
3052   Options options = Options::From("aidl --checkapi old new");
3053   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
3054   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
3055 
3056   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3057 }
3058 
TEST_F(AidlTest,CheckApi_EnumFieldsWithDefaultValues)3059 TEST_F(AidlTest, CheckApi_EnumFieldsWithDefaultValues) {
3060   Options options = Options::From("aidl --checkapi old new");
3061   const string foo_definition = "package p; parcelable Foo{ p.Enum e = p.Enum.FOO; }";
3062   const string enum_definition = "package p; enum Enum { FOO }";
3063   io_delegate_.SetFileContents("old/p/Foo.aidl", foo_definition);
3064   io_delegate_.SetFileContents("old/p/Enum.aidl", enum_definition);
3065   io_delegate_.SetFileContents("new/p/Foo.aidl", foo_definition);
3066   io_delegate_.SetFileContents("new/p/Enum.aidl", enum_definition);
3067 
3068   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3069 }
3070 
TEST_F(AidlTest,CheckApi_EnumFieldsFromImported)3071 TEST_F(AidlTest, CheckApi_EnumFieldsFromImported) {
3072   Options options = Options::From("aidl --checkapi old new -I import");
3073 
3074   io_delegate_.SetFileContents("old/p/Foo.aidl", "package p; parcelable Foo{ other.Enum e; }");
3075   io_delegate_.SetFileContents("new/p/Foo.aidl",
3076                                "package p; parcelable Foo{ other.Enum e = other.Enum.FOO; }");
3077   io_delegate_.SetFileContents("import/other/Enum.aidl", "package other; enum Enum { FOO }");
3078 
3079   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3080 }
3081 
TEST_F(AidlTest,CheckApiEqual_EnumFieldsWithDefaultValues)3082 TEST_F(AidlTest, CheckApiEqual_EnumFieldsWithDefaultValues) {
3083   Options options = Options::From("aidl --checkapi=equal old new");
3084   const string foo_definition = "package p; parcelable Foo{ p.Enum e = p.Enum.FOO; }";
3085   const string enum_definition = "package p; enum Enum { FOO }";
3086   io_delegate_.SetFileContents("old/p/Foo.aidl", foo_definition);
3087   io_delegate_.SetFileContents("old/p/Enum.aidl", enum_definition);
3088   io_delegate_.SetFileContents("new/p/Foo.aidl", foo_definition);
3089   io_delegate_.SetFileContents("new/p/Enum.aidl", enum_definition);
3090   CaptureStderr();
3091   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
3092   EXPECT_EQ("", GetCapturedStderr());
3093 }
3094 
3095 class AidlTestCompatibleChanges : public AidlTest {
3096  protected:
3097   Options options_ = Options::From("aidl --checkapi old new");
3098 };
3099 
TEST_F(AidlTestCompatibleChanges,NewType)3100 TEST_F(AidlTestCompatibleChanges, NewType) {
3101   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3102                                "package p;"
3103                                "interface IFoo {"
3104                                "  void foo(int a);"
3105                                "}");
3106   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3107                                "package p;"
3108                                "interface IFoo {"
3109                                "  void foo(int a);"
3110                                "}");
3111   io_delegate_.SetFileContents("new/p/IBar.aidl",
3112                                "package p;"
3113                                "interface IBar {"
3114                                "  void bar();"
3115                                "}");
3116   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3117 }
3118 
TEST_F(AidlTestCompatibleChanges,NewMethod)3119 TEST_F(AidlTestCompatibleChanges, NewMethod) {
3120   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3121                                "package p;"
3122                                "interface IFoo {"
3123                                "  void foo(int a);"
3124                                "}");
3125   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3126                                "package p;"
3127                                "interface IFoo {"
3128                                "  void foo(int a);"
3129                                "  void bar();"
3130                                "  void baz(in List<String> arg);"
3131                                "}");
3132   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3133 }
3134 
TEST_F(AidlTestCompatibleChanges,NewField)3135 TEST_F(AidlTestCompatibleChanges, NewField) {
3136   io_delegate_.SetFileContents("old/p/Data.aidl",
3137                                "package p;"
3138                                "parcelable Data {"
3139                                "  int foo;"
3140                                "}");
3141   io_delegate_.SetFileContents("new/p/Data.aidl",
3142                                "package p;"
3143                                "parcelable Data {"
3144                                "  int foo;"
3145                                "  int bar = 0;"
3146                                "  @nullable List<Data> list;"
3147                                "}");
3148   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3149 }
3150 
TEST_F(AidlTestCompatibleChanges,NewField2)3151 TEST_F(AidlTestCompatibleChanges, NewField2) {
3152   io_delegate_.SetFileContents("old/p/Data.aidl",
3153                                "package p;"
3154                                "parcelable Data {"
3155                                "}");
3156   io_delegate_.SetFileContents("new/p/Data.aidl",
3157                                "package p;"
3158                                "parcelable Data {"
3159                                "  int foo = 0;"
3160                                "}");
3161   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3162 }
3163 
TEST_F(AidlTestCompatibleChanges,NewEnumerator)3164 TEST_F(AidlTestCompatibleChanges, NewEnumerator) {
3165   io_delegate_.SetFileContents("old/p/Enum.aidl",
3166                                "package p;"
3167                                "enum Enum {"
3168                                "  FOO = 1,"
3169                                "}");
3170   io_delegate_.SetFileContents("new/p/Enum.aidl",
3171                                "package p;"
3172                                "enum Enum {"
3173                                "  FOO = 1,"
3174                                "  BAR = 2,"
3175                                "}");
3176   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3177 }
3178 
TEST_F(AidlTestCompatibleChanges,ReorderedEnumerator)3179 TEST_F(AidlTestCompatibleChanges, ReorderedEnumerator) {
3180   io_delegate_.SetFileContents("old/p/Enum.aidl",
3181                                "package p;"
3182                                "enum Enum {"
3183                                "  FOO = 1,"
3184                                "  BAR = 2,"
3185                                "}");
3186   io_delegate_.SetFileContents("new/p/Enum.aidl",
3187                                "package p;"
3188                                "enum Enum {"
3189                                "  BAR = 2,"
3190                                "  FOO = 1,"
3191                                "}");
3192   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3193 }
3194 
TEST_F(AidlTestCompatibleChanges,NewUnionField)3195 TEST_F(AidlTestCompatibleChanges, NewUnionField) {
3196   io_delegate_.SetFileContents("old/p/Union.aidl",
3197                                "package p;"
3198                                "union Union {"
3199                                "  String foo;"
3200                                "}");
3201   io_delegate_.SetFileContents("new/p/Union.aidl",
3202                                "package p;"
3203                                "union Union {"
3204                                "  String foo;"
3205                                "  int num;"
3206                                "}");
3207   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3208 }
3209 
TEST_F(AidlTestCompatibleChanges,NewPackage)3210 TEST_F(AidlTestCompatibleChanges, NewPackage) {
3211   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3212                                "package p;"
3213                                "interface IFoo {"
3214                                "  void foo(int a);"
3215                                "}");
3216   io_delegate_.SetFileContents("old/p/Data.aidl",
3217                                "package p;"
3218                                "parcelable Data {"
3219                                "  int foo;"
3220                                "}");
3221   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3222                                "package p;"
3223                                "interface IFoo {"
3224                                "  void foo(int a);"
3225                                "}");
3226   io_delegate_.SetFileContents("new/p/Data.aidl",
3227                                "package p;"
3228                                "parcelable Data {"
3229                                "  int foo;"
3230                                "}");
3231   io_delegate_.SetFileContents("new/q/IFoo.aidl",
3232                                "package q;"
3233                                "interface IFoo {"
3234                                "  void foo(int a);"
3235                                "}");
3236   io_delegate_.SetFileContents("new/q/Data.aidl",
3237                                "package q;"
3238                                "parcelable Data {"
3239                                "  int foo;"
3240                                "}");
3241   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3242 }
3243 
TEST_F(AidlTestCompatibleChanges,ArgNameChange)3244 TEST_F(AidlTestCompatibleChanges, ArgNameChange) {
3245   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3246                                "package p;"
3247                                "interface IFoo {"
3248                                "  void foo(int a);"
3249                                "}");
3250   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3251                                "package p;"
3252                                "interface IFoo {"
3253                                "  void foo(int b);"
3254                                "}");
3255   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3256 }
3257 
TEST_F(AidlTestCompatibleChanges,AddedConstValue)3258 TEST_F(AidlTestCompatibleChanges, AddedConstValue) {
3259   io_delegate_.SetFileContents("old/p/I.aidl",
3260                                "package p; interface I {"
3261                                "const int A = 1; }");
3262   io_delegate_.SetFileContents("new/p/I.aidl",
3263                                "package p ; interface I {"
3264                                "const int A = 1; const int B = 2;}");
3265   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3266 }
3267 
TEST_F(AidlTestCompatibleChanges,ChangedConstValueOrder)3268 TEST_F(AidlTestCompatibleChanges, ChangedConstValueOrder) {
3269   io_delegate_.SetFileContents("old/p/I.aidl",
3270                                "package p; interface I {"
3271                                "const int A = 1; const int B = 2;}");
3272   io_delegate_.SetFileContents("new/p/I.aidl",
3273                                "package p ; interface I {"
3274                                "const int B = 2; const int A = 1;}");
3275   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3276 }
3277 
TEST_F(AidlTestCompatibleChanges,ReorderedAnnatations)3278 TEST_F(AidlTestCompatibleChanges, ReorderedAnnatations) {
3279   io_delegate_.SetFileContents("old/p/Foo.aidl",
3280                                "package p;"
3281                                "@JavaPassthrough(annotation=\"Alice\")"
3282                                "@JavaPassthrough(annotation=\"Bob\")"
3283                                "parcelable Foo {}");
3284   io_delegate_.SetFileContents("new/p/Foo.aidl",
3285                                "package p;"
3286                                "@JavaPassthrough(annotation=\"Bob\")"
3287                                "@JavaPassthrough(annotation=\"Alice\")"
3288                                "parcelable Foo {}");
3289   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3290 }
3291 
TEST_F(AidlTestCompatibleChanges,OkayToDeprecate)3292 TEST_F(AidlTestCompatibleChanges, OkayToDeprecate) {
3293   io_delegate_.SetFileContents("old/p/Foo.aidl",
3294                                "package p;"
3295                                "parcelable Foo {}");
3296   io_delegate_.SetFileContents("new/p/Foo.aidl",
3297                                "package p;"
3298                                "@JavaPassthrough(annotation=\"@Deprecated\")"
3299                                "parcelable Foo {}");
3300   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3301 }
3302 
TEST_F(AidlTestCompatibleChanges,NewFieldOfNewType)3303 TEST_F(AidlTestCompatibleChanges, NewFieldOfNewType) {
3304   io_delegate_.SetFileContents("old/p/Data.aidl",
3305                                "package p;"
3306                                "parcelable Data {"
3307                                "  int num;"
3308                                "}");
3309   io_delegate_.SetFileContents(
3310       "new/p/Data.aidl",
3311       "package p;"
3312       "parcelable Data {"
3313       "  int num;"
3314       "  p.Enum e;"  // this is considered as valid since 0(enum default) is valid for "Enum" type
3315       "}");
3316   io_delegate_.SetFileContents("new/p/Enum.aidl",
3317                                "package p;"
3318                                "enum Enum {"
3319                                "  FOO = 0,"
3320                                "  BAR = 1,"
3321                                "}");
3322   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3323 }
3324 
TEST_F(AidlTestCompatibleChanges,CompatibleExplicitDefaults)3325 TEST_F(AidlTestCompatibleChanges, CompatibleExplicitDefaults) {
3326   io_delegate_.SetFileContents("old/p/Data.aidl",
3327                                "package p;\n"
3328                                "parcelable Data {\n"
3329                                "  p.Enum e;\n"
3330                                "}");
3331   io_delegate_.SetFileContents("old/p/Enum.aidl",
3332                                "package p;\n"
3333                                "enum Enum {\n"
3334                                "  FOO = 0,\n"
3335                                "  BAR = 1,\n"
3336                                "}");
3337   io_delegate_.SetFileContents("new/p/Data.aidl",
3338                                "package p;\n"
3339                                "parcelable Data {\n"
3340                                "  p.Enum e = p.Enum.FOO;\n"
3341                                "}");
3342   io_delegate_.SetFileContents("new/p/Enum.aidl",
3343                                "package p;\n"
3344                                "enum Enum {\n"
3345                                "  FOO = 0,\n"
3346                                "  BAR = 1,\n"
3347                                "}");
3348   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3349 }
3350 
TEST_F(AidlTestCompatibleChanges,NewNestedTypes)3351 TEST_F(AidlTestCompatibleChanges, NewNestedTypes) {
3352   io_delegate_.SetFileContents("old/p/Data.aidl",
3353                                "package p;\n"
3354                                "parcelable Data {\n"
3355                                "  int n;\n"
3356                                "}");
3357   io_delegate_.SetFileContents("new/p/Data.aidl",
3358                                "package p;\n"
3359                                "parcelable Data {\n"
3360                                "  enum NewEnum { N = 3 }\n"
3361                                "  int n;\n"
3362                                "  NewEnum e = NewEnum.N;\n"
3363                                "}");
3364   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3365 }
3366 
TEST_F(AidlTestCompatibleChanges,NewJavaSuppressLint)3367 TEST_F(AidlTestCompatibleChanges, NewJavaSuppressLint) {
3368   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3369                                "package p;"
3370                                "interface IFoo {"
3371                                "  void foo(int a);"
3372                                "}");
3373   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3374                                "package p;"
3375                                "@JavaSuppressLint({\"NewApi\"})"
3376                                "interface IFoo {"
3377                                "  void foo(int a);"
3378                                "}");
3379   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3380 }
3381 
3382 class AidlTestIncompatibleChanges : public AidlTest {
3383  protected:
3384   Options options_ = Options::From("aidl --checkapi old new");
3385 };
3386 
TEST_F(AidlTestIncompatibleChanges,RemovedType)3387 TEST_F(AidlTestIncompatibleChanges, RemovedType) {
3388   const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
3389   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3390                                "package p;"
3391                                "interface IFoo {"
3392                                "  void foo(in String[] str);"
3393                                "  void bar(@utf8InCpp String str);"
3394                                "}");
3395   CaptureStderr();
3396   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3397   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3398 }
3399 
TEST_F(AidlTestIncompatibleChanges,RemovedTypeNotInternal)3400 TEST_F(AidlTestIncompatibleChanges, RemovedTypeNotInternal) {
3401   // We create new Tag enums internal to unions and they show up in these logs
3402   const string expected_stderr =
3403       "ERROR: old/p/Foo.aidl:1.16-20: Removed type: p.Foo\n"
3404       "ERROR: (derived from)old/p/Foo.aidl:1.16-20: Removed type: p.Foo.Tag\n";
3405   io_delegate_.SetFileContents("old/p/Foo.aidl",
3406                                "package p;"
3407                                "union Foo {"
3408                                "  int foo;"
3409                                "  int bar;"
3410                                "}");
3411   CaptureStderr();
3412   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3413   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3414 }
3415 
TEST_F(AidlTestIncompatibleChanges,RemovedMethod)3416 TEST_F(AidlTestIncompatibleChanges, RemovedMethod) {
3417   const string expected_stderr =
3418       "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
3419   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3420                                "package p;"
3421                                "interface IFoo {"
3422                                "  void foo(in String[] str);"
3423                                "  void bar(@utf8InCpp String str);"
3424                                "}");
3425   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3426                                "package p;"
3427                                "interface IFoo {"
3428                                "  void foo(in String[] str);"
3429                                "}");
3430   CaptureStderr();
3431   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3432   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3433 }
3434 
TEST_F(AidlTestIncompatibleChanges,UntypedListInInterface)3435 TEST_F(AidlTestIncompatibleChanges, UntypedListInInterface) {
3436   const string expected_stderr =
3437       "ERROR: new/p/IFoo.aidl:1.61-65: "
3438       "Encountered an untyped List or Map. The use of untyped List/Map is "
3439       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3440       "the receiving side. Consider switching to an array or a generic List/Map.\n"
3441       "ERROR: new/p/IFoo.aidl: Failed to read.\n";
3442   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3443                                "package p;"
3444                                "interface IFoo {"
3445                                "  void foo(in String[] str);"
3446                                "}");
3447   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3448                                "package p;"
3449                                "interface IFoo {"
3450                                "  void foo(in String[] str);"
3451                                "  void bar(in List arg);"
3452                                "}");
3453   CaptureStderr();
3454   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3455   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3456 }
3457 
TEST_F(AidlTestCompatibleChanges,UntypedListInParcelable)3458 TEST_F(AidlTestCompatibleChanges, UntypedListInParcelable) {
3459   const string expected_stderr =
3460       "ERROR: new/p/Data.aidl:1.54-59: "
3461       "Encountered an untyped List or Map. The use of untyped List/Map is "
3462       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
3463       "the receiving side. Consider switching to an array or a generic List/Map.\n"
3464       "ERROR: new/p/Data.aidl: Failed to read.\n";
3465   io_delegate_.SetFileContents("old/p/Data.aidl",
3466                                "package p;"
3467                                "parcelable Data {"
3468                                "  int foo;"
3469                                "}");
3470   io_delegate_.SetFileContents("new/p/Data.aidl",
3471                                "package p;"
3472                                "parcelable Data {"
3473                                "  int foo;"
3474                                "  @nullable List list;"
3475                                "}");
3476   CaptureStderr();
3477   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3478   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3479 }
3480 
TEST_F(AidlTestIncompatibleChanges,RemovedField)3481 TEST_F(AidlTestIncompatibleChanges, RemovedField) {
3482   const string expected_stderr =
3483       "ERROR: new/p/Data.aidl:1.21-26: Number of fields in p.Data is reduced from 2 to 1.\n";
3484   io_delegate_.SetFileContents("old/p/Data.aidl",
3485                                "package p;"
3486                                "parcelable Data {"
3487                                "  int foo;"
3488                                "  int bar;"
3489                                "}");
3490   io_delegate_.SetFileContents("new/p/Data.aidl",
3491                                "package p;"
3492                                "parcelable Data {"
3493                                "  int foo;"
3494                                "}");
3495   CaptureStderr();
3496   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3497   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3498 }
3499 
TEST_F(AidlTestIncompatibleChanges,NewFieldWithNoDefault)3500 TEST_F(AidlTestIncompatibleChanges, NewFieldWithNoDefault) {
3501   const string expected_stderr =
3502       "ERROR: new/p/Data.aidl:1.46-50: Field 'str' does not have a useful default in some "
3503       "backends. Please either provide a default value for this field or mark the field as "
3504       "@nullable. This value or a null value will be used automatically when an old version of "
3505       "this parcelable is sent to a process which understands a new version of this parcelable. In "
3506       "order to make sure your code continues to be backwards compatible, make sure the default or "
3507       "null value does not cause a semantic change to this parcelable.\n";
3508   io_delegate_.SetFileContents("old/p/Data.aidl",
3509                                "package p;"
3510                                "parcelable Data {"
3511                                "  int num;"
3512                                "}");
3513   io_delegate_.SetFileContents("new/p/Data.aidl",
3514                                "package p;"
3515                                "parcelable Data {"
3516                                "  int num;"
3517                                "  String str;"
3518                                "}");
3519   CaptureStderr();
3520   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3521   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3522 }
3523 
TEST_F(AidlTestIncompatibleChanges,NewFieldWithNonZeroEnum)3524 TEST_F(AidlTestIncompatibleChanges, NewFieldWithNonZeroEnum) {
3525   const string expected_stderr =
3526       "ERROR: new/p/Data.aidl:1.46-48: Field 'e' of enum 'Enum' can't be initialized as '0'. "
3527       "Please make sure 'Enum' has '0' as a valid value.\n";
3528   io_delegate_.SetFileContents("old/p/Data.aidl",
3529                                "package p;"
3530                                "parcelable Data {"
3531                                "  int num;"
3532                                "}");
3533   io_delegate_.SetFileContents("new/p/Data.aidl",
3534                                "package p;"
3535                                "parcelable Data {"
3536                                "  int num;"
3537                                "  p.Enum e;"
3538                                "}");
3539   io_delegate_.SetFileContents("new/p/Enum.aidl",
3540                                "package p;"
3541                                "enum Enum {"
3542                                "  FOO = 1,"
3543                                "  BAR = 2,"
3544                                "}");
3545   CaptureStderr();
3546   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3547   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3548 }
3549 
TEST_F(AidlTestIncompatibleChanges,RemovedEnumerator)3550 TEST_F(AidlTestIncompatibleChanges, RemovedEnumerator) {
3551   const string expected_stderr =
3552       "ERROR: new/p/Enum.aidl:1.15-20: Removed enumerator from p.Enum: FOO\n";
3553   io_delegate_.SetFileContents("old/p/Enum.aidl",
3554                                "package p;"
3555                                "enum Enum {"
3556                                "  FOO = 1,"
3557                                "  BAR = 2,"
3558                                "}");
3559   io_delegate_.SetFileContents("new/p/Enum.aidl",
3560                                "package p;"
3561                                "enum Enum {"
3562                                "  BAR = 2,"
3563                                "}");
3564   CaptureStderr();
3565   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3566   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3567 }
3568 
TEST_F(AidlTestIncompatibleChanges,RemovedUnionField)3569 TEST_F(AidlTestIncompatibleChanges, RemovedUnionField) {
3570   const string expected_stderr =
3571       "ERROR: new/p/Union.aidl:1.16-22: Number of fields in p.Union is reduced from 2 to 1.\n"
3572       "ERROR: (derived from)new/p/Union.aidl:1.16-22: Removed enumerator from p.Union.Tag: num\n";
3573   io_delegate_.SetFileContents("old/p/Union.aidl",
3574                                "package p;"
3575                                "union Union {"
3576                                "  String str;"
3577                                "  int num;"
3578                                "}");
3579   io_delegate_.SetFileContents("new/p/Union.aidl",
3580                                "package p;"
3581                                "union Union {"
3582                                "  String str;"
3583                                "}");
3584   CaptureStderr();
3585   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3586   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3587 }
3588 
TEST_F(AidlTestIncompatibleChanges,RenamedMethod)3589 TEST_F(AidlTestIncompatibleChanges, RenamedMethod) {
3590   const string expected_stderr =
3591       "ERROR: old/p/IFoo.aidl:1.61-65: Removed or changed method: p.IFoo.bar(String)\n";
3592   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3593                                "package p;"
3594                                "interface IFoo {"
3595                                "  void foo(in String[] str);"
3596                                "  void bar(@utf8InCpp String str);"
3597                                "}");
3598   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3599                                "package p;"
3600                                "interface IFoo {"
3601                                "  void foo(in String[] str);"
3602                                "  void bar2(@utf8InCpp String str);"
3603                                "}");
3604   CaptureStderr();
3605   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3606   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3607 }
3608 
TEST_F(AidlTestIncompatibleChanges,RenamedType)3609 TEST_F(AidlTestIncompatibleChanges, RenamedType) {
3610   const string expected_stderr = "ERROR: old/p/IFoo.aidl:1.11-20: Removed type: p.IFoo\n";
3611   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3612                                "package p;"
3613                                "interface IFoo {"
3614                                "  void foo(in String[] str);"
3615                                "  void bar(@utf8InCpp String str);"
3616                                "}");
3617   io_delegate_.SetFileContents("new/p/IFoo2.aidl",
3618                                "package p;"
3619                                "interface IFoo2 {"
3620                                "  void foo(in String[] str);"
3621                                "  void bar(@utf8InCpp String str);"
3622                                "}");
3623   CaptureStderr();
3624   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3625   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3626 }
3627 
TEST_F(AidlTestIncompatibleChanges,ChangedEnumerator)3628 TEST_F(AidlTestIncompatibleChanges, ChangedEnumerator) {
3629   const string expected_stderr =
3630       "ERROR: new/p/Enum.aidl:1.15-20: Changed enumerator value: p.Enum::FOO from 1 to 3.\n";
3631   io_delegate_.SetFileContents("old/p/Enum.aidl",
3632                                "package p;"
3633                                "enum Enum {"
3634                                "  FOO = 1,"
3635                                "  BAR = 2,"
3636                                "}");
3637   io_delegate_.SetFileContents("new/p/Enum.aidl",
3638                                "package p;"
3639                                "enum Enum {"
3640                                "  FOO = 3,"
3641                                "  BAR = 2,"
3642                                "}");
3643   CaptureStderr();
3644   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3645   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3646 }
3647 
TEST_F(AidlTestIncompatibleChanges,ReorderedMethod)3648 TEST_F(AidlTestIncompatibleChanges, ReorderedMethod) {
3649   const string expected_stderr =
3650       "ERROR: new/p/IFoo.aidl:1.67-71: Transaction ID changed: p.IFoo.foo(String[]) is changed "
3651       "from 0 to 1.\n"
3652       "ERROR: new/p/IFoo.aidl:1.33-37: Transaction ID changed: p.IFoo.bar(String) is changed from "
3653       "1 to 0.\n";
3654   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3655                                "package p;"
3656                                "interface IFoo {"
3657                                "  void foo(in String[] str);"
3658                                "  void bar(@utf8InCpp String str);"
3659                                "}");
3660   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3661                                "package p;"
3662                                "interface IFoo {"
3663                                "  void bar(@utf8InCpp String str);"
3664                                "  void foo(in String[] str);"
3665                                "}");
3666   CaptureStderr();
3667   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3668   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3669 }
3670 
TEST_F(AidlTestIncompatibleChanges,ReorderedField)3671 TEST_F(AidlTestIncompatibleChanges, ReorderedField) {
3672   const string expected_stderr =
3673       "ERROR: new/p/Data.aidl:1.33-37: Reordered bar from 1 to 0.\n"
3674       "ERROR: new/p/Data.aidl:1.43-47: Reordered foo from 0 to 1.\n";
3675   io_delegate_.SetFileContents("old/p/Data.aidl",
3676                                "package p;"
3677                                "parcelable Data {"
3678                                "  int foo;"
3679                                "  int bar;"
3680                                "}");
3681   io_delegate_.SetFileContents("new/p/Data.aidl",
3682                                "package p;"
3683                                "parcelable Data {"
3684                                "  int bar;"
3685                                "  int foo;"
3686                                "}");
3687   CaptureStderr();
3688   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3689   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3690 }
3691 
TEST_F(AidlTestIncompatibleChanges,ChangedDirectionSpecifier)3692 TEST_F(AidlTestIncompatibleChanges, ChangedDirectionSpecifier) {
3693   const string expected_stderr = "ERROR: new/p/IFoo.aidl:1.33-37: Direction changed: in to out.\n";
3694   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3695                                "package p;"
3696                                "interface IFoo {"
3697                                "  void foo(in String[] str);"
3698                                "  void bar(@utf8InCpp String str);"
3699                                "}");
3700   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3701                                "package p;"
3702                                "interface IFoo {"
3703                                "  void foo(out String[] str);"
3704                                "  void bar(@utf8InCpp String str);"
3705                                "}");
3706   CaptureStderr();
3707   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3708   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3709 }
3710 
TEST_F(AidlTestIncompatibleChanges,AddedAnnotation)3711 TEST_F(AidlTestIncompatibleChanges, AddedAnnotation) {
3712   const string expected_stderr =
3713       "ERROR: new/p/IFoo.aidl:1.51-58: Changed annotations: (empty) to @utf8InCpp\n";
3714   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3715                                "package p;"
3716                                "interface IFoo {"
3717                                "  void foo(in String[] str);"
3718                                "  void bar(@utf8InCpp String str);"
3719                                "}");
3720   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3721                                "package p;"
3722                                "interface IFoo {"
3723                                "  void foo(in @utf8InCpp String[] str);"
3724                                "  void bar(@utf8InCpp String str);"
3725                                "}");
3726   CaptureStderr();
3727   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3728   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3729 }
3730 
TEST_F(AidlTestIncompatibleChanges,RemovedAnnotation)3731 TEST_F(AidlTestIncompatibleChanges, RemovedAnnotation) {
3732   const string expected_stderr =
3733       "ERROR: new/p/IFoo.aidl:1.66-72: Changed annotations: @utf8InCpp to (empty)\n";
3734   io_delegate_.SetFileContents("old/p/IFoo.aidl",
3735                                "package p;"
3736                                "interface IFoo {"
3737                                "  void foo(in String[] str);"
3738                                "  void bar(@utf8InCpp String str);"
3739                                "}");
3740   io_delegate_.SetFileContents("new/p/IFoo.aidl",
3741                                "package p;"
3742                                "interface IFoo {"
3743                                "  void foo(in String[] str);"
3744                                "  void bar(String str);"
3745                                "}");
3746   CaptureStderr();
3747   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3748   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3749 }
3750 
TEST_F(AidlTestIncompatibleChanges,ChangedFixedSizeArraySize)3751 TEST_F(AidlTestIncompatibleChanges, ChangedFixedSizeArraySize) {
3752   const string expected_stderr =
3753       "ERROR: new/p/Data.aidl:1.28-33: Type changed: int[8] to int[9].\n";
3754   io_delegate_.SetFileContents("old/p/Data.aidl",
3755                                "package p;"
3756                                "parcelable Data {"
3757                                "  int[8] bar;"
3758                                "}");
3759   io_delegate_.SetFileContents("new/p/Data.aidl",
3760                                "package p;"
3761                                "parcelable Data {"
3762                                "  int[9] bar;"
3763                                "}");
3764   CaptureStderr();
3765   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3766   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3767 }
3768 
TEST_F(AidlTestIncompatibleChanges,ChangedAnnatationParams)3769 TEST_F(AidlTestIncompatibleChanges, ChangedAnnatationParams) {
3770   // this is also the test for backing type remaining the same
3771   const string expected_stderr =
3772       "ERROR: new/p/Foo.aidl:1.36-40: Changed annotations: @Backing(type=\"int\") "
3773       "to @Backing(type=\"long\")\n";
3774   io_delegate_.SetFileContents("old/p/Foo.aidl",
3775                                "package p;"
3776                                "@Backing(type=\"int\")"
3777                                "enum Foo {A}");
3778   io_delegate_.SetFileContents("new/p/Foo.aidl",
3779                                "package p;"
3780                                "@Backing(type=\"long\")"
3781                                "enum Foo {A}");
3782 
3783   CaptureStderr();
3784   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3785   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3786 }
3787 
TEST_F(AidlTestIncompatibleChanges,AddedParcelableAnnotation)3788 TEST_F(AidlTestIncompatibleChanges, AddedParcelableAnnotation) {
3789   const string expected_stderr =
3790       "ERROR: new/p/Foo.aidl:1.32-36: Changed annotations: (empty) to @FixedSize\n";
3791   io_delegate_.SetFileContents("old/p/Foo.aidl",
3792                                "package p;"
3793                                "parcelable Foo {"
3794                                "  int A;"
3795                                "}");
3796   io_delegate_.SetFileContents("new/p/Foo.aidl",
3797                                "package p;"
3798                                "@FixedSize parcelable Foo {"
3799                                "  int A;"
3800                                "}");
3801   CaptureStderr();
3802   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3803   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3804 }
3805 
TEST_F(AidlTestIncompatibleChanges,RemovedParcelableAnnotation)3806 TEST_F(AidlTestIncompatibleChanges, RemovedParcelableAnnotation) {
3807   const string expected_stderr =
3808       "ERROR: new/p/Foo.aidl:1.21-25: Changed annotations: @FixedSize to (empty)\n";
3809   io_delegate_.SetFileContents("old/p/Foo.aidl",
3810                                "package p;"
3811                                "@FixedSize parcelable Foo {"
3812                                "  int A;"
3813                                "}");
3814   io_delegate_.SetFileContents("new/p/Foo.aidl",
3815                                "package p;"
3816                                "parcelable Foo {"
3817                                "  int A;"
3818                                "}");
3819   CaptureStderr();
3820   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3821   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3822 }
3823 
TEST_F(AidlTestIncompatibleChanges,RemovedPackage)3824 TEST_F(AidlTestIncompatibleChanges, RemovedPackage) {
3825   const string expected_stderr = "ERROR: old/q/IFoo.aidl:1.11-21: Removed type: q.IFoo\n";
3826   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{}");
3827   io_delegate_.SetFileContents("old/q/IFoo.aidl", "package q; interface IFoo{}");
3828   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{}");
3829   CaptureStderr();
3830   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3831   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3832 }
3833 
TEST_F(AidlTestIncompatibleChanges,ChangedDefaultValue)3834 TEST_F(AidlTestIncompatibleChanges, ChangedDefaultValue) {
3835   const string expected_stderr = "ERROR: new/p/D.aidl:1.30-32: Changed default value: 1 to 2.\n";
3836   io_delegate_.SetFileContents("old/p/D.aidl", "package p; parcelable D { int a = 1; }");
3837   io_delegate_.SetFileContents("new/p/D.aidl", "package p; parcelable D { int a = 2; }");
3838   CaptureStderr();
3839   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3840   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3841 }
3842 
TEST_F(AidlTestIncompatibleChanges,RemovedConstValue)3843 TEST_F(AidlTestIncompatibleChanges, RemovedConstValue) {
3844   const string expected_stderr =
3845       "ERROR: old/p/I.aidl:1.51-53: Removed constant declaration: p.I.B\n";
3846   io_delegate_.SetFileContents("old/p/I.aidl",
3847                                "package p; interface I {"
3848                                "const int A = 1; const int B = 2;}");
3849   io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 1; }");
3850   CaptureStderr();
3851   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3852   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3853 }
3854 
TEST_F(AidlTestIncompatibleChanges,ChangedConstValue)3855 TEST_F(AidlTestIncompatibleChanges, ChangedConstValue) {
3856   const string expected_stderr =
3857       "ERROR: new/p/I.aidl:1.11-21: Changed constant value: p.I.A from 1 to 2.\n";
3858   io_delegate_.SetFileContents("old/p/I.aidl", "package p; interface I { const int A = 1; }");
3859   io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 2; }");
3860   CaptureStderr();
3861   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3862   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3863 }
3864 
TEST_F(AidlTestIncompatibleChanges,FixedSizeAddedField)3865 TEST_F(AidlTestIncompatibleChanges, FixedSizeAddedField) {
3866   const string expected_stderr =
3867       "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is changed from 1 to 2. "
3868       "This is an incompatible change for FixedSize types.\n";
3869   io_delegate_.SetFileContents("old/p/Foo.aidl",
3870                                "package p; @FixedSize parcelable Foo { int A = 1; }");
3871   io_delegate_.SetFileContents("new/p/Foo.aidl",
3872                                "package p; @FixedSize parcelable Foo { int A = 1; int B = 2; }");
3873   CaptureStderr();
3874   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3875   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3876 }
3877 
TEST_F(AidlTestIncompatibleChanges,UidRangeParcelAddedField)3878 TEST_F(AidlTestIncompatibleChanges, UidRangeParcelAddedField) {
3879   const string expected_stderr =
3880       "ERROR: new/android/net/UidRangeParcel.aidl:1.32-47: Number of fields in "
3881       "android.net.UidRangeParcel is changed from 1 to 2. "
3882       "But it is forbidden because of legacy support.\n";
3883   io_delegate_.SetFileContents("old/android/net/UidRangeParcel.aidl",
3884                                "package android.net; parcelable UidRangeParcel { int A = 1; }");
3885   io_delegate_.SetFileContents(
3886       "new/android/net/UidRangeParcel.aidl",
3887       "package android.net; parcelable UidRangeParcel { int A = 1; int B = 2; }");
3888   CaptureStderr();
3889   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3890   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3891 }
3892 
TEST_F(AidlTestIncompatibleChanges,FixedSizeRemovedField)3893 TEST_F(AidlTestIncompatibleChanges, FixedSizeRemovedField) {
3894   const string expected_stderr =
3895       "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is reduced from 2 to 1.\n";
3896   io_delegate_.SetFileContents("old/p/Foo.aidl",
3897                                "package p; @FixedSize parcelable Foo { int A = 1; int B = 1; }");
3898   io_delegate_.SetFileContents("new/p/Foo.aidl",
3899                                "package p; @FixedSize parcelable Foo { int A = 1; }");
3900   CaptureStderr();
3901   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3902   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3903 }
3904 
TEST_F(AidlTestIncompatibleChanges,IncompatibleChangesInNestedType)3905 TEST_F(AidlTestIncompatibleChanges, IncompatibleChangesInNestedType) {
3906   const string expected_stderr =
3907       "ERROR: new/p/Foo.aidl:1.33-37: Number of fields in p.Foo is reduced from 2 to 1.\n";
3908   io_delegate_.SetFileContents("old/p/Foo.aidl",
3909                                "package p;\n"
3910                                "parcelable Foo {\n"
3911                                "  interface IBar {\n"
3912                                "    void foo();"
3913                                "  }\n"
3914                                "}");
3915   io_delegate_.SetFileContents("new/p/Foo.aidl",
3916                                "package p;\n"
3917                                "parcelable Foo {\n"
3918                                "  interface IBar {\n"
3919                                "    void foo(int n);"  // incompatible: signature changed
3920                                "  }\n"
3921                                "}");
3922   CaptureStderr();
3923   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3924   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Removed or changed method: p.Foo.IBar.foo()"));
3925 }
3926 
TEST_F(AidlTestIncompatibleChanges,IncompatibleTwoWayToOneWay)3927 TEST_F(AidlTestIncompatibleChanges, IncompatibleTwoWayToOneWay) {
3928   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
3929   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ oneway void foo();}");
3930 
3931   CaptureStderr();
3932   EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
3933   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Oneway attribute added: p.IFoo.foo()"));
3934 }
3935 
TEST_F(AidlTestCompatibleChanges,CompatibleOneWayToTwoWay)3936 TEST_F(AidlTestCompatibleChanges, CompatibleOneWayToTwoWay) {
3937   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ oneway void foo();}");
3938   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo();}");
3939 
3940   EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
3941 }
3942 
TEST_P(AidlTest,RejectNonFixedSizeFromFixedSize)3943 TEST_P(AidlTest, RejectNonFixedSizeFromFixedSize) {
3944   const string expected_stderr =
3945       "ERROR: Foo.aidl:2.8-10: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3946       "a.\n"
3947       "ERROR: Foo.aidl:3.6-8: The @FixedSize parcelable 'Foo' has a non-fixed size field named b.\n"
3948       "ERROR: Foo.aidl:4.9-11: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3949       "c.\n"
3950       "ERROR: Foo.aidl:5.23-25: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3951       "d.\n"
3952       "ERROR: Foo.aidl:6.10-12: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3953       "e.\n"
3954       "ERROR: Foo.aidl:7.15-17: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3955       "f.\n"
3956       "ERROR: Foo.aidl:9.23-33: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3957       "nullable1.\n"
3958       "ERROR: Foo.aidl:10.34-44: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3959       "nullable2.\n";
3960 
3961   io_delegate_.SetFileContents("Foo.aidl",
3962                                "@FixedSize parcelable Foo {\n"
3963                                "  int[] a;\n"
3964                                "  Bar b;\n"
3965                                "  String c;\n"
3966                                "  ParcelFileDescriptor d;\n"
3967                                "  IBinder e;\n"
3968                                "  List<String> f;\n"
3969                                "  int isFixedSize;\n"
3970                                "  @nullable OtherFixed nullable1;\n"
3971                                "  @nullable(heap=true) OtherFixed nullable2;\n"
3972                                "  float[16] floats;\n"
3973                                "}");
3974   io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { int a; }");
3975   io_delegate_.SetFileContents("OtherFixed.aidl", "@FixedSize parcelable OtherFixed { int a; }");
3976   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
3977 
3978   CaptureStderr();
3979   EXPECT_FALSE(compile_aidl(options, io_delegate_));
3980   EXPECT_EQ(expected_stderr, GetCapturedStderr());
3981 }
3982 
TEST_P(AidlTest,RejectNonFixedSizeFromFixedSize_Union)3983 TEST_P(AidlTest, RejectNonFixedSizeFromFixedSize_Union) {
3984   const string expected_stderr =
3985       "ERROR: Foo.aidl:2.8-10: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3986       "a.\n"
3987       "ERROR: Foo.aidl:3.6-8: The @FixedSize parcelable 'Foo' has a non-fixed size field named b.\n"
3988       "ERROR: Foo.aidl:4.9-11: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3989       "c.\n"
3990       "ERROR: Foo.aidl:5.23-25: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3991       "d.\n"
3992       "ERROR: Foo.aidl:6.10-12: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3993       "e.\n"
3994       "ERROR: Foo.aidl:7.15-17: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3995       "f.\n"
3996       "ERROR: Foo.aidl:9.23-33: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3997       "nullable1.\n"
3998       "ERROR: Foo.aidl:10.34-44: The @FixedSize parcelable 'Foo' has a non-fixed size field named "
3999       "nullable2.\n";
4000 
4001   io_delegate_.SetFileContents("Foo.aidl",
4002                                "@FixedSize union Foo {\n"
4003                                "  int[] a = {};\n"
4004                                "  Bar b;\n"
4005                                "  String c;\n"
4006                                "  ParcelFileDescriptor d;\n"
4007                                "  IBinder e;\n"
4008                                "  List<String> f;\n"
4009                                "  int isFixedSize;\n"
4010                                "  @nullable OtherFixed nullable1;\n"
4011                                "  @nullable(heap=true) OtherFixed nullable2;\n"
4012                                "  float[16] floats;\n"
4013                                "}");
4014   io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { int a; }");
4015   io_delegate_.SetFileContents("OtherFixed.aidl", "@FixedSize parcelable OtherFixed { int a; }");
4016   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
4017 
4018   CaptureStderr();
4019   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4020   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4021 }
4022 
TEST_P(AidlTest,AcceptFixedSizeFromFixedSize)4023 TEST_P(AidlTest, AcceptFixedSizeFromFixedSize) {
4024   const string expected_stderr = "";
4025 
4026   io_delegate_.SetFileContents("Foo.aidl", "@FixedSize parcelable Foo { int a; Bar b; }");
4027   io_delegate_.SetFileContents("Bar.aidl", "@FixedSize parcelable Bar { Val c; }");
4028   io_delegate_.SetFileContents("Val.aidl", "enum Val { A, B, }");
4029   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
4030 
4031   CaptureStderr();
4032   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4033   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4034 }
4035 
TEST_F(AidlTest,RejectAmbiguousImports)4036 TEST_F(AidlTest, RejectAmbiguousImports) {
4037   const string expected_stderr =
4038       "ERROR: p/IFoo.aidl: Duplicate files found for q.IBar from:\n"
4039       "dir1/q/IBar.aidl\n"
4040       "dir2/q/IBar.aidl\n";
4041   Options options = Options::From("aidl --lang=java -o out -I . -I dir1 -I dir2 p/IFoo.aidl");
4042   io_delegate_.SetFileContents("p/IFoo.aidl", "package p; import q.IBar; interface IFoo{}");
4043   io_delegate_.SetFileContents("dir1/q/IBar.aidl", "package q; interface IBar{}");
4044   io_delegate_.SetFileContents("dir2/q/IBar.aidl", "package q; interface IBar{}");
4045 
4046   CaptureStderr();
4047   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4048   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4049 }
4050 
TEST_F(AidlTest,HandleManualIdAssignments)4051 TEST_F(AidlTest, HandleManualIdAssignments) {
4052   const string expected_stderr =
4053       "ERROR: new/p/IFoo.aidl:1.32-36: Transaction ID changed: p.IFoo.foo() is changed from 10 to "
4054       "11.\n";
4055   Options options = Options::From("aidl --checkapi old new");
4056   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
4057   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 10;}");
4058 
4059   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
4060 
4061   io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{ void foo() = 11;}");
4062   CaptureStderr();
4063   EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
4064   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4065 }
4066 
TEST_P(AidlTest,ParcelFileDescriptorIsBuiltinType)4067 TEST_P(AidlTest, ParcelFileDescriptorIsBuiltinType) {
4068   Options options =
4069       Options::From("aidl -I . --lang=" + to_string(GetLanguage()) + " -h out -o out p/IFoo.aidl");
4070 
4071   // use without import
4072   io_delegate_.SetFileContents("p/IFoo.aidl",
4073                                "package p; interface IFoo{ void foo(in ParcelFileDescriptor fd);}");
4074   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4075 
4076   // capture output files
4077   map<string, string> outputs = io_delegate_.OutputFiles();
4078 
4079   // use without import but with full name
4080   io_delegate_.SetFileContents(
4081       "p/IFoo.aidl",
4082       "package p; interface IFoo{ void foo(in android.os.ParcelFileDescriptor fd);}");
4083   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4084   // output files should be the same
4085   EXPECT_EQ(outputs, io_delegate_.OutputFiles());
4086 
4087   // use with import (as before)
4088   io_delegate_.SetFileContents("p/IFoo.aidl",
4089                                "package p;"
4090                                "import android.os.ParcelFileDescriptor;"
4091                                "interface IFoo{"
4092                                "  void foo(in ParcelFileDescriptor fd);"
4093                                "}");
4094   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4095   // output files should be the same
4096   EXPECT_EQ(outputs, io_delegate_.OutputFiles());
4097 }
4098 
TEST_P(AidlTest,RejectsOutputParcelFileDescriptor)4099 TEST_P(AidlTest, RejectsOutputParcelFileDescriptor) {
4100   Options options = Options::From("aidl p/IFoo.aidl -I . --lang=" + to_string(GetLanguage()));
4101   CaptureStderr();
4102   io_delegate_.SetFileContents("p/IFoo.aidl",
4103                                "package p;"
4104                                "interface IFoo{"
4105                                "  void foo(out ParcelFileDescriptor fd);"
4106                                "}");
4107   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4108   EXPECT_THAT(GetCapturedStderr(), HasSubstr("can't be an out parameter"));
4109 }
4110 
TEST_P(AidlTest,RejectsArgumentDirectionNotSpecified)4111 TEST_P(AidlTest, RejectsArgumentDirectionNotSpecified) {
4112   Options options = Options::From("aidl p/IFoo.aidl -I . --lang=" + to_string(GetLanguage()));
4113   CaptureStderr();
4114   io_delegate_.SetFileContents("p/IFoo.aidl",
4115                                "package p;"
4116                                "interface IFoo{"
4117                                "  void foo(ParcelFileDescriptor fd);"
4118                                "}");
4119   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4120   EXPECT_THAT(GetCapturedStderr(),
4121               HasSubstr("ParcelFileDescriptor can be an in or inout parameter."));
4122 }
4123 
TEST_F(AidlTest,ManualIds)4124 TEST_F(AidlTest, ManualIds) {
4125   Options options = Options::From("aidl --lang=java -I . -o out IFoo.aidl");
4126   io_delegate_.SetFileContents("IFoo.aidl",
4127                                "interface IFoo {\n"
4128                                "  void foo() = 0;\n"
4129                                "  void bar() = 1;\n"
4130                                "}");
4131   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4132 }
4133 
TEST_F(AidlTest,ManualIdsWithMetaTransactions)4134 TEST_F(AidlTest, ManualIdsWithMetaTransactions) {
4135   Options options = Options::From("aidl --lang=java -I . --version 10 -o out IFoo.aidl");
4136   io_delegate_.SetFileContents("IFoo.aidl",
4137                                "interface IFoo {\n"
4138                                "  void foo() = 0;\n"
4139                                "  void bar() = 1;\n"
4140                                "}");
4141   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4142 }
4143 
TEST_F(AidlTest,FailOnDuplicatedIds)4144 TEST_F(AidlTest, FailOnDuplicatedIds) {
4145   const string expected_stderr =
4146       "ERROR: IFoo.aidl:3.7-11: Found duplicate method id (3) for method bar\n";
4147   Options options = Options::From("aidl --lang=java -I . --version 10 -o out IFoo.aidl");
4148   io_delegate_.SetFileContents("IFoo.aidl",
4149                                "interface IFoo {\n"
4150                                "  void foo() = 3;\n"
4151                                "  void bar() = 3;\n"
4152                                "}");
4153   CaptureStderr();
4154   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4155   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4156 }
4157 
TEST_F(AidlTest,FailOnOutOfRangeIds)4158 TEST_F(AidlTest, FailOnOutOfRangeIds) {
4159   // 16777115 is kLastMetaMethodId + 1
4160   const string expected_stderr =
4161       "ERROR: IFoo.aidl:3.7-11: Found out of bounds id (16777115) for method bar. "
4162       "Value for id must be between 0 and 16777114 inclusive.\n";
4163   Options options = Options::From("aidl --lang=java -I . --version 10 -o out IFoo.aidl");
4164   io_delegate_.SetFileContents("IFoo.aidl",
4165                                "interface IFoo {\n"
4166                                "  void foo() = 3;\n"
4167                                "  void bar() = 16777115;\n"
4168                                "}");
4169   CaptureStderr();
4170   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4171   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4172 }
4173 
TEST_F(AidlTest,FailOnPartiallyAssignedIds)4174 TEST_F(AidlTest, FailOnPartiallyAssignedIds) {
4175   const string expected_stderr =
4176       "ERROR: IFoo.aidl:3.7-11: You must either assign id's to all methods or to none of them.\n";
4177   Options options = Options::From("aidl --lang=java -I . --version 10 -o out IFoo.aidl");
4178   io_delegate_.SetFileContents("IFoo.aidl",
4179                                "interface IFoo {\n"
4180                                "  void foo() = 3;\n"
4181                                "  void bar();\n"
4182                                "}");
4183   CaptureStderr();
4184   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4185   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4186 }
4187 
TEST_F(AidlTest,AssignedIds)4188 TEST_F(AidlTest, AssignedIds) {
4189   CaptureStderr();
4190   EXPECT_NE(nullptr, Parse("IFoo.aidl",
4191                            "interface IFoo {\n"
4192                            "  void foo();\n"
4193                            "  void bar();\n"
4194                            "  interface INested {\n"
4195                            "    void foo();\n"
4196                            "    void bar();\n"
4197                            "  }\n"
4198                            "}",
4199                            typenames_, Options::Language::JAVA));
4200   EXPECT_EQ("", GetCapturedStderr());
4201   auto foo = typenames_.ResolveTypename("IFoo").defined_type;
4202   ASSERT_EQ(2u, foo->GetMethods().size());
4203   EXPECT_EQ(0, foo->GetMethods()[0]->GetId());
4204   EXPECT_EQ(1, foo->GetMethods()[1]->GetId());
4205   auto nested = typenames_.ResolveTypename("IFoo.INested").defined_type;
4206   ASSERT_EQ(2u, nested->GetMethods().size());
4207   EXPECT_EQ(0, nested->GetMethods()[0]->GetId());
4208   EXPECT_EQ(1, nested->GetMethods()[1]->GetId());
4209 }
4210 
TEST_F(AidlTest,AllowDuplicatedImportPaths)4211 TEST_F(AidlTest, AllowDuplicatedImportPaths) {
4212   Options options = Options::From("aidl --lang=java -I . -I dir -I dir IFoo.aidl");
4213   io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
4214   io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
4215   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4216 }
4217 
TEST_F(AidlTest,UnusedImportDoesNotContributeInclude)4218 TEST_F(AidlTest, UnusedImportDoesNotContributeInclude) {
4219   io_delegate_.SetFileContents("a/b/IFoo.aidl",
4220                                "package a.b;\n"
4221                                "import a.b.IBar;\n"
4222                                "import a.b.IQux;\n"
4223                                "interface IFoo { IQux foo(); }\n");
4224   io_delegate_.SetFileContents("a/b/IBar.aidl", "package a.b; interface IBar { void foo(); }");
4225   io_delegate_.SetFileContents("a/b/IQux.aidl", "package a.b; interface IQux { void foo(); }");
4226 
4227   Options options = Options::From("aidl --lang=ndk a/b/IFoo.aidl -I . -o out -h out/include");
4228   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4229 
4230   string output;
4231   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/include/aidl/a/b/IFoo.h", &output));
4232   // IBar was imported but wasn't used. include is not expected.
4233   EXPECT_THAT(output, Not(testing::HasSubstr("#include <aidl/a/b/IBar.h>")));
4234   // IBar was imported and used. include is expected.
4235   EXPECT_THAT(output, (testing::HasSubstr("#include <aidl/a/b/IQux.h>")));
4236 }
4237 
TEST_F(AidlTest,BasePathAsImportPath)4238 TEST_F(AidlTest, BasePathAsImportPath) {
4239   Options options = Options::From("aidl --lang=java -I some -I other some/dir/pkg/name/IFoo.aidl");
4240   io_delegate_.SetFileContents("some/dir/pkg/name/IFoo.aidl",
4241                                "package pkg.name; interface IFoo { void foo(); }");
4242   const string expected_stderr =
4243       "ERROR: some/dir/pkg/name/IFoo.aidl:1.18-28: directory some/dir/ is not found in any of "
4244       "the import paths:\n - other/\n - some/\n";
4245   CaptureStderr();
4246   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4247   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4248 }
4249 
TEST_F(AidlTest,ParseJavaPassthroughAnnotation)4250 TEST_F(AidlTest, ParseJavaPassthroughAnnotation) {
4251   io_delegate_.SetFileContents("a/IFoo.aidl", R"--(package a;
4252     import a.MyEnum;
4253     @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
4254     @JavaPassthrough(annotation="@com.android.AliceTwo")
4255     interface IFoo {
4256         @JavaPassthrough(annotation="@com.android.Bob")
4257         void foo(@JavaPassthrough(annotation="@com.android.Cat") int x, MyEnum y);
4258         const @JavaPassthrough(annotation="@com.android.David") int A = 3;
4259     })--");
4260   // JavaPassthrough should work with other types as well (e.g. enum)
4261   io_delegate_.SetFileContents("a/MyEnum.aidl", R"--(package a;
4262     @JavaPassthrough(annotation="@com.android.Alice(arg=com.android.Alice.Value.A)")
4263     @JavaPassthrough(annotation="@com.android.AliceTwo")
4264     @Backing(type="byte")
4265     enum MyEnum {
4266       a, b, c
4267     })--");
4268 
4269   Options java_options = Options::From("aidl -I . --lang=java -o out a/IFoo.aidl a/MyEnum.aidl");
4270   EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
4271 
4272   string java_out;
4273   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/IFoo.java", &java_out));
4274   // type-decl-level annotations with newline at the end
4275   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
4276   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
4277   // member-decl-level annotations with newline at the end
4278   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Bob\n"));
4279   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.David\n"));
4280   // inline annotations with space at the end
4281   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Cat "));
4282 
4283   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/MyEnum.java", &java_out));
4284   // type-decl-level annotations with newline at the end
4285   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.Alice(arg=com.android.Alice.Value.A)\n"));
4286   EXPECT_THAT(java_out, testing::HasSubstr("@com.android.AliceTwo\n"));
4287 
4288   // Other backends shouldn't be bothered
4289   Options cpp_options =
4290       Options::From("aidl -I . --lang=cpp -o out -h out a/IFoo.aidl a/MyEnum.aidl");
4291   EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
4292 
4293   Options ndk_options =
4294       Options::From("aidl -I . --lang=ndk -o out -h out a/IFoo.aidl a/MyEnum.aidl");
4295   EXPECT_TRUE(compile_aidl(ndk_options, io_delegate_));
4296 
4297   Options rust_options = Options::From("aidl -I . --lang=rust -o out a/IFoo.aidl a/MyEnum.aidl");
4298   EXPECT_TRUE(compile_aidl(rust_options, io_delegate_));
4299 }
4300 
TEST_F(AidlTest,ParseRustDerive)4301 TEST_F(AidlTest, ParseRustDerive) {
4302   io_delegate_.SetFileContents("a/Foo.aidl", R"(package a;
4303     @RustDerive(Clone=true, Copy=false)
4304     parcelable Foo {
4305         int a;
4306     })");
4307 
4308   Options rust_options = Options::From("aidl -I . --lang=rust -o out a/Foo.aidl");
4309   EXPECT_TRUE(compile_aidl(rust_options, io_delegate_));
4310 
4311   string rust_out;
4312   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.rs", &rust_out));
4313   EXPECT_THAT(rust_out, testing::HasSubstr("#[derive(Debug, Clone)]"));
4314 
4315   // Other backends shouldn't be bothered
4316   Options cpp_options = Options::From("aidl --lang=cpp -I . -o out -h out a/Foo.aidl");
4317   EXPECT_TRUE(compile_aidl(cpp_options, io_delegate_));
4318 
4319   Options ndk_options = Options::From("aidl --lang=ndk -I . -o out -h out a/Foo.aidl");
4320   EXPECT_TRUE(compile_aidl(ndk_options, io_delegate_));
4321 
4322   Options java_options = Options::From("aidl --lang=java -I . -o out a/Foo.aidl");
4323   EXPECT_TRUE(compile_aidl(java_options, io_delegate_));
4324 }
4325 
TEST_P(AidlTest,TypesShouldHaveRustDerive)4326 TEST_P(AidlTest, TypesShouldHaveRustDerive) {
4327   CaptureStderr();
4328   string code =
4329       "@RustDerive(PartialEq=true)\n"
4330       "parcelable Foo {\n"
4331       "  parcelable Bar {}\n"
4332       "  Bar bar;\n"
4333       "}";
4334   EXPECT_EQ(nullptr, Parse("Foo.aidl", code, typenames_, GetLanguage(), nullptr, {}));
4335   EXPECT_THAT(
4336       GetCapturedStderr(),
4337       testing::HasSubstr("Field bar of type with @RustDerive PartialEq also needs to derive this"));
4338 }
4339 
TEST_F(AidlTest,EmptyEnforceAnnotation)4340 TEST_F(AidlTest, EmptyEnforceAnnotation) {
4341   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4342     interface IFoo {
4343         @EnforcePermission()
4344         void Protected();
4345     })");
4346 
4347   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4348   CaptureStderr();
4349   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4350   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Unable to parse @EnforcePermission annotation"));
4351 }
4352 
TEST_F(AidlTest,InterfaceEnforceCondition)4353 TEST_F(AidlTest, InterfaceEnforceCondition) {
4354   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4355     @EnforcePermission("INTERNET")
4356     interface IFoo {
4357         void Protected();
4358     })");
4359 
4360   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4361   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4362 }
4363 
TEST_F(AidlTest,EnforceConditionAny)4364 TEST_F(AidlTest, EnforceConditionAny) {
4365   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4366     interface IFoo {
4367         @EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"})
4368         void Protected();
4369     })");
4370 
4371   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4372   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4373 }
4374 
TEST_F(AidlTest,EnforceConditionAll)4375 TEST_F(AidlTest, EnforceConditionAll) {
4376   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4377     interface IFoo {
4378         @EnforcePermission(allOf={"INTERNET", "READ_PHONE_STATE"})
4379         void Protected();
4380     })");
4381 
4382   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4383   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4384 }
4385 
TEST_F(AidlTest,InterfaceAndMethodEnforceCondition)4386 TEST_F(AidlTest, InterfaceAndMethodEnforceCondition) {
4387   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4388     @EnforcePermission("INTERNET")
4389     interface IFoo {
4390         @EnforcePermission("SYSTEM_UID")
4391         void Protected();
4392     })");
4393 
4394   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4395   CaptureStderr();
4396   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4397   EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4398                                              "the method Protected is also annotated"));
4399 }
4400 
TEST_F(AidlTest,NoPermissionInterfaceEnforceMethod)4401 TEST_F(AidlTest, NoPermissionInterfaceEnforceMethod) {
4402   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4403     @RequiresNoPermission
4404     interface IFoo {
4405         @EnforcePermission("INTERNET")
4406         void Protected();
4407     })");
4408 
4409   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4410   CaptureStderr();
4411   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4412   EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4413                                              "the method Protected is also annotated"));
4414 }
4415 
TEST_F(AidlTest,ManualPermissionInterfaceEnforceMethod)4416 TEST_F(AidlTest, ManualPermissionInterfaceEnforceMethod) {
4417   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4418     @PermissionManuallyEnforced
4419     interface IFoo {
4420         @EnforcePermission("INTERNET")
4421         void Protected();
4422     })");
4423 
4424   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4425   CaptureStderr();
4426   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4427   EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4428                                              "the method Protected is also annotated"));
4429 }
4430 
TEST_F(AidlTest,EnforceInterfaceNoPermissionsMethod)4431 TEST_F(AidlTest, EnforceInterfaceNoPermissionsMethod) {
4432   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4433     @EnforcePermission("INTERNET")
4434     interface IFoo {
4435         @RequiresNoPermission
4436         void Protected();
4437     })");
4438 
4439   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4440   CaptureStderr();
4441   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4442   EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4443                                              "the method Protected is also annotated"));
4444 }
4445 
TEST_F(AidlTest,EnforceInterfaceManualPermissionMethod)4446 TEST_F(AidlTest, EnforceInterfaceManualPermissionMethod) {
4447   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4448     @EnforcePermission("INTERNET")
4449     interface IFoo {
4450         @PermissionManuallyEnforced
4451         void Protected();
4452     })");
4453 
4454   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4455   CaptureStderr();
4456   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4457   EXPECT_THAT(GetCapturedStderr(), HasSubstr("The interface IFoo uses a permission annotation but "
4458                                              "the method Protected is also annotated"));
4459 }
4460 
TEST_F(AidlTest,JavaSuppressLint)4461 TEST_F(AidlTest, JavaSuppressLint) {
4462   io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
4463     @JavaSuppressLint({"NewApi"})
4464     interface IFoo {
4465     })");
4466 
4467   Options options = Options::From("aidl --lang=java -I . -o out a/IFoo.aidl");
4468   CaptureStderr();
4469   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4470   EXPECT_EQ(GetCapturedStderr(), "");
4471   string code;
4472   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/IFoo.java", &code));
4473   EXPECT_THAT(code, HasSubstr("@android.annotation.SuppressLint(value = {\"NewApi\"})"));
4474 }
4475 
4476 class AidlOutputPathTest : public AidlTest {
4477  protected:
SetUp()4478   void SetUp() override {
4479     AidlTest::SetUp();
4480     io_delegate_.SetFileContents("sub/dir/foo/bar/IFoo.aidl", "package foo.bar; interface IFoo {}");
4481   }
4482 
Test(const Options & options,const std::string expected_output_path)4483   void Test(const Options& options, const std::string expected_output_path) {
4484     EXPECT_TRUE(compile_aidl(options, io_delegate_));
4485     // check the existence
4486     EXPECT_TRUE(io_delegate_.GetWrittenContents(expected_output_path, nullptr));
4487   }
4488 };
4489 
TEST_F(AidlOutputPathTest,OutDirWithNoOutputFile)4490 TEST_F(AidlOutputPathTest, OutDirWithNoOutputFile) {
4491   // <out_dir> / <package_name> / <type_name>.java
4492   Test(Options::From("aidl -I sub/dir -o out sub/dir/foo/bar/IFoo.aidl"), "out/foo/bar/IFoo.java");
4493 }
4494 
TEST_F(AidlOutputPathTest,OutDirWithOutputFile)4495 TEST_F(AidlOutputPathTest, OutDirWithOutputFile) {
4496   // when output file is explicitly set, it is always respected. -o option is
4497   // ignored.
4498   Test(Options::From("aidl -I sub/dir -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"),
4499        "output/IFoo.java");
4500 }
4501 
TEST_F(AidlOutputPathTest,NoOutDirWithOutputFile)4502 TEST_F(AidlOutputPathTest, NoOutDirWithOutputFile) {
4503   Test(Options::From("aidl -I sub/dir -o out sub/dir/foo/bar/IFoo.aidl output/IFoo.java"),
4504        "output/IFoo.java");
4505 }
4506 
TEST_F(AidlOutputPathTest,NoOutDirWithNoOutputFile)4507 TEST_F(AidlOutputPathTest, NoOutDirWithNoOutputFile) {
4508   // output is the same as the input file except for the suffix
4509   Test(Options::From("aidl -I sub/dir sub/dir/foo/bar/IFoo.aidl"), "sub/dir/foo/bar/IFoo.java");
4510 }
4511 
TEST_P(AidlTest,PassOnValidUnsignedInt32Int)4512 TEST_P(AidlTest, PassOnValidUnsignedInt32Int) {
4513   EvaluateValidAssignment(
4514       R"(package a; interface IFoo { const int UINT32_VALUE = 2147483650u32; })", "", typenames_,
4515       GetLanguage());
4516 }
4517 
TEST_P(AidlTest,FailOnOutOfBoundsUInt32MaxConstInt)4518 TEST_P(AidlTest, FailOnOutOfBoundsUInt32MaxConstInt) {
4519   AidlError error;
4520   const string expected_stderr =
4521       "ERROR: p/IFoo.aidl:3.59-73: Could not parse integer: 4294967300u32\n";
4522   CaptureStderr();
4523   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4524                            R"(package p;
4525                               interface IFoo {
4526                                 const int uint32_max_oob = 4294967300u32;
4527                               }
4528                              )",
4529                            typenames_, GetLanguage(), &error));
4530   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4531   EXPECT_EQ(AidlError::PARSE_ERROR, error);
4532 }
4533 
TEST_P(AidlTest,PassOnValidUnsignedInt64Int)4534 TEST_P(AidlTest, PassOnValidUnsignedInt64Int) {
4535   EvaluateValidAssignment(
4536       R"(package a; interface IFoo { const long UINT64_VALUE = 18446744073709551615u64; })", "",
4537       typenames_, GetLanguage());
4538 }
4539 
TEST_P(AidlTest,FailOnOutOfBoundsUInt64MaxConstInt)4540 TEST_P(AidlTest, FailOnOutOfBoundsUInt64MaxConstInt) {
4541   AidlError error;
4542   const string expected_stderr =
4543       "ERROR: p/IFoo.aidl:3.60-84: Could not parse integer: 18446744073709551620u64\n";
4544   CaptureStderr();
4545   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4546                            R"(package p;
4547                               interface IFoo {
4548                                 const long uint64_max_oob = 18446744073709551620u64;
4549                               }
4550                              )",
4551                            typenames_, GetLanguage(), &error));
4552   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4553   EXPECT_EQ(AidlError::PARSE_ERROR, error);
4554 }
4555 
TEST_P(AidlTest,PassOnValidUnsignedInt32Hex)4556 TEST_P(AidlTest, PassOnValidUnsignedInt32Hex) {
4557   EvaluateValidAssignment(
4558       R"(package a; interface IFoo { const int UINT32_VALUE = 0xffffffffu32; })", "", typenames_,
4559       GetLanguage());
4560 }
4561 
TEST_P(AidlTest,FailOnOutOfBoundsUInt32MaxConstHex)4562 TEST_P(AidlTest, FailOnOutOfBoundsUInt32MaxConstHex) {
4563   AidlError error;
4564   const string expected_stderr =
4565       "ERROR: p/IFoo.aidl:3.59-74: Invalid type specifier for an int64 literal: int "
4566       "(0xfffffffffu32).\n";
4567   CaptureStderr();
4568   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4569                            R"(package p;
4570                               interface IFoo {
4571                                 const int uint32_max_oob = 0xfffffffffu32;
4572                               }
4573                              )",
4574                            typenames_, GetLanguage(), &error));
4575   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4576   EXPECT_EQ(AidlError::BAD_TYPE, error);
4577 }
4578 
TEST_P(AidlTest,PassOnValidUnsignedInt64Hex)4579 TEST_P(AidlTest, PassOnValidUnsignedInt64Hex) {
4580   EvaluateValidAssignment(
4581       R"(package a; interface IFoo { const int UINT64_VALUE = 0xffffffffffffffffu64; })", "",
4582       typenames_, GetLanguage());
4583 }
4584 
TEST_P(AidlTest,FailOnOutOfBoundsUInt64MaxConstHex)4585 TEST_P(AidlTest, FailOnOutOfBoundsUInt64MaxConstHex) {
4586   AidlError error;
4587   const string expected_stderr =
4588       "ERROR: p/IFoo.aidl:3.59-82: Could not parse hexvalue: 0xfffffffffffffffffu64\n";
4589   CaptureStderr();
4590   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4591                            R"(package p;
4592                               interface IFoo {
4593                                 const int uint64_max_oob = 0xfffffffffffffffffu64;
4594                               }
4595                              )",
4596                            typenames_, GetLanguage(), &error));
4597   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4598   EXPECT_EQ(AidlError::PARSE_ERROR, error);
4599 }
4600 
TEST_P(AidlTest,FailOnOutOfBoundsInt32MaxConstInt)4601 TEST_P(AidlTest, FailOnOutOfBoundsInt32MaxConstInt) {
4602   AidlError error;
4603   const string expected_stderr =
4604       "ERROR: p/IFoo.aidl:3.58-69: Invalid type specifier for an int64 literal: int "
4605       "(2147483650). Did you mean: 2147483650u32?\n";
4606   CaptureStderr();
4607   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4608                            R"(package p;
4609                               interface IFoo {
4610                                 const int int32_max_oob = 2147483650;
4611                               }
4612                              )",
4613                            typenames_, GetLanguage(), &error));
4614   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4615   EXPECT_EQ(AidlError::BAD_TYPE, error);
4616 }
4617 
TEST_P(AidlTest,FailOnOutOfBoundsInt32MinConstInt)4618 TEST_P(AidlTest, FailOnOutOfBoundsInt32MinConstInt) {
4619   AidlError error;
4620   const string expected_stderr =
4621       "ERROR: p/IFoo.aidl:3.58-60: Invalid type specifier for an int64 literal: int "
4622       "(-2147483650).\n";
4623   CaptureStderr();
4624   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4625                            R"(package p;
4626                               interface IFoo {
4627                                 const int int32_min_oob = -2147483650;
4628                               }
4629                              )",
4630                            typenames_, GetLanguage(), &error));
4631   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4632   EXPECT_EQ(AidlError::BAD_TYPE, error);
4633 }
4634 
TEST_P(AidlTest,FailOnOutOfBoundsInt64MaxConstInt)4635 TEST_P(AidlTest, FailOnOutOfBoundsInt64MaxConstInt) {
4636   AidlError error;
4637   const string expected_stderr =
4638       "ERROR: p/IFoo.aidl:3.59-86: Could not parse integer: 21474836509999999999999999\n";
4639   CaptureStderr();
4640   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4641                            R"(package p;
4642                               interface IFoo {
4643                                 const long int64_max_oob = 21474836509999999999999999;
4644                               }
4645                              )",
4646                            typenames_, GetLanguage(), &error));
4647   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4648   EXPECT_EQ(AidlError::PARSE_ERROR, error);
4649 }
4650 
TEST_P(AidlTest,FailOnOutOfBoundsInt64MinConstInt)4651 TEST_P(AidlTest, FailOnOutOfBoundsInt64MinConstInt) {
4652   AidlError error;
4653   const string expected_stderr =
4654       "ERROR: p/IFoo.aidl:3.61-87: Could not parse integer: 21474836509999999999999999\n";
4655   CaptureStderr();
4656   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
4657                            R"(package p;
4658                               interface IFoo {
4659                                 const long int64_min_oob = -21474836509999999999999999;
4660                               }
4661                              )",
4662                            typenames_, GetLanguage(), &error));
4663   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4664   EXPECT_EQ(AidlError::PARSE_ERROR, error);
4665 }
4666 
TEST_P(AidlTest,FailOnOutOfBoundsAutofilledEnum)4667 TEST_P(AidlTest, FailOnOutOfBoundsAutofilledEnum) {
4668   AidlError error;
4669   const string expected_stderr =
4670       "ERROR: p/TestEnum.aidl:5.1-36: Invalid type specifier for an int32 literal: byte (FOO+1).\n"
4671       "ERROR: p/TestEnum.aidl:5.1-36: Enumerator type differs from enum backing type.\n";
4672   CaptureStderr();
4673   EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
4674                            R"(package p;
4675                               @Backing(type="byte")
4676                               enum TestEnum {
4677                                 FOO = 127,
4678                                 BAR,
4679                               }
4680                              )",
4681                            typenames_, GetLanguage(), &error));
4682   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4683   EXPECT_EQ(AidlError::BAD_TYPE, error);
4684 }
4685 
TEST_P(AidlTest,FailOnUnsupportedBackingType)4686 TEST_P(AidlTest, FailOnUnsupportedBackingType) {
4687   AidlError error;
4688   const string expected_stderr =
4689       "ERROR: p/TestEnum.aidl:3.35-44: Invalid backing type: boolean. Backing type must be one of: "
4690       "byte, int, long\n";
4691   CaptureStderr();
4692   EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
4693                            R"(package p;
4694                               @Backing(type="boolean")
4695                               enum TestEnum {
4696                                 FOO = 0,
4697                                 BAR = 1,
4698                               }
4699                              )",
4700                            typenames_, GetLanguage(), &error));
4701   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4702   EXPECT_EQ(AidlError::BAD_TYPE, error);
4703 }
4704 
TEST_P(AidlTest,UnsupportedBackingAnnotationParam)4705 TEST_P(AidlTest, UnsupportedBackingAnnotationParam) {
4706   AidlError error;
4707   const string expected_stderr =
4708       "ERROR: p/TestEnum.aidl:2.1-51: Parameter foo not supported for annotation Backing. It must "
4709       "be one of: type\n";
4710   CaptureStderr();
4711   EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
4712                            R"(package p;
4713                               @Backing(foo="byte")
4714                               enum TestEnum {
4715                                 FOO = 1,
4716                                 BAR,
4717                               }
4718                              )",
4719                            typenames_, GetLanguage(), &error));
4720   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4721   EXPECT_EQ(AidlError::BAD_TYPE, error);
4722 }
4723 
TEST_P(AidlTest,BackingAnnotationRequireTypeParameter)4724 TEST_P(AidlTest, BackingAnnotationRequireTypeParameter) {
4725   const string expected_stderr = "ERROR: Enum.aidl:1.1-9: Missing 'type' on @Backing.\n";
4726   CaptureStderr();
4727   EXPECT_EQ(nullptr, Parse("Enum.aidl", "@Backing enum Enum { FOO }", typenames_, GetLanguage()));
4728   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4729 }
4730 
TEST_F(AidlTest,SupportJavaOnlyImmutableAnnotation)4731 TEST_F(AidlTest, SupportJavaOnlyImmutableAnnotation) {
4732   io_delegate_.SetFileContents("Foo.aidl",
4733                                "@JavaOnlyImmutable parcelable Foo { int a; Bar b; List<Bar> c; "
4734                                "Map<String, Baz> d; Bar[] e; }");
4735   io_delegate_.SetFileContents("Bar.aidl", "@JavaOnlyImmutable parcelable Bar { String a; }");
4736   io_delegate_.SetFileContents("Baz.aidl",
4737                                "@JavaOnlyImmutable @JavaOnlyStableParcelable parcelable Baz;");
4738   Options options = Options::From("aidl --lang=java -I . Foo.aidl");
4739   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4740 }
4741 
TEST_F(AidlTest,RejectMutableParcelableFromJavaOnlyImmutableParcelable)4742 TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableParcelable) {
4743   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { Bar bar; }");
4744   io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
4745   string expected_error =
4746       "ERROR: Foo.aidl:1.40-44: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
4747       "named 'bar'.\n";
4748   CaptureStderr();
4749   Options options = Options::From("aidl --lang=java Foo.aidl -I .");
4750   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4751   EXPECT_EQ(expected_error, GetCapturedStderr());
4752 }
4753 
TEST_F(AidlTest,JavaOnlyImmutableParcelableWithEnumFields)4754 TEST_F(AidlTest, JavaOnlyImmutableParcelableWithEnumFields) {
4755   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { Bar bar; }");
4756   io_delegate_.SetFileContents("Bar.aidl", "enum Bar { FOO }");
4757   CaptureStderr();
4758   Options options = Options::From("aidl --lang=java Foo.aidl -I .");
4759   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4760   EXPECT_EQ("", GetCapturedStderr());
4761 }
4762 
TEST_F(AidlTest,RejectMutableParcelableFromJavaOnlyImmutableUnion)4763 TEST_F(AidlTest, RejectMutableParcelableFromJavaOnlyImmutableUnion) {
4764   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable union Foo { Bar bar; }");
4765   io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar { String a; }");
4766   string expected_error =
4767       "ERROR: Foo.aidl:1.35-39: The @JavaOnlyImmutable 'Foo' has a non-immutable field "
4768       "named 'bar'.\n";
4769   CaptureStderr();
4770   Options options = Options::From("aidl --lang=java Foo.aidl -I .");
4771   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4772   EXPECT_EQ(expected_error, GetCapturedStderr());
4773 }
4774 
TEST_F(AidlTest,ImmutableParcelableCannotBeInOut)4775 TEST_F(AidlTest, ImmutableParcelableCannotBeInOut) {
4776   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
4777   io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(inout Foo foo); }");
4778   string expected_error =
4779       "ERROR: IBar.aidl:1.35-39: 'foo' can't be an inout parameter because @JavaOnlyImmutable can "
4780       "only be an in parameter.\n";
4781   CaptureStderr();
4782   Options options = Options::From("aidl --lang=java IBar.aidl -I .");
4783   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4784   EXPECT_EQ(expected_error, GetCapturedStderr());
4785 }
4786 
TEST_F(AidlTest,ImmutableParcelableCannotBeOut)4787 TEST_F(AidlTest, ImmutableParcelableCannotBeOut) {
4788   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; }");
4789   io_delegate_.SetFileContents("IBar.aidl", "interface IBar { void my(out Foo foo); }");
4790   string expected_error =
4791       "ERROR: IBar.aidl:1.33-37: 'foo' can't be an out parameter because @JavaOnlyImmutable can "
4792       "only be an in parameter.\n";
4793   CaptureStderr();
4794   Options options = Options::From("aidl --lang=java IBar.aidl -I .");
4795   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4796   EXPECT_EQ(expected_error, GetCapturedStderr());
4797 }
4798 
TEST_F(AidlTest,ImmutableParcelableFieldNameRestriction)4799 TEST_F(AidlTest, ImmutableParcelableFieldNameRestriction) {
4800   io_delegate_.SetFileContents("Foo.aidl", "@JavaOnlyImmutable parcelable Foo { int a; int A; }");
4801   Options options = Options::From("aidl -I . --lang=java Foo.aidl");
4802   const string expected_stderr =
4803       "ERROR: Foo.aidl:1.47-49: 'Foo' has duplicate field name 'A' after capitalizing the first "
4804       "letter\n";
4805   CaptureStderr();
4806   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4807   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4808 }
4809 
TEST_P(AidlTest,UnionInUnion)4810 TEST_P(AidlTest, UnionInUnion) {
4811   import_paths_.insert(".");
4812   io_delegate_.SetFileContents("Bar.aidl", "union Bar { int n = 42; long l; }");
4813   CaptureStderr();
4814   EXPECT_NE(nullptr, Parse("Foo.aidl", "union Foo { Bar b; int n; }", typenames_, GetLanguage()));
4815   EXPECT_THAT("", GetCapturedStderr());
4816 }
4817 
TEST_P(AidlTest,UnionRejectsEmptyDecl)4818 TEST_P(AidlTest, UnionRejectsEmptyDecl) {
4819   const string method = "package a; union Foo {}";
4820   const string expected_stderr = "ERROR: a/Foo.aidl:1.17-21: The union 'Foo' has no fields.\n";
4821   CaptureStderr();
4822   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
4823   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
4824 }
4825 
TEST_P(AidlTest,UnionRejectsParcelableHolder)4826 TEST_P(AidlTest, UnionRejectsParcelableHolder) {
4827   const string method = "package a; union Foo { ParcelableHolder x; }";
4828   const string expected_stderr =
4829       "ERROR: a/Foo.aidl:1.40-42: A union can't have a member of ParcelableHolder 'x'\n";
4830   CaptureStderr();
4831   EXPECT_EQ(nullptr, Parse("a/Foo.aidl", method, typenames_, GetLanguage()));
4832   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_stderr));
4833 }
4834 
TEST_P(AidlTest,UnionRejectsFirstEnumWithNoDefaults)4835 TEST_P(AidlTest, UnionRejectsFirstEnumWithNoDefaults) {
4836   import_paths_.insert(".");
4837   io_delegate_.SetFileContents("a/Enum.aidl", "package a; enum Enum { FOO, BAR }");
4838   const string expected_err = "The union's first member should have a useful default value.";
4839   CaptureStderr();
4840   EXPECT_EQ(nullptr,
4841             Parse("a/Foo.aidl", "package a; union Foo { a.Enum e; }", typenames_, GetLanguage()));
4842   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr(expected_err));
4843 }
4844 
TEST_P(AidlTest,GenericStructuredParcelable)4845 TEST_P(AidlTest, GenericStructuredParcelable) {
4846   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T, U> { int a; int A; }");
4847   Options options = Options::From("aidl -I . Foo.aidl --lang=" + to_string(GetLanguage()));
4848   const string expected_stderr = "";
4849   CaptureStderr();
4850   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4851   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4852 }
4853 
TEST_F(AidlTest,GenericStructuredParcelableWithStringConstants_Cpp)4854 TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Cpp) {
4855   io_delegate_.SetFileContents("Foo.aidl",
4856                                "parcelable Foo<T, U> { int a; const String s = \"\"; }");
4857   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(Options::Language::CPP) +
4858                                   " -o out -h out");
4859   const string expected_stderr = "";
4860   CaptureStderr();
4861   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4862   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4863 
4864   string code;
4865   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
4866   EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
4867 const ::android::String16& Foo<T,U>::s() {
4868   static const ::android::String16 value(::android::String16(""));
4869   return value;
4870 })--"));
4871 }
4872 
TEST_F(AidlTest,GenericStructuredParcelableWithStringConstants_Ndk)4873 TEST_F(AidlTest, GenericStructuredParcelableWithStringConstants_Ndk) {
4874   io_delegate_.SetFileContents("Foo.aidl",
4875                                "parcelable Foo<T, U> { int a; const String s = \"\"; }");
4876   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(Options::Language::NDK) +
4877                                   " -o out -h out");
4878   const string expected_stderr = "";
4879   CaptureStderr();
4880   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4881   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4882 
4883   string code;
4884   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
4885   EXPECT_THAT(code, testing::HasSubstr(R"--(template <typename T, typename U>
4886 const char* Foo<T, U>::s = "";
4887 )--"));
4888 }
4889 
TEST_F(AidlTest,NestedTypeArgs)4890 TEST_F(AidlTest, NestedTypeArgs) {
4891   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<A> { }");
4892   io_delegate_.SetFileContents("a/Baz.aidl", "package a; parcelable Baz<A, B> { }");
4893 
4894   io_delegate_.SetFileContents("a/Foo.aidl",
4895                                "package a; import a.Bar; import a.Baz; parcelable Foo { "
4896                                "Baz<Bar<Bar<String[]>>[], Bar<String>> barss; }");
4897   Options options = Options::From("aidl a/Foo.aidl -I . -o out --lang=java");
4898   const string expected_stderr = "";
4899   CaptureStderr();
4900   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4901   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4902 
4903   string code;
4904   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/a/Foo.java", &code));
4905   EXPECT_THAT(code,
4906               testing::HasSubstr(
4907                   "a.Baz<a.Bar<a.Bar<java.lang.String[]>>[],a.Bar<java.lang.String>> barss;"));
4908 }
4909 
TEST_F(AidlTest,AcceptMultiDimensionalFixedSizeArray)4910 TEST_F(AidlTest, AcceptMultiDimensionalFixedSizeArray) {
4911   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[2][3] a; }");
4912 
4913   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=ndk");
4914   CaptureStderr();
4915   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4916   EXPECT_EQ("", GetCapturedStderr());
4917 }
4918 
TEST_F(AidlTest,AcceptBinarySizeArray)4919 TEST_F(AidlTest, AcceptBinarySizeArray) {
4920   io_delegate_.SetFileContents(
4921       "a/Bar.aidl", "package a; parcelable Bar { const int CONST = 3; String[CONST + 1] a; }");
4922 
4923   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=ndk");
4924   CaptureStderr();
4925   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4926   EXPECT_EQ("", GetCapturedStderr());
4927 }
4928 
TEST_F(AidlTest,AcceptRefSizeArray)4929 TEST_F(AidlTest, AcceptRefSizeArray) {
4930   io_delegate_.SetFileContents(
4931       "a/Bar.aidl", "package a; parcelable Bar { const int CONST = 3; String[CONST] a; }");
4932 
4933   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=ndk");
4934   CaptureStderr();
4935   EXPECT_TRUE(compile_aidl(options, io_delegate_));
4936   EXPECT_EQ("", GetCapturedStderr());
4937 }
4938 
TEST_F(AidlTest,RejectArrayOfFixedSizeArray)4939 TEST_F(AidlTest, RejectArrayOfFixedSizeArray) {
4940   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[2][] a; }");
4941 
4942   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4943   CaptureStderr();
4944   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4945   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Multi-dimensional arrays must be fixed size."));
4946 }
4947 
TEST_F(AidlTest,RejectFixedSizeArrayOfDynamicArray)4948 TEST_F(AidlTest, RejectFixedSizeArrayOfDynamicArray) {
4949   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[][3] a; }");
4950 
4951   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4952   CaptureStderr();
4953   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4954   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Multi-dimensional arrays must be fixed size."));
4955 }
4956 
TEST_F(AidlTest,RejectArrayOfArray)4957 TEST_F(AidlTest, RejectArrayOfArray) {
4958   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[][] a; }");
4959 
4960   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4961   CaptureStderr();
4962   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4963   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Multi-dimensional arrays must be fixed size."));
4964 }
4965 
TEST_F(AidlTest,RejectInvalidArraySize_Negative)4966 TEST_F(AidlTest, RejectInvalidArraySize_Negative) {
4967   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[-1] a; }");
4968 
4969   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4970   CaptureStderr();
4971   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4972   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Array size must be a positive number"));
4973 }
4974 
TEST_F(AidlTest,RejectInvalidArraySize_WrongType)4975 TEST_F(AidlTest, RejectInvalidArraySize_WrongType) {
4976   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { String[\"3\"] a; }");
4977 
4978   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4979   CaptureStderr();
4980   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4981   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Array size must be a positive number"));
4982 }
4983 
TEST_F(AidlTest,DoubleGenericError)4984 TEST_F(AidlTest, DoubleGenericError) {
4985   io_delegate_.SetFileContents("a/Bar.aidl",
4986                                "package a; parcelable Bar { List<String><String> a; }");
4987 
4988   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
4989   const string expected_stderr =
4990       "ERROR: a/Bar.aidl:1.28-33: Can only specify one set of type parameters.\n";
4991   CaptureStderr();
4992   EXPECT_FALSE(compile_aidl(options, io_delegate_));
4993   EXPECT_EQ(expected_stderr, GetCapturedStderr());
4994 }
4995 
TEST_F(AidlTest,ArrayBeforeGenericError)4996 TEST_F(AidlTest, ArrayBeforeGenericError) {
4997   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar { List[]<String> a; }");
4998 
4999   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
5000   CaptureStderr();
5001   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5002   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("syntax error, unexpected '<'"));
5003 }
5004 
TEST_F(AidlTest,NullableArraysAreNotSupported)5005 TEST_F(AidlTest, NullableArraysAreNotSupported) {
5006   io_delegate_.SetFileContents("a/Bar.aidl",
5007                                "package a; parcelable Bar { String @nullable [] a; }");
5008 
5009   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
5010   CaptureStderr();
5011   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5012   EXPECT_THAT(GetCapturedStderr(), testing::HasSubstr("Annotations for arrays are not supported."));
5013 }
5014 
TEST_F(AidlTest,ListOfNullablesAreNotSupported)5015 TEST_F(AidlTest, ListOfNullablesAreNotSupported) {
5016   io_delegate_.SetFileContents("a/Bar.aidl",
5017                                "package a; parcelable Bar { List<@nullable String> a; }");
5018 
5019   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
5020   CaptureStderr();
5021   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5022   EXPECT_THAT(GetCapturedStderr(),
5023               testing::HasSubstr("Annotations for type arguments are not supported."));
5024 }
5025 
TEST_F(AidlTest,DefaultShouldMatchWithFixedSizeArray)5026 TEST_F(AidlTest, DefaultShouldMatchWithFixedSizeArray) {
5027   io_delegate_.SetFileContents("a/Bar.aidl",
5028                                "package a;\n"
5029                                "parcelable Bar {\n"
5030                                "  int[2][3] a = {{1,2,3}, {4,5,6}};\n"
5031                                "}");
5032 
5033   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=ndk");
5034   CaptureStderr();
5035   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5036   EXPECT_EQ("", GetCapturedStderr());
5037 }
5038 
TEST_F(AidlTest,FixedSizeArrayWithWrongTypeDefaultValue)5039 TEST_F(AidlTest, FixedSizeArrayWithWrongTypeDefaultValue) {
5040   io_delegate_.SetFileContents("a/Bar.aidl",
5041                                "package a;\n"
5042                                "parcelable Bar {\n"
5043                                "  int[2][3] a = {{\"1\",\"2\",\"3\"}, {4,5,6}};\n"
5044                                "}");
5045 
5046   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
5047   CaptureStderr();
5048   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5049   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Invalid type specifier for a literal string: int"));
5050 }
5051 
TEST_F(AidlTest,FixedSizeArrayWithMoreElements)5052 TEST_F(AidlTest, FixedSizeArrayWithMoreElements) {
5053   io_delegate_.SetFileContents("a/Bar.aidl",
5054                                "package a;\n"
5055                                "parcelable Bar {\n"
5056                                "  int[2][3] a = {{1,2,3,4}, {4,5,6}};\n"
5057                                "}");
5058 
5059   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
5060   CaptureStderr();
5061   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5062   EXPECT_THAT(GetCapturedStderr(),
5063               HasSubstr("Expected an array of 3 elements, but found one with 4 elements"));
5064 }
5065 
TEST_F(AidlTest,FixedSizeArrayWithFewerElements)5066 TEST_F(AidlTest, FixedSizeArrayWithFewerElements) {
5067   io_delegate_.SetFileContents("a/Bar.aidl",
5068                                "package a;\n"
5069                                "parcelable Bar {\n"
5070                                "  int[2][3] a = {};\n"
5071                                "}");
5072 
5073   Options options = Options::From("aidl a/Bar.aidl -I . -o out --lang=java");
5074   CaptureStderr();
5075   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5076   EXPECT_THAT(GetCapturedStderr(),
5077               HasSubstr("Expected an array of 2 elements, but found one with 0 elements"));
5078 }
5079 
5080 struct GenericAidlTest : ::testing::Test {
5081   FakeIoDelegate io_delegate_;
Compileandroid::aidl::GenericAidlTest5082   void Compile(string cmd) {
5083     io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo { Bar<Baz<Qux>> x; }");
5084     io_delegate_.SetFileContents("Bar.aidl", "parcelable Bar<T> {  }");
5085     io_delegate_.SetFileContents("Baz.aidl", "parcelable Baz<T> {  }");
5086     io_delegate_.SetFileContents("Qux.aidl", "parcelable Qux {  }");
5087 
5088     Options options = Options::From(cmd);
5089     CaptureStderr();
5090     EXPECT_TRUE(compile_aidl(options, io_delegate_));
5091     EXPECT_EQ("", GetCapturedStderr());
5092   }
5093 };
5094 
TEST_F(GenericAidlTest,ImportGenericParameterTypesCPP)5095 TEST_F(GenericAidlTest, ImportGenericParameterTypesCPP) {
5096   Compile("aidl Foo.aidl --lang=cpp -I . -o out -h out");
5097   string code;
5098   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/Foo.h", &code));
5099   EXPECT_THAT(code, testing::HasSubstr("#include <Bar.h>"));
5100   EXPECT_THAT(code, testing::HasSubstr("#include <Baz.h>"));
5101   EXPECT_THAT(code, testing::HasSubstr("#include <Qux.h>"));
5102 }
5103 
TEST_F(GenericAidlTest,ImportGenericParameterTypesNDK)5104 TEST_F(GenericAidlTest, ImportGenericParameterTypesNDK) {
5105   Compile("aidl Foo.aidl --lang=ndk -I . -o out -h out");
5106   string code;
5107   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/Foo.h", &code));
5108   EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Bar.h>"));
5109   EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Baz.h>"));
5110   EXPECT_THAT(code, testing::HasSubstr("#include <aidl/Qux.h>"));
5111 }
5112 
TEST_P(AidlTest,RejectGenericStructuredParcelabelRepeatedParam)5113 TEST_P(AidlTest, RejectGenericStructuredParcelabelRepeatedParam) {
5114   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { int a; int A; }");
5115   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
5116   const string expected_stderr =
5117       "ERROR: Foo.aidl:1.11-15: Every type parameter should be unique.\n";
5118   CaptureStderr();
5119   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5120   EXPECT_EQ(expected_stderr, GetCapturedStderr());
5121 }
5122 
TEST_P(AidlTest,RejectGenericStructuredParcelableField)5123 TEST_P(AidlTest, RejectGenericStructuredParcelableField) {
5124   io_delegate_.SetFileContents("Foo.aidl", "parcelable Foo<T,T> { T a; int A; }");
5125   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
5126   const string expected_stderr =
5127       "ERROR: Foo.aidl: Couldn't find import for class T. Searched here:\n - ./\nERROR: "
5128       "Foo.aidl:1.22-24: Failed to resolve 'T'\n";
5129   CaptureStderr();
5130   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5131   EXPECT_EQ(expected_stderr, GetCapturedStderr());
5132 }
5133 
TEST_P(AidlTest,LongCommentWithinConstExpression)5134 TEST_P(AidlTest, LongCommentWithinConstExpression) {
5135   io_delegate_.SetFileContents("Foo.aidl", "enum Foo { FOO = (1 << 1) /* comment */ | 0x0 }");
5136   Options options = Options::From("aidl Foo.aidl -I . --lang=" + to_string(GetLanguage()));
5137   CaptureStderr();
5138   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5139   EXPECT_EQ("", GetCapturedStderr());
5140 }
5141 
TEST_F(AidlTest,RejectUntypdeListAndMapInUnion)5142 TEST_F(AidlTest, RejectUntypdeListAndMapInUnion) {
5143   io_delegate_.SetFileContents("a/Foo.aidl", "package a; union Foo { List l; Map m; }");
5144   Options options = Options::From("aidl a/Foo.aidl -I . --lang=java -o out");
5145   std::string expectedErr =
5146       "ERROR: a/Foo.aidl:1.28-30: "
5147       "Encountered an untyped List or Map. The use of untyped List/Map is "
5148       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
5149       "the receiving side. Consider switching to an array or a generic List/Map.\n"
5150       "ERROR: a/Foo.aidl:1.35-37: "
5151       "Encountered an untyped List or Map. The use of untyped List/Map is "
5152       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
5153       "the receiving side. Consider switching to an array or a generic List/Map.\n";
5154   CaptureStderr();
5155   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5156   EXPECT_EQ(expectedErr, GetCapturedStderr());
5157 }
5158 
TEST_F(AidlTest,RejectUntypdeListAndMapInUnstructuredParcelable)5159 TEST_F(AidlTest, RejectUntypdeListAndMapInUnstructuredParcelable) {
5160   io_delegate_.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { List l; Map m; }");
5161   Options options = Options::From("aidl a/Foo.aidl -I . --lang=java -o out");
5162   std::string expectedErr =
5163       "ERROR: a/Foo.aidl:1.33-35: "
5164       "Encountered an untyped List or Map. The use of untyped List/Map is "
5165       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
5166       "the receiving side. Consider switching to an array or a generic List/Map.\n"
5167       "ERROR: a/Foo.aidl:1.40-42: "
5168       "Encountered an untyped List or Map. The use of untyped List/Map is "
5169       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
5170       "the receiving side. Consider switching to an array or a generic List/Map.\n";
5171   CaptureStderr();
5172   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5173   EXPECT_EQ(expectedErr, GetCapturedStderr());
5174 }
5175 
TEST_F(AidlTest,RejectNestedUntypedListAndMap)5176 TEST_F(AidlTest, RejectNestedUntypedListAndMap) {
5177   io_delegate_.SetFileContents("a/Bar.aidl", "package a; parcelable Bar<T>;");
5178   io_delegate_.SetFileContents(
5179       "a/Foo.aidl", "package a; import a.Bar; parcelable Foo { Bar<List> a; Bar<Map> b; }");
5180   Options options = Options::From("aidl a/Foo.aidl -I . --lang=java -o out");
5181   std::string expectedErr =
5182       "ERROR: a/Foo.aidl:1.52-54: "
5183       "Encountered an untyped List or Map. The use of untyped List/Map is "
5184       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
5185       "the receiving side. Consider switching to an array or a generic List/Map.\n"
5186       "ERROR: a/Foo.aidl:1.64-66: "
5187       "Encountered an untyped List or Map. The use of untyped List/Map is "
5188       "prohibited because it is not guaranteed that the objects in the list are recognizable in "
5189       "the receiving side. Consider switching to an array or a generic List/Map.\n";
5190   CaptureStderr();
5191   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5192   EXPECT_EQ(expectedErr, GetCapturedStderr());
5193 }
5194 
TEST_F(AidlTest,EnumWithDefaults_Java)5195 TEST_F(AidlTest, EnumWithDefaults_Java) {
5196   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
5197   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5198 package p;
5199 import p.Enum;
5200 parcelable Foo {
5201   Enum e = Enum.BAR;
5202 })");
5203   CaptureStderr();
5204   auto options = Options::From("aidl -I a --lang java -o out a/p/Foo.aidl");
5205   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5206   auto err = GetCapturedStderr();
5207   EXPECT_EQ("", err);
5208 
5209   string code;
5210   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.java", &code));
5211   EXPECT_THAT(code, testing::HasSubstr("byte e = p.Enum.BAR"));
5212 }
5213 
TEST_F(AidlTest,EnumWithDefaults_Cpp)5214 TEST_F(AidlTest, EnumWithDefaults_Cpp) {
5215   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
5216   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5217 package p;
5218 import p.Enum;
5219 parcelable Foo {
5220   Enum e = Enum.BAR;
5221 })");
5222   CaptureStderr();
5223   auto options = Options::From("aidl -I a --lang cpp -o out -h out a/p/Foo.aidl");
5224   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5225   auto err = GetCapturedStderr();
5226   EXPECT_EQ("", err);
5227 
5228   string code;
5229   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.h", &code));
5230   EXPECT_THAT(code, testing::HasSubstr("::p::Enum e = ::p::Enum::BAR;"));
5231 }
5232 
TEST_F(AidlTest,EnumWithDefaults_Ndk)5233 TEST_F(AidlTest, EnumWithDefaults_Ndk) {
5234   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
5235   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5236 package p;
5237 import p.Enum;
5238 parcelable Foo {
5239   Enum e = Enum.BAR;
5240 })");
5241   CaptureStderr();
5242   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5243   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5244   auto err = GetCapturedStderr();
5245   EXPECT_EQ("", err);
5246 
5247   string code;
5248   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
5249   EXPECT_THAT(code, testing::HasSubstr("::aidl::p::Enum e = ::aidl::p::Enum::BAR;"));
5250 }
5251 
TEST_F(AidlTest,EnumWithDefaults_Rust)5252 TEST_F(AidlTest, EnumWithDefaults_Rust) {
5253   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO, BAR }");
5254   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5255 package p;
5256 import p.Enum;
5257 parcelable Foo {
5258   int  n = 42;
5259   Enum e = Enum.BAR;
5260 })");
5261   CaptureStderr();
5262   auto options = Options::From("aidl -I a --lang rust -o out -h out a/p/Foo.aidl");
5263   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5264   auto err = GetCapturedStderr();
5265   EXPECT_EQ("", err);
5266 
5267   string code;
5268   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/p/Foo.rs", &code));
5269   EXPECT_THAT(code, testing::HasSubstr(R"(
5270   fn default() -> Self {
5271     Self {
5272       r#n: 42,
5273       r#e: crate::mangled::_1_p_4_Enum::BAR,
5274     }
5275   })"));
5276 }
5277 
TEST_P(AidlTest,EnumeratorIsConstantValue_DefaultValue)5278 TEST_P(AidlTest, EnumeratorIsConstantValue_DefaultValue) {
5279   import_paths_.insert("a");
5280   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
5281   CaptureStderr();
5282   const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
5283 package p;
5284 import p.Enum;
5285 parcelable Foo {
5286   int e = Enum.FOO | Enum.BAR;
5287 })",
5288                                       typenames_, GetLanguage());
5289   auto err = GetCapturedStderr();
5290   EXPECT_EQ("", err);
5291   EXPECT_TRUE(type);
5292   const auto& fields = type->AsStructuredParcelable()->GetFields();
5293   EXPECT_EQ("int e = 3", fields[0]->ToString());
5294 }
5295 
TEST_F(AidlTest,EnumeratorIsConstantValue_CanDefineOtherEnumerator)5296 TEST_F(AidlTest, EnumeratorIsConstantValue_CanDefineOtherEnumerator) {
5297   CaptureStderr();
5298   const AidlDefinedType* type = Parse("a/p/Foo.aidl", R"(
5299 package a.p;
5300 @Backing(type="int")
5301 enum Foo {
5302       STANDARD_SHIFT = 16,
5303       STANDARD_BT709 = 1 << STANDARD_SHIFT,
5304       STANDARD_BT601_625 = 2 << STANDARD_SHIFT,
5305 }
5306 )",
5307                                       typenames_, Options::Language::JAVA);
5308   auto err = GetCapturedStderr();
5309   EXPECT_EQ("", err);
5310   ASSERT_NE(type, nullptr);
5311   const auto& enum_type = type->AsEnumDeclaration();
5312   string code;
5313   auto writer = CodeWriter::ForString(&code);
5314   DumpVisitor visitor(*writer, /*inline_constants=*/true);
5315   visitor.Visit(*enum_type);
5316   writer->Close();
5317   EXPECT_EQ(R"--(@Backing(type="int")
5318 enum Foo {
5319   STANDARD_SHIFT = 16,
5320   STANDARD_BT709 = 65536,
5321   STANDARD_BT601_625 = 131072,
5322 }
5323 )--",
5324             code);
5325 }
5326 
TEST_F(AidlTest,DumpApiWithConstantReferences)5327 TEST_F(AidlTest, DumpApiWithConstantReferences) {
5328   io_delegate_.SetFileContents("foo/bar/Foo.aidl", R"(
5329 package foo.bar;
5330 import foo.bar.Bar;
5331 import foo.bar.Enum;
5332 parcelable Foo {
5333   int n = Bar.A + 1;
5334   int[] ns = {1, Bar.A, Bar.B + 1};
5335   Enum e = Enum.A;
5336   Enum[] es = {Enum.A, Enum.B};
5337 }
5338 )");
5339   io_delegate_.SetFileContents("foo/bar/Bar.aidl", R"(
5340 package foo.bar;
5341 parcelable Bar {
5342   const int A = 1;
5343   const int B = A + 1;
5344 }
5345 )");
5346   io_delegate_.SetFileContents("foo/bar/Enum.aidl", R"(
5347 package foo.bar;
5348 enum Enum {
5349   A,
5350   B = A + 2,
5351 }
5352 )");
5353   vector<string> args = {"aidl",
5354                          "--dumpapi",
5355                          "--out=dump",
5356                          "--include=.",
5357                          "foo/bar/Foo.aidl",
5358                          "foo/bar/Bar.aidl",
5359                          "foo/bar/Enum.aidl"};
5360   ASSERT_TRUE(dump_api(Options::From(args), io_delegate_));
5361 
5362   string actual;
5363   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Foo.aidl", &actual));
5364   EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
5365 parcelable Foo {
5366   int n = (foo.bar.Bar.A + 1) /* 2 */;
5367   int[] ns = {1, foo.bar.Bar.A /* 1 */, (foo.bar.Bar.B + 1) /* 3 */};
5368   foo.bar.Enum e = foo.bar.Enum.A;
5369   foo.bar.Enum[] es = {foo.bar.Enum.A, foo.bar.Enum.B};
5370 }
5371 )"),
5372             actual);
5373   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Bar.aidl", &actual));
5374   EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
5375 parcelable Bar {
5376   const int A = 1;
5377   const int B = (A + 1) /* 2 */;
5378 }
5379 )"),
5380             actual);
5381   EXPECT_TRUE(io_delegate_.GetWrittenContents("dump/foo/bar/Enum.aidl", &actual));
5382   EXPECT_EQ(string(kPreamble).append(R"(package foo.bar;
5383 enum Enum {
5384   A,
5385   B = (A + 2) /* 2 */,
5386 }
5387 )"),
5388             actual);
5389 }
5390 
TEST_F(AidlTest,EnumDefaultShouldBeEnumerators)5391 TEST_F(AidlTest, EnumDefaultShouldBeEnumerators) {
5392   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
5393   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5394 package p;
5395 import p.Enum;
5396 parcelable Foo {
5397   Enum e = Enum.FOO | Enum.BAR;
5398 })");
5399   CaptureStderr();
5400   auto options = Options::From("aidl -I a --lang java -o out -h out a/p/Foo.aidl");
5401   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5402   auto err = GetCapturedStderr();
5403   EXPECT_EQ("ERROR: a/p/Foo.aidl:5.11-20: Invalid value (Enum.FOO|Enum.BAR) for enum p.Enum\n",
5404             err);
5405 }
5406 
TEST_F(AidlTest,EnumDefaultShouldBeEnumerators_RejectsNumericValue)5407 TEST_F(AidlTest, EnumDefaultShouldBeEnumerators_RejectsNumericValue) {
5408   io_delegate_.SetFileContents("a/p/Enum.aidl", "package p; enum Enum { FOO = 1, BAR = 2}");
5409   io_delegate_.SetFileContents("a/p/Foo.aidl", R"(
5410 package p;
5411 import p.Enum;
5412 parcelable Foo {
5413   Enum e = 1;
5414 })");
5415   CaptureStderr();
5416   auto options = Options::From("aidl -I a --lang java -o out -h out a/p/Foo.aidl");
5417   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5418   EXPECT_THAT(GetCapturedStderr(), HasSubstr("Invalid value (1) for enum p.Enum"));
5419 }
5420 
TEST_P(AidlTest,DefaultWithEmptyArray)5421 TEST_P(AidlTest, DefaultWithEmptyArray) {
5422   io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; parcelable Foo { p.Bar[] bars = {}; }");
5423   io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; parcelable Bar { }");
5424   CaptureStderr();
5425   auto options =
5426       Options::From("aidl -I a --lang " + to_string(GetLanguage()) + " -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 }
5431 
TEST_P(AidlTest,RejectRefsInAnnotation)5432 TEST_P(AidlTest, RejectRefsInAnnotation) {
5433   io_delegate_.SetFileContents("a/p/IFoo.aidl",
5434                                "package p; interface IFoo {\n"
5435                                "  const String ANNOTATION = \"@Annotation\";\n"
5436                                "  @JavaPassthrough(annotation=ANNOTATION) void foo();\n"
5437                                "}");
5438   CaptureStderr();
5439   auto options = Options::From("aidl -I a --lang " + to_string(GetLanguage()) +
5440                                " -o out -h out a/p/IFoo.aidl");
5441   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5442   auto err = GetCapturedStderr();
5443   EXPECT_EQ(
5444       "ERROR: a/p/IFoo.aidl:3.31-41: Value must be a constant expression but contains reference to "
5445       "ANNOTATION.\n",
5446       err);
5447 }
5448 
TEST_F(AidlTest,DefaultWithEnumValues)5449 TEST_F(AidlTest, DefaultWithEnumValues) {
5450   io_delegate_.SetFileContents(
5451       "a/p/Foo.aidl",
5452       "package p; import p.Bar; parcelable Foo { Bar[] bars = { Bar.FOO, Bar.FOO }; }");
5453   io_delegate_.SetFileContents("a/p/Bar.aidl", "package p; enum Bar { FOO, BAR }");
5454   CaptureStderr();
5455   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5456   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5457   auto err = GetCapturedStderr();
5458   EXPECT_EQ("", err);
5459   string code;
5460   EXPECT_TRUE(io_delegate_.GetWrittenContents("out/aidl/p/Foo.h", &code));
5461   EXPECT_THAT(
5462       code, testing::HasSubstr(
5463                 "std::vector<::aidl::p::Bar> bars = {::aidl::p::Bar::FOO, ::aidl::p::Bar::FOO};"));
5464 }
5465 
TEST_F(AidlTest,RejectsCircularReferencingEnumerators)5466 TEST_F(AidlTest, RejectsCircularReferencingEnumerators) {
5467   io_delegate_.SetFileContents("a/p/Foo.aidl", "package p; enum Foo { A = B, B }");
5468   CaptureStderr();
5469   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5470   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5471   auto err = GetCapturedStderr();
5472   EXPECT_EQ("ERROR: a/p/Foo.aidl:1.26-28: Found a circular reference: B -> A -> B\n", err);
5473 }
5474 
TEST_F(AidlTest,RejectsCircularReferencingConsts)5475 TEST_F(AidlTest, RejectsCircularReferencingConsts) {
5476   io_delegate_.SetFileContents("a/p/Foo.aidl",
5477                                "package p; parcelable Foo { const int A = A + 1; }");
5478   CaptureStderr();
5479   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5480   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5481   auto err = GetCapturedStderr();
5482   EXPECT_EQ("ERROR: a/p/Foo.aidl:1.42-44: Found a circular reference: A -> A\n", err);
5483 }
5484 
TEST_F(AidlTest,RecursiveReferences)5485 TEST_F(AidlTest, RecursiveReferences) {
5486   io_delegate_.SetFileContents("a/p/Foo.aidl",
5487                                "package p; parcelable Foo { const int A = p.Bar.A + 1; }");
5488   io_delegate_.SetFileContents("a/p/Bar.aidl",
5489                                "package p; parcelable Bar { const int A = p.Baz.A + 1; }");
5490   io_delegate_.SetFileContents("a/p/Baz.aidl", "package p; parcelable Baz { const int A = 1; }");
5491   CaptureStderr();
5492   auto options = Options::From("aidl -I a --lang ndk -o out -h out a/p/Foo.aidl");
5493   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5494   EXPECT_EQ("", GetCapturedStderr());
5495 }
5496 
TEST_P(AidlTest,CircularReferenceWithFullyQualified)5497 TEST_P(AidlTest, CircularReferenceWithFullyQualified) {
5498   io_delegate_.SetFileContents("Foo.aidl", "enum Foo { A = Foo.A }");
5499   auto options =
5500       Options::From("aidl --lang " + to_string(GetLanguage()) + " -I . -o out -h out Foo.aidl");
5501   const string err = "ERROR: Foo.aidl:1.15-21: Found a circular reference: Foo.A -> Foo.A\n";
5502   CaptureStderr();
5503   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5504   EXPECT_EQ(err, GetCapturedStderr());
5505 }
5506 
TEST_P(AidlTest,ConstRefsCanPointToTheSameValue)5507 TEST_P(AidlTest, ConstRefsCanPointToTheSameValue) {
5508   io_delegate_.SetFileContents("Foo.aidl", "enum Foo { A = 0 }");
5509   // this demonstrates the case that "Foo.A" const-ref node is visited twice by B and C.
5510   io_delegate_.SetFileContents("Bar.aidl", "enum Bar { A = Foo.A, B = A, C = A }");
5511   auto options =
5512       Options::From("aidl --lang " + to_string(GetLanguage()) + " -I . -o out -h out Bar.aidl");
5513   CaptureStderr();
5514   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5515   EXPECT_EQ("", GetCapturedStderr());
5516 }
5517 
TEST_P(AidlTest,UnknownConstReference)5518 TEST_P(AidlTest, UnknownConstReference) {
5519   io_delegate_.SetFileContents("Foo.aidl", " parcelable Foo { int field = UNKNOWN_REF; }");
5520   auto options =
5521       Options::From("aidl -I . --lang " + to_string(GetLanguage()) + " -o out -h out Foo.aidl");
5522   const string err =
5523       "ERROR: Foo.aidl:1.30-42: Can't find UNKNOWN_REF in Foo\n"
5524       "ERROR: Foo.aidl:1.30-42: Unknown reference 'UNKNOWN_REF'\n";
5525   CaptureStderr();
5526   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5527   EXPECT_EQ(err, GetCapturedStderr());
5528 }
5529 
TEST_P(AidlTest,ConstExpressionArrays)5530 TEST_P(AidlTest, ConstExpressionArrays) {
5531   io_delegate_.SetFileContents("Foo.aidl", " parcelable Foo { int[] field = {} - {1,2}; }");
5532   auto options =
5533       Options::From("aidl -I . --lang " + to_string(GetLanguage()) + " -o out -h out Foo.aidl");
5534   const string err =
5535       "ERROR: Foo.aidl:1.32-35: Operation '-' is not supported with array literals\n";
5536   CaptureStderr();
5537   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5538   EXPECT_EQ(err, GetCapturedStderr());
5539 }
5540 
TEST_P(AidlTest,JavaCompatibleBuiltinTypes)5541 TEST_P(AidlTest, JavaCompatibleBuiltinTypes) {
5542   string contents = R"(
5543 import android.os.IBinder;
5544 import android.os.IInterface;
5545 interface IFoo {}
5546   )";
5547   EXPECT_NE(nullptr, Parse("IFoo.aidl", contents, typenames_, GetLanguage()));
5548 }
5549 
TEST_P(AidlTest,WarningInterfaceName)5550 TEST_P(AidlTest, WarningInterfaceName) {
5551   io_delegate_.SetFileContents("p/Foo.aidl", "package p; interface Foo {}");
5552   auto options = Options::From("aidl -I . --lang " + to_string(GetLanguage()) +
5553                                " -Winterface-name -o out -h out p/Foo.aidl");
5554   CaptureStderr();
5555   EXPECT_TRUE(compile_aidl(options, io_delegate_));
5556   EXPECT_EQ(
5557       "WARNING: p/Foo.aidl:1.11-21: Interface names should start with I. [-Winterface-name]\n",
5558       GetCapturedStderr());
5559 }
5560 
TEST_P(AidlTest,ErrorInterfaceName)5561 TEST_P(AidlTest, ErrorInterfaceName) {
5562   io_delegate_.SetFileContents("p/Foo.aidl", "package p; interface Foo {}");
5563   auto options = Options::From("aidl -I . --lang " + to_string(GetLanguage()) +
5564                                " -Winterface-name -Werror -o out -h out p/Foo.aidl");
5565   CaptureStderr();
5566   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5567   EXPECT_EQ("ERROR: p/Foo.aidl:1.11-21: Interface names should start with I. [-Winterface-name]\n",
5568             GetCapturedStderr());
5569 }
5570 
TEST_F(AidlTest,RejectsIncorrectOutputFilePathOnLegacyCppInput)5571 TEST_F(AidlTest, RejectsIncorrectOutputFilePathOnLegacyCppInput) {
5572   const std::string input_file = "base/p/q/IFoo.aidl";
5573   const std::string header_dir = "out/";
5574   const std::string output_file = "out/base/p/q/IFoo.cpp";
5575   io_delegate_.SetFileContents(input_file, "package p.q; interface IFoo {}");
5576 
5577   auto options = Options::From({"aidl-cpp", "-I base", input_file, header_dir, output_file});
5578   CaptureStderr();
5579   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5580   EXPECT_THAT(
5581       GetCapturedStderr(),
5582       testing::StartsWith(
5583           "ERROR: base/p/q/IFoo.aidl:1.13-23: Output file is expected to be at out/p/q/IFoo.cpp, "
5584           "but is out/base/p/q/IFoo.cpp."));
5585 }
5586 
TEST_F(AidlTest,FormatCommentsForJava)5587 TEST_F(AidlTest, FormatCommentsForJava) {
5588   using android::aidl::FormatCommentsForJava;
5589 
5590   struct TestCase {
5591     vector<Comment> comments;
5592     string formatted;
5593   };
5594   vector<TestCase> testcases = {
5595       {{}, ""},
5596       {{{"// line comments\n"}}, "// line comments\n"},
5597       {{{"// @hide \n"}}, "// @hide \n"},
5598       // Transform the last block comment as Javadoc.
5599       {{{"/*\n"
5600          " * Hello, world!\n"
5601          " */"}},
5602        "/** Hello, world! */\n"},
5603       {{{"/* @hide */"}}, "/** @hide */\n"},
5604       {{{"/**\n"
5605          "   @param foo ...\n"
5606          "*/"}},
5607        "/** @param foo ... */\n"},
5608       {{{"/* @hide */"}, {"/* @hide */"}}, "/* @hide */\n/** @hide */\n"},
5609       {{{"/* @deprecated first */"}, {"/* @deprecated second */"}},
5610        "/* @deprecated first */\n/** @deprecated second */\n"},
5611       {{{"/* @deprecated */"}, {"/** @param foo */"}}, "/* @deprecated */\n/** @param foo */\n"},
5612       // Line comments are printed as they are
5613       {{{"/* @deprecated */"}, {"// line comments\n"}}, "/* @deprecated */\n// line comments\n"},
5614   };
5615   for (const auto& [input, formatted] : testcases) {
5616     EXPECT_EQ(formatted, FormatCommentsForJava(input));
5617   }
5618 }
5619 
TEST_F(AidlTest,SuppressWarningsIsNotForArgs)5620 TEST_F(AidlTest, SuppressWarningsIsNotForArgs) {
5621   io_delegate_.SetFileContents(
5622       "IFoo.aidl",
5623       "interface IFoo {\n"
5624       "  void foo(in @SuppressWarnings(value={\"inout-parameter\"}) int x);\n"
5625       "}");
5626   auto options = Options::From("aidl -I . --lang=java IFoo.aidl");
5627   CaptureStderr();
5628   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5629   EXPECT_THAT(GetCapturedStderr(), HasSubstr("@SuppressWarnings is not available"));
5630 }
5631 
TEST_F(AidlTest,VoidCantBeUsedInMethodParameterType)5632 TEST_F(AidlTest, VoidCantBeUsedInMethodParameterType) {
5633   io_delegate_.SetFileContents("p/IFoo.aidl", "package p; interface IFoo{ void j(void n);}");
5634   auto options = Options::From("aidl -I . --lang=java -o out p/IFoo.aidl");
5635   CaptureStderr();
5636   EXPECT_FALSE(compile_aidl(options, io_delegate_));
5637   EXPECT_THAT(GetCapturedStderr(), HasSubstr("'void' is an invalid type for the parameter 'n'"));
5638 }
5639 
TEST_F(AidlTest,InterfaceVectorIsAvailableAfterTiramisu)5640 TEST_F(AidlTest, InterfaceVectorIsAvailableAfterTiramisu) {
5641   io_delegate_.SetFileContents("p/IFoo.aidl",
5642                                "package p;\n"
5643                                "interface IFoo{\n"
5644                                "  void foo(in IFoo[] n);\n"
5645                                "  void bar(in List<IFoo> n);\n"
5646                                "}");
5647   CaptureStderr();
5648   EXPECT_FALSE(
5649       compile_aidl(Options::From("aidl -I . --lang=java --min_sdk_version 30 -o out p/IFoo.aidl"),
5650                    io_delegate_));
5651   auto captured_stderr = GetCapturedStderr();
5652   EXPECT_THAT(captured_stderr, HasSubstr("Array of interfaces is available since"));
5653   EXPECT_THAT(captured_stderr, HasSubstr("List of interfaces is available since"));
5654 
5655   CaptureStderr();
5656   EXPECT_TRUE(compile_aidl(
5657       Options::From("aidl -I . --lang=java --min_sdk_version Tiramisu -o out p/IFoo.aidl"),
5658       io_delegate_));
5659   EXPECT_EQ(GetCapturedStderr(), "");
5660 }
5661 
TEST_F(AidlTest,RustNameOf_PfdFixedArray)5662 TEST_F(AidlTest, RustNameOf_PfdFixedArray) {
5663   auto pfd = typenames_.MakeResolvedType(AIDL_LOCATION_HERE, "ParcelFileDescriptor", false);
5664   ASSERT_TRUE(pfd->MakeArray(FixedSizeArray{
5665       std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(AIDL_LOCATION_HERE, "2"))}));
5666   ASSERT_TRUE(pfd->MakeArray(FixedSizeArray{
5667       std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(AIDL_LOCATION_HERE, "3"))}));
5668   EXPECT_EQ(rust::RustNameOf(*pfd, typenames_, rust::StorageMode::PARCELABLE_FIELD, false),
5669             "[[Option<binder::ParcelFileDescriptor>; 3]; 2]");
5670   EXPECT_EQ(rust::RustNameOf(*pfd, typenames_, rust::StorageMode::DEFAULT_VALUE, false),
5671             "[[Option<binder::ParcelFileDescriptor>; 3]; 2]");
5672   EXPECT_EQ(rust::RustNameOf(*pfd, typenames_, rust::StorageMode::IN_ARGUMENT, false),
5673             "&[[binder::ParcelFileDescriptor; 3]; 2]");
5674   EXPECT_EQ(rust::RustNameOf(*pfd, typenames_, rust::StorageMode::VALUE, false),
5675             "[[binder::ParcelFileDescriptor; 3]; 2]");
5676 }
5677 
TEST_F(AidlTest,RustNameOf_PfdDynamicArray)5678 TEST_F(AidlTest, RustNameOf_PfdDynamicArray) {
5679   auto pfd = typenames_.MakeResolvedType(AIDL_LOCATION_HERE, "ParcelFileDescriptor", true);
5680   EXPECT_EQ(rust::RustNameOf(*pfd, typenames_, rust::StorageMode::PARCELABLE_FIELD, false),
5681             "Vec<binder::ParcelFileDescriptor>");
5682   EXPECT_EQ(rust::RustNameOf(*pfd, typenames_, rust::StorageMode::DEFAULT_VALUE, false),
5683             "Vec<Option<binder::ParcelFileDescriptor>>");
5684   // we use UNSIZED_ARGUMENT mode for input argument of dynamic array
5685   EXPECT_EQ(rust::RustNameOf(*pfd, typenames_, rust::StorageMode::UNSIZED_ARGUMENT, false),
5686             "&[binder::ParcelFileDescriptor]");
5687   EXPECT_EQ(rust::RustNameOf(*pfd, typenames_, rust::StorageMode::VALUE, false),
5688             "Vec<binder::ParcelFileDescriptor>");
5689 }
5690 
5691 struct TypeParam {
5692   string kind;
5693   string literal;
5694 };
5695 
5696 const TypeParam kTypeParams[] = {
5697     {"primitive", "int"},
5698     {"primitiveArray", "int[]"},
5699     {"primitiveFixedArray", "int[3]"},
5700     {"String", "String"},
5701     {"StringArray", "String[]"},
5702     {"IBinder", "IBinder"},
5703     {"ParcelFileDescriptor", "ParcelFileDescriptor"},
5704     {"parcelable", "a.Foo"},
5705     {"enum", "a.Enum"},
5706     {"union", "a.Union"},
5707     {"interface", "a.IBar"},
5708 };
5709 
5710 struct ExpectedResult {
5711   string expected_error;
5712   string expected_error_for_nullable;
5713 };
5714 
5715 const std::map<std::string, ExpectedResult> kListSupportExpectations = {
5716     {"cpp_primitive", {"A generic type cannot", "A generic type cannot"}},
5717     {"java_primitive", {"A generic type cannot", "A generic type cannot"}},
5718     {"ndk_primitive", {"A generic type cannot", "A generic type cannot"}},
5719     {"rust_primitive", {"A generic type cannot", "A generic type cannot"}},
5720     {"cpp_primitiveArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5721     {"java_primitiveArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5722     {"ndk_primitiveArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5723     {"rust_primitiveArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5724     {"cpp_primitiveFixedArray",
5725      {"List of arrays is not supported", "List of arrays is not supported"}},
5726     {"java_primitiveFixedArray",
5727      {"List of arrays is not supported", "List of arrays is not supported"}},
5728     {"ndk_primitiveFixedArray",
5729      {"List of arrays is not supported", "List of arrays is not supported"}},
5730     {"rust_primitiveFixedArray",
5731      {"List of arrays is not supported", "List of arrays is not supported"}},
5732     {"cpp_String", {"", ""}},
5733     {"java_String", {"", ""}},
5734     {"ndk_String", {"", ""}},
5735     {"rust_String", {"", ""}},
5736     {"cpp_StringArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5737     {"java_StringArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5738     {"ndk_StringArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5739     {"rust_StringArray", {"List of arrays is not supported", "List of arrays is not supported"}},
5740     {"cpp_IBinder", {"", ""}},
5741     {"java_IBinder", {"", ""}},
5742     {"ndk_IBinder", {"", ""}},
5743     {"rust_IBinder", {"", ""}},
5744     {"cpp_ParcelFileDescriptor", {"", ""}},
5745     {"java_ParcelFileDescriptor", {"", ""}},
5746     {"ndk_ParcelFileDescriptor", {"", ""}},
5747     {"rust_ParcelFileDescriptor", {"", ""}},
5748     {"cpp_interface", {"", ""}},
5749     {"java_interface", {"", ""}},
5750     {"ndk_interface", {"", ""}},
5751     {"rust_interface", {"", ""}},
5752     {"cpp_parcelable", {"", ""}},
5753     {"java_parcelable", {"", ""}},
5754     {"ndk_parcelable", {"", ""}},
5755     {"rust_parcelable", {"", ""}},
5756     {"cpp_enum", {"A generic type cannot", "A generic type cannot"}},
5757     {"java_enum", {"A generic type cannot", "A generic type cannot"}},
5758     {"ndk_enum", {"A generic type cannot", "A generic type cannot"}},
5759     {"rust_enum", {"A generic type cannot", "A generic type cannot"}},
5760     {"cpp_union", {"", ""}},
5761     {"java_union", {"", ""}},
5762     {"ndk_union", {"", ""}},
5763     {"rust_union", {"", ""}},
5764 };
5765 
5766 const std::map<std::string, ExpectedResult> kArraySupportExpectations = {
5767     {"cpp_primitive", {"", ""}},
5768     {"java_primitive", {"", ""}},
5769     {"ndk_primitive", {"", ""}},
5770     {"rust_primitive", {"", ""}},
5771     {"cpp_primitiveArray",
5772      {"Multi-dimensional arrays must be fixed size.",
5773       "Multi-dimensional arrays must be fixed size."}},
5774     {"java_primitiveArray",
5775      {"Multi-dimensional arrays must be fixed size.",
5776       "Multi-dimensional arrays must be fixed size."}},
5777     {"ndk_primitiveArray",
5778      {"Multi-dimensional arrays must be fixed size.",
5779       "Multi-dimensional arrays must be fixed size."}},
5780     {"rust_primitiveArray",
5781      {"Multi-dimensional arrays must be fixed size.",
5782       "Multi-dimensional arrays must be fixed size."}},
5783     {"cpp_primitiveFixedArray",
5784      {"Multi-dimensional arrays must be fixed size.",
5785       "Multi-dimensional arrays must be fixed size."}},
5786     {"java_primitiveFixedArray",
5787      {"Multi-dimensional arrays must be fixed size.",
5788       "Multi-dimensional arrays must be fixed size."}},
5789     {"ndk_primitiveFixedArray",
5790      {"Multi-dimensional arrays must be fixed size.",
5791       "Multi-dimensional arrays must be fixed size."}},
5792     {"rust_primitiveFixedArray",
5793      {"Multi-dimensional arrays must be fixed size.",
5794       "Multi-dimensional arrays must be fixed size."}},
5795     {"cpp_String", {"", ""}},
5796     {"java_String", {"", ""}},
5797     {"ndk_String", {"", ""}},
5798     {"rust_String", {"", ""}},
5799     {"cpp_StringArray",
5800      {"Multi-dimensional arrays must be fixed size.",
5801       "Multi-dimensional arrays must be fixed size."}},
5802     {"java_StringArray",
5803      {"Multi-dimensional arrays must be fixed size.",
5804       "Multi-dimensional arrays must be fixed size."}},
5805     {"ndk_StringArray",
5806      {"Multi-dimensional arrays must be fixed size.",
5807       "Multi-dimensional arrays must be fixed size."}},
5808     {"rust_StringArray",
5809      {"Multi-dimensional arrays must be fixed size.",
5810       "Multi-dimensional arrays must be fixed size."}},
5811     {"cpp_IBinder", {"", ""}},
5812     {"java_IBinder", {"", ""}},
5813     {"ndk_IBinder", {"", ""}},
5814     {"rust_IBinder", {"", ""}},
5815     {"cpp_ParcelFileDescriptor", {"", ""}},
5816     {"java_ParcelFileDescriptor", {"", ""}},
5817     {"ndk_ParcelFileDescriptor", {"", ""}},
5818     {"rust_ParcelFileDescriptor", {"", ""}},
5819     {"cpp_interface", {"", ""}},
5820     {"java_interface", {"", ""}},
5821     {"ndk_interface", {"", ""}},
5822     {"rust_interface", {"", ""}},
5823     {"cpp_parcelable", {"", ""}},
5824     {"java_parcelable", {"", ""}},
5825     {"ndk_parcelable", {"", ""}},
5826     {"rust_parcelable", {"", ""}},
5827     {"cpp_enum", {"", ""}},
5828     {"java_enum", {"", ""}},
5829     {"ndk_enum", {"", ""}},
5830     {"rust_enum", {"", ""}},
5831     {"cpp_union", {"", ""}},
5832     {"java_union", {"", ""}},
5833     {"ndk_union", {"", ""}},
5834     {"rust_union", {"", ""}},
5835 };
5836 
5837 const std::map<std::string, ExpectedResult> kFieldSupportExpectations = {
5838     {"cpp_primitive", {"", "cannot get nullable annotation"}},
5839     {"java_primitive", {"", "cannot get nullable annotation"}},
5840     {"ndk_primitive", {"", "cannot get nullable annotation"}},
5841     {"rust_primitive", {"", "cannot get nullable annotation"}},
5842     {"cpp_primitiveArray", {"", ""}},
5843     {"java_primitiveArray", {"", ""}},
5844     {"ndk_primitiveArray", {"", ""}},
5845     {"rust_primitiveArray", {"", ""}},
5846     {"cpp_primitiveFixedArray", {"", ""}},
5847     {"java_primitiveFixedArray", {"", ""}},
5848     {"ndk_primitiveFixedArray", {"", ""}},
5849     {"rust_primitiveFixedArray", {"", ""}},
5850     {"cpp_String", {"", ""}},
5851     {"java_String", {"", ""}},
5852     {"ndk_String", {"", ""}},
5853     {"rust_String", {"", ""}},
5854     {"cpp_StringArray", {"", ""}},
5855     {"java_StringArray", {"", ""}},
5856     {"ndk_StringArray", {"", ""}},
5857     {"rust_StringArray", {"", ""}},
5858     {"cpp_IBinder", {"", ""}},
5859     {"java_IBinder", {"", ""}},
5860     {"ndk_IBinder", {"", ""}},
5861     {"rust_IBinder", {"", ""}},
5862     {"cpp_ParcelFileDescriptor", {"", ""}},
5863     {"java_ParcelFileDescriptor", {"", ""}},
5864     {"ndk_ParcelFileDescriptor", {"", ""}},
5865     {"rust_ParcelFileDescriptor", {"", ""}},
5866     {"cpp_interface", {"", ""}},
5867     {"java_interface", {"", ""}},
5868     {"ndk_interface", {"", ""}},
5869     {"rust_interface", {"", ""}},
5870     {"cpp_parcelable", {"", ""}},
5871     {"java_parcelable", {"", ""}},
5872     {"ndk_parcelable", {"", ""}},
5873     {"rust_parcelable", {"", ""}},
5874     {"cpp_enum", {"", "cannot get nullable annotation"}},
5875     {"java_enum", {"", "cannot get nullable annotation"}},
5876     {"ndk_enum", {"", "cannot get nullable annotation"}},
5877     {"rust_enum", {"", "cannot get nullable annotation"}},
5878     {"cpp_union", {"", ""}},
5879     {"java_union", {"", ""}},
5880     {"ndk_union", {"", ""}},
5881     {"rust_union", {"", ""}},
5882 };
5883 
5884 class AidlTypeParamTest
5885     : public testing::TestWithParam<std::tuple<Options::Language, TypeParam, bool>> {
5886  public:
Run(const std::string & generic_type_decl,const std::map<std::string,ExpectedResult> & expectations)5887   void Run(const std::string& generic_type_decl,
5888            const std::map<std::string, ExpectedResult>& expectations) {
5889     const auto& param = GetParam();
5890     const auto& lang = to_string(std::get<0>(param));
5891     const auto& kind = std::get<1>(param).kind;
5892     const bool nullable = std::get<2>(param);
5893 
5894     FakeIoDelegate io;
5895     io.SetFileContents("a/IBar.aidl", "package a; interface IBar { }");
5896     io.SetFileContents("a/Enum.aidl", "package a; enum Enum { A }");
5897     io.SetFileContents("a/Union.aidl", "package a; union Union { int a; }");
5898     io.SetFileContents("a/Foo.aidl", "package a; parcelable Foo { int a; }");
5899     std::string decl =
5900         std::vformat(generic_type_decl, std::make_format_args(std::get<1>(param).literal));
5901     if (nullable) {
5902       decl = "@nullable " + decl;
5903     }
5904     io.SetFileContents("a/Target.aidl", "package a; parcelable Target { " + decl + " f; }");
5905 
5906     const auto options = Options::From(std::format(
5907         "aidl -I . --min_sdk_version current --lang={} a/Target.aidl -o out -h out", lang));
5908     CaptureStderr();
5909     compile_aidl(options, io);
5910     auto it = expectations.find(lang + "_" + kind);
5911     ASSERT_TRUE(it != expectations.end()) << "missing expectation for " << lang << "_" << kind;
5912     const string err = GetCapturedStderr();
5913     const string expected_error =
5914         nullable ? it->second.expected_error_for_nullable : it->second.expected_error;
5915     if (expected_error.empty()) {
5916       EXPECT_EQ("", err);
5917     } else {
5918       EXPECT_THAT(err, testing::HasSubstr(expected_error));
5919     }
5920   }
5921 };
5922 
5923 INSTANTIATE_TEST_SUITE_P(
5924     AidlTestSuite, AidlTypeParamTest,
5925     testing::Combine(testing::Values(Options::Language::CPP, Options::Language::JAVA,
5926                                      Options::Language::NDK, Options::Language::RUST),
5927                      testing::ValuesIn(kTypeParams), testing::Values(true, false)),
__anon078f757c0702(const testing::TestParamInfo<std::tuple<Options::Language, TypeParam, bool>>& info) 5928     [](const testing::TestParamInfo<std::tuple<Options::Language, TypeParam, bool>>& info) {
5929       string name = to_string(std::get<0>(info.param)) + "_" + std::get<1>(info.param).kind;
5930       if (std::get<2>(info.param)) {
5931         name += "_nullable";
5932       }
5933       return name;
5934     });
5935 
TEST_P(AidlTypeParamTest,ListSupportedTypes)5936 TEST_P(AidlTypeParamTest, ListSupportedTypes) {
5937   Run("List<{}>", kListSupportExpectations);
5938 }
5939 
TEST_P(AidlTypeParamTest,ArraySupportedTypes)5940 TEST_P(AidlTypeParamTest, ArraySupportedTypes) {
5941   Run("{}[]", kArraySupportExpectations);
5942 }
5943 
TEST_P(AidlTypeParamTest,ParcelableFieldTypes)5944 TEST_P(AidlTypeParamTest, ParcelableFieldTypes) {
5945   Run("{}", kFieldSupportExpectations);
5946 }
5947 
5948 }  // namespace aidl
5949 }  // namespace android
5950