• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021, 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 "preprocess.h"
18 
19 #include <android-base/strings.h>
20 
21 #include "aidl.h"
22 
23 using android::base::Join;
24 
25 namespace android {
26 namespace aidl {
27 
28 namespace {
29 // PreprocessVisitor emits
30 // - types including comments(hide/deprecated) and annotations
31 // - constant delcarations for interface/parcelable/unions
32 // - enumerators for enums
33 struct PreprocessVisitor : AidlVisitor {
34   CodeWriter& out;
PreprocessVisitorandroid::aidl::__anona278a5b80111::PreprocessVisitor35   PreprocessVisitor(CodeWriter& out) : out(out) {}
36 
DumpTypeandroid::aidl::__anona278a5b80111::PreprocessVisitor37   void DumpType(const AidlDefinedType& dt, const string& type) {
38     DumpComments(dt);
39     DumpAnnotations(dt);
40     // Top-level definition emits canonical name while nested type emits "name" only.
41     if (dt.GetParentType()) {
42       out << type << " " << dt.GetName();
43     } else {
44       out << type << " " << dt.GetCanonicalName();
45     }
46     if (auto generic_type = dt.AsParameterizable(); generic_type && generic_type->IsGeneric()) {
47       out << "<" << Join(generic_type->GetTypeParameters(), ", ") << ">";
48     }
49   }
DumpMembersandroid::aidl::__anona278a5b80111::PreprocessVisitor50   void DumpMembers(const AidlDefinedType& dt) {
51     out << " {\n";
52     out.Indent();
53     for (const auto& constdecl : dt.GetConstantDeclarations()) {
54       constdecl->DispatchVisit(*this);
55     }
56     for (const auto& nested : dt.GetNestedTypes()) {
57       nested->DispatchVisit(*this);
58     }
59     out.Dedent();
60     out << "}\n";
61   }
DumpCommentsandroid::aidl::__anona278a5b80111::PreprocessVisitor62   void DumpComments(const AidlCommentable& c) {
63     const auto hidden = c.IsHidden();
64     const auto deprecated = FindDeprecated(c.GetComments());
65     if (hidden || deprecated) {
66       out << "/**\n";
67       if (hidden) {
68         out << " * @hide\n";
69       }
70       if (deprecated) {
71         out << " * @deprecated " << deprecated->note << "\n";
72       }
73       out << " */\n";
74     }
75   }
DumpAnnotationsandroid::aidl::__anona278a5b80111::PreprocessVisitor76   void DumpAnnotations(const AidlAnnotatable& a) {
77     auto annotations = a.ToString();
78     if (!annotations.empty()) {
79       out << annotations << "\n";
80     }
81   }
DumpConstantValueandroid::aidl::__anona278a5b80111::PreprocessVisitor82   void DumpConstantValue(const AidlTypeSpecifier& type, const AidlConstantValue& c) {
83     out << c.ValueString(type, AidlConstantValueDecorator);
84   }
Visitandroid::aidl::__anona278a5b80111::PreprocessVisitor85   void Visit(const AidlInterface& t) override {
86     DumpType(t, "interface");
87     DumpMembers(t);
88   }
Visitandroid::aidl::__anona278a5b80111::PreprocessVisitor89   void Visit(const AidlParcelable& t) override {
90     DumpType(t, "parcelable");
91     if (const auto& cpp_header = t.GetCppHeader(); !cpp_header.empty()) {
92       out << " cpp_header " << cpp_header;
93     }
94     if (const auto& ndk_header = t.GetNdkHeader(); !ndk_header.empty()) {
95       out << " ndk_header " << ndk_header;
96     }
97     out << ";\n";
98   }
Visitandroid::aidl::__anona278a5b80111::PreprocessVisitor99   void Visit(const AidlStructuredParcelable& t) override {
100     DumpType(t, "parcelable");
101     DumpMembers(t);
102   }
Visitandroid::aidl::__anona278a5b80111::PreprocessVisitor103   void Visit(const AidlUnionDecl& t) override {
104     DumpType(t, "union");
105     DumpMembers(t);
106   }
Visitandroid::aidl::__anona278a5b80111::PreprocessVisitor107   void Visit(const AidlEnumDeclaration& t) override {
108     DumpType(t, "enum");
109     out << " {\n";
110     out.Indent();
111     for (const auto& e : t.GetEnumerators()) {
112       out << e->GetName() << " = ";
113       DumpConstantValue(t.GetBackingType(), *e->GetValue());
114       out << ",\n";
115     }
116     out.Dedent();
117     out << "}\n";
118   }
Visitandroid::aidl::__anona278a5b80111::PreprocessVisitor119   void Visit(const AidlConstantDeclaration& c) override {
120     DumpComments(c);
121     out << "const ";
122     Visit(c.GetType());
123     out << " " << c.GetName() << " = ";
124     DumpConstantValue(c.GetType(), c.GetValue());
125     out << ";\n";
126   }
Visitandroid::aidl::__anona278a5b80111::PreprocessVisitor127   void Visit(const AidlTypeSpecifier& t) override { out << t.ToString(); }
128 };
129 
130 }  // namespace
131 
Preprocess(const Options & options,const IoDelegate & io_delegate)132 bool Preprocess(const Options& options, const IoDelegate& io_delegate) {
133   unique_ptr<CodeWriter> writer = io_delegate.GetCodeWriter(options.OutputFile());
134   PreprocessVisitor visitor(*writer);
135 
136   for (const auto& file : options.InputFiles()) {
137     AidlTypenames typenames;
138     auto result =
139         internals::load_and_validate_aidl(file, options, io_delegate, &typenames, nullptr);
140     if (result == AidlError::OK) {
141       const auto& doc = typenames.MainDocument();
142       for (const auto& t : doc.DefinedTypes()) {
143         t->DispatchVisit(visitor);
144       }
145     } else {
146       return false;
147     }
148   }
149 
150   return writer->Close();
151 }
152 
153 }  // namespace aidl
154 }  // namespace android
155