1 /*
2 * Copyright (C) 2018, 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 #pragma once
18
19 #include <functional>
20 #include <string>
21 #include <type_traits>
22
23 #include "aidl_language.h"
24
25 // This is used to help generate code targetting C++ (the language) whether using the libbinder or
26 // libbinder_ndk backend.
27
28 namespace android {
29 namespace aidl {
30 namespace cpp {
31
32 extern char kTransactionLogStruct[];
33
34 // These roughly correspond to the various class names in the C++ hierarchy:
35 enum class ClassNames {
36 BASE, // Foo (not a real class, but useful in some circumstances).
37 CLIENT, // BpFoo
38 SERVER, // BnFoo
39 INTERFACE, // IFoo
40 DEFAULT_IMPL, // IFooDefault
41 RAW, // (as shown in the file)
42 DELEGATOR_IMPL, // IFooDelegator
43 };
44
45 string ClassName(const AidlDefinedType& defined_type, ClassNames type);
46
47 // Return the alignment of known types and enum backing types.
48 // If the alignment is unknown, or it is a FizedSize parcelable with its
49 // own guaranteed alignment(so it does not need to be specified), 0 will be
50 // returned.
51 size_t AlignmentOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames);
52
53 // Generate the relative path to a header file. If |use_os_sep| we'll use the
54 // operating system specific path separator rather than C++'s expected '/' when
55 // including headers.
56 std::string HeaderFile(const AidlDefinedType& defined_type, ClassNames class_type,
57 bool use_os_sep = true);
58
59 bool ValidateOutputFilePath(const string& output_file, const Options& options,
60 const AidlDefinedType& defined_type);
61
62 void EnterNamespace(CodeWriter& out, const AidlDefinedType& defined_type);
63 void LeaveNamespace(CodeWriter& out, const AidlDefinedType& defined_type);
64
65 string BuildVarName(const AidlArgument& a);
66 const string GenLogBeforeExecute(const string className, const AidlMethod& method, bool isServer,
67 bool isNdk);
68 const string GenLogAfterExecute(const string className, const AidlInterface& interface,
69 const AidlMethod& method, const string& statusVarName,
70 const string& returnVarName, bool isServer, bool isNdk);
71
72 template <typename T, typename = std::enable_if_t<std::is_copy_constructible_v<T>>>
Append(std::vector<T> as,const std::vector<T> & bs)73 std::vector<T> Append(std::vector<T> as, const std::vector<T>& bs) {
74 as.insert(as.end(), bs.begin(), bs.end());
75 return as;
76 }
77
78 template <typename T>
Append(std::vector<T> && as,std::vector<T> && bs)79 std::vector<T> Append(std::vector<T>&& as, std::vector<T>&& bs) {
80 std::vector<T> appended = std::move(as);
81 std::copy(std::move_iterator(bs.begin()), std::move_iterator(bs.end()),
82 std::back_inserter(appended));
83 return appended;
84 }
85
86 // Returns Parent1::Parent2::Self. Namespaces are not included.
87 std::string GetQualifiedName(const AidlDefinedType& type, ClassNames name = ClassNames::RAW);
88
89 void GenerateEnumClassDecl(CodeWriter& out, const AidlEnumDeclaration& enum_decl,
90 const std::string& backing_type, ::ConstantValueDecorator decorator);
91 std::string GenerateEnumToString(const AidlEnumDeclaration& enum_decl,
92 const std::string& backing_type);
93 std::string GenerateEnumValues(const AidlEnumDeclaration& enum_decl,
94 const std::vector<std::string>& enclosing_namespaces_of_enum_decl);
95 std::string TemplateDecl(const AidlParcelable& defined_type);
96
97 void GenerateParcelableComparisonOperators(CodeWriter& out, const AidlParcelable& parcelable);
98
99 void GenerateToString(CodeWriter& out, const AidlStructuredParcelable& parcelable);
100 void GenerateToString(CodeWriter& out, const AidlUnionDecl& parcelable);
101
102 std::string GetDeprecatedAttribute(const AidlCommentable& type);
103
104 template <typename Stream>
GenerateDeprecated(Stream & out,const AidlCommentable & type)105 void GenerateDeprecated(Stream& out, const AidlCommentable& type) {
106 if (auto deprecated = GetDeprecatedAttribute(type); !deprecated.empty()) {
107 out << " " + deprecated;
108 }
109 }
110
111 struct ParcelWriterContext {
112 string status_type;
113 string status_ok;
114 string status_bad;
115 std::function<void(CodeWriter& out, const std::string& var, const AidlTypeSpecifier& type)>
116 read_func;
117 std::function<void(CodeWriter& out, const std::string& value, const AidlTypeSpecifier& type)>
118 write_func;
119 };
120
121 struct UnionWriter {
122 const AidlUnionDecl& decl;
123 const AidlTypenames& typenames;
124 const std::function<std::string(const AidlTypeSpecifier&, const AidlTypenames&)> name_of;
125 const ::ConstantValueDecorator& decorator;
126
127 static std::set<std::string> GetHeaders(const AidlUnionDecl&);
128
129 void PrivateFields(CodeWriter& out) const;
130 void PublicFields(CodeWriter& out) const;
131 void ReadFromParcel(CodeWriter& out, const ParcelWriterContext&) const;
132 void WriteToParcel(CodeWriter& out, const ParcelWriterContext&) const;
133 };
134
135 std::string CppConstantValueDecorator(
136 const AidlTypeSpecifier& type,
137 const std::variant<std::string, std::vector<std::string>>& raw_value, bool is_ndk);
138
139 void GenerateForwardDecls(CodeWriter& out, const AidlDefinedType& root_type, bool is_ndk);
140
141 struct ClangDiagnosticIgnoreDeprecated {
142 CodeWriter& out;
143 bool deprecated;
ClangDiagnosticIgnoreDeprecatedClangDiagnosticIgnoreDeprecated144 ClangDiagnosticIgnoreDeprecated(CodeWriter& out, bool deprecated)
145 : out(out), deprecated(deprecated) {
146 // enter
147 if (deprecated) {
148 out << "#pragma clang diagnostic push\n";
149 out << "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n";
150 }
151 }
~ClangDiagnosticIgnoreDeprecatedClangDiagnosticIgnoreDeprecated152 ~ClangDiagnosticIgnoreDeprecated() {
153 // exit
154 if (deprecated) {
155 out << "#pragma clang diagnostic pop\n";
156 }
157 }
158 };
159
160 bool HasDeprecatedField(const AidlParcelable& parcelable);
161 } // namespace cpp
162 } // namespace aidl
163 } // namespace android
164