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   MAYBE_INTERFACE,  // == INTERFACE for AidlInterface, == RAW for other types
44 };
45 
46 string ClassName(const AidlDefinedType& defined_type, ClassNames type);
47 
48 // Returns the alignment of known types and enum backing types or nullopt for
49 // non-FixedSize parcelables.
50 std::optional<size_t> AlignmentOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames);
51 std::optional<size_t> AlignmentOfDefinedType(const AidlDefinedType& defined_type,
52                                              const AidlTypenames& typenames);
53 
54 size_t AlignTo(size_t val, size_t align);
55 
56 // Return the size of known types and enum backing types or nullopt for
57 // non-FixedSize parcelables.
58 std::optional<size_t> SizeOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames);
59 std::optional<size_t> SizeOfDefinedType(const AidlDefinedType& defined_type,
60                                         const AidlTypenames& typenames);
61 
62 // Generate the relative path to a header file.  If |use_os_sep| we'll use the
63 // operating system specific path separator rather than C++'s expected '/' when
64 // including headers.
65 std::string HeaderFile(const AidlDefinedType& defined_type, ClassNames class_type,
66                        bool use_os_sep = true);
67 
68 bool ValidateOutputFilePath(const string& output_file, const Options& options,
69                             const AidlDefinedType& defined_type);
70 
71 void EnterNamespace(CodeWriter& out, const AidlDefinedType& defined_type);
72 void LeaveNamespace(CodeWriter& out, const AidlDefinedType& defined_type);
73 
74 string BuildVarName(const AidlArgument& a);
75 const string GenLogBeforeExecute(const string className, const AidlMethod& method, bool isServer,
76                                  bool isNdk);
77 const string GenLogAfterExecute(const string className, const AidlInterface& interface,
78                                 const AidlMethod& method, const string& statusVarName,
79                                 const string& returnVarName, bool isServer, bool isNdk);
80 
81 template <typename T, typename = std::enable_if_t<std::is_copy_constructible_v<T>>>
Append(std::vector<T> as,const std::vector<T> & bs)82 std::vector<T> Append(std::vector<T> as, const std::vector<T>& bs) {
83   as.insert(as.end(), bs.begin(), bs.end());
84   return as;
85 }
86 
87 template <typename T>
Append(std::vector<T> && as,std::vector<T> && bs)88 std::vector<T> Append(std::vector<T>&& as, std::vector<T>&& bs) {
89   std::vector<T> appended = std::move(as);
90   std::copy(std::move_iterator(bs.begin()), std::move_iterator(bs.end()),
91             std::back_inserter(appended));
92   return appended;
93 }
94 
95 // Returns Parent1::Parent2::Self. Namespaces are not included.
96 std::string GetQualifiedName(const AidlDefinedType& type, ClassNames name = ClassNames::RAW);
97 
98 void GenerateEnumClassDecl(CodeWriter& out, const AidlEnumDeclaration& enum_decl,
99                            const std::string& backing_type, ::ConstantValueDecorator decorator);
100 std::string GenerateEnumToString(const AidlEnumDeclaration& enum_decl,
101                                  const std::string& backing_type);
102 std::string GenerateEnumValues(const AidlEnumDeclaration& enum_decl,
103                                const std::vector<std::string>& enclosing_namespaces_of_enum_decl);
104 std::string TemplateDecl(const AidlParcelable& defined_type);
105 
106 void GenerateParcelableComparisonOperators(CodeWriter& out, const AidlParcelable& parcelable);
107 
108 void GenerateToString(CodeWriter& out, const AidlStructuredParcelable& parcelable);
109 void GenerateToString(CodeWriter& out, const AidlUnionDecl& parcelable);
110 
111 std::string GetDeprecatedAttribute(const AidlCommentable& type);
112 
113 template <typename Stream>
GenerateDeprecated(Stream & out,const AidlCommentable & type)114 void GenerateDeprecated(Stream& out, const AidlCommentable& type) {
115   if (auto deprecated = GetDeprecatedAttribute(type); !deprecated.empty()) {
116     out << " " + deprecated;
117   }
118 }
119 
120 struct ParcelWriterContext {
121   string status_type;
122   string status_ok;
123   string status_bad;
124   std::function<void(CodeWriter& out, const std::string& var, const AidlTypeSpecifier& type)>
125       read_func;
126   std::function<void(CodeWriter& out, const std::string& value, const AidlTypeSpecifier& type)>
127       write_func;
128 };
129 
130 struct UnionWriter {
131   const AidlUnionDecl& decl;
132   const AidlTypenames& typenames;
133   const std::function<std::string(const AidlTypeSpecifier&, const AidlTypenames&)> name_of;
134   const ::ConstantValueDecorator& decorator;
135 
136   static std::set<std::string> GetHeaders(const AidlUnionDecl&);
137 
138   void PrivateFields(CodeWriter& out) const;
139   void PublicFields(CodeWriter& out) const;
140   void ReadFromParcel(CodeWriter& out, const ParcelWriterContext&) const;
141   void WriteToParcel(CodeWriter& out, const ParcelWriterContext&) const;
142 };
143 
144 std::string CppConstantValueDecorator(
145     const AidlTypeSpecifier& type,
146     const std::variant<std::string, std::vector<std::string>>& raw_value, bool is_ndk);
147 
148 void GenerateForwardDecls(CodeWriter& out, const AidlDefinedType& root_type, bool is_ndk);
149 
150 struct ClangDiagnosticIgnoreDeprecated {
151   CodeWriter& out;
152   bool deprecated;
ClangDiagnosticIgnoreDeprecatedClangDiagnosticIgnoreDeprecated153   ClangDiagnosticIgnoreDeprecated(CodeWriter& out, bool deprecated)
154       : out(out), deprecated(deprecated) {
155     // enter
156     if (deprecated) {
157       out << "#pragma clang diagnostic push\n";
158       out << "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n";
159     }
160   }
~ClangDiagnosticIgnoreDeprecatedClangDiagnosticIgnoreDeprecated161   ~ClangDiagnosticIgnoreDeprecated() {
162     // exit
163     if (deprecated) {
164       out << "#pragma clang diagnostic pop\n";
165     }
166   }
167 };
168 
169 bool HasDeprecatedField(const AidlParcelable& parcelable);
170 }  // namespace cpp
171 }  // namespace aidl
172 }  // namespace android
173