1 /*
2  * Copyright (C) 2019 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 <map>
20 #include <set>
21 #include <string>
22 #include <vector>
23 #include "Reference.h"
24 
25 namespace android {
26 
27 struct CompoundType;
28 struct Coordinator;
29 struct Formatter;
30 struct FQName;
31 struct Interface;
32 struct Method;
33 struct NamedType;
34 struct Scope;
35 struct Type;
36 
37 struct FieldWithVersion {
38     const NamedReference<Type>* field;
39     // name of the field appended by the
40     std::string fullName;
41     std::pair<size_t, size_t> version;
42 };
43 
44 struct ProcessedCompoundType {
45     // map modified name to field. This modified name is old.new
46     std::vector<FieldWithVersion> fields;
47     std::set<const NamedType*> subTypes;
48 };
49 
50 struct ReplacedTypeInfo {
51     // if a HIDL type is replaced, this returns the new AIDL type
52     // android.hardware.safe_enum@1.0::Monostate -> boolean
53     std::string aidlReplacedType;
54     // if a HIDL type is replaced, this is the FQName of the new AIDL type
55     // android.hardware.safe_enum@1.0::Monostate -> std::nullopt
56     std::optional<std::string> aidlReplacedFQName;
57     // if a HIDL type is replaced, this returns the function needed to generate translation
58     std::optional<std::function<void(Formatter&)>> translateField;
59 };
60 
61 enum class AidlBackend { UNKNOWN, NDK, CPP, JAVA };
62 
63 struct AidlHelper {
64     /* FQName helpers */
65     // getAidlName returns the type names
66     // backend == UNKNOWN
67     // android.hardware.foo@1.0::IBar::Baz -> Baz
68     // backend == CPP || backend == NDK
69     // android.hardware.foo@1.0::IBar::Baz -> IBar::Baz
70     // backend == JAVA
71     // android.hardware.foo@1.0::IBar::Baz -> IBar.Baz
72     static std::string getAidlName(const FQName& fqName,
73                                    AidlBackend backend = AidlBackend::UNKNOWN);
74 
75     // getAidlPackage returns the AIDL package
76     // android.hardware.foo@1.x -> android.hardware.foo
77     // android.hardware.foo@2.x -> android.hardware.foo2
78     static std::string getAidlPackage(const FQName& fqName);
79     // returns getAidlPackage(fqName) with '.' replaced by '/'
80     // android.hardware.foo@1.x -> android/hardware/foo
81     static std::string getAidlPackagePath(const FQName& fqName);
82 
83     // getAidlFQName = getAidlPackage + "." + getAidlName
84     static std::optional<std::string> getAidlFQName(const FQName& fqName);
85 
86     // if a HIDL type is replaced, this returns the ReplacedTypeInfo for the new AIDL type
87     static std::optional<const ReplacedTypeInfo> getAidlReplacedType(const FQName& fqName);
88 
89     static void emitFileHeader(
90             Formatter& out, const NamedType& type,
91             const std::map<const NamedType*, const ProcessedCompoundType>& processedTypes);
92     static Formatter getFileWithHeader(
93             const NamedType& namedType, const Coordinator& coordinator,
94             const std::map<const NamedType*, const ProcessedCompoundType>& processedTypes);
95 
96     /* Methods for Type */
97     static std::string getAidlType(const Type& type, const FQName& relativeTo,
98                                    AidlBackend backend = AidlBackend::UNKNOWN);
99 
100     /* Methods for NamedType */
101     static void emitAidl(
102             const NamedType& namedType, Formatter& out,
103             const std::map<const NamedType*, const ProcessedCompoundType>& processedTypes);
104 
105     // Walk through all of the type's parents until we reach the top and return.
106     static const NamedType* getTopLevelType(const NamedType* type);
107 
108     /* Methods for Interface */
109     static void emitAidl(const Interface& interface, Formatter& out,
110                          const std::map<const NamedType*, const ProcessedCompoundType>&);
111     // Returns all methods that would exist in an AIDL equivalent interface
112     static std::vector<const Method*> getUserDefinedMethods(Formatter& out,
113                                                             const Interface& interface);
114 
115     static void processCompoundType(const CompoundType& compoundType,
116                                     ProcessedCompoundType* processedType,
117                                     const std::string& fieldNamePrefix);
118 
119     static Formatter& notes();
120     static void setNotes(Formatter* formatter);
121 
122     // return the full file names for the header/source files based on the backend
123     static std::string translateHeaderFile(const FQName& fqName, AidlBackend backend);
124     static std::string translateSourceFile(const FQName& fqName, AidlBackend backend);
125 
126     static void emitTranslation(
127             const Coordinator& coordinator, const FQName& fqName,
128             const std::set<const NamedType*>& namedTypesInPackage,
129             const std::map<const NamedType*, const ProcessedCompoundType>& processedTypes);
130     static void setFileHeader(const std::string& file);
131     static void emitFileHeader(Formatter& out);
setExpandExtendedAidlHelper132     static void setExpandExtended(bool expand) { expandExtended = expand; };
isExpandExtendedAidlHelper133     static bool isExpandExtended() { return expandExtended; };
134     static bool shouldBeExpanded(const FQName& source, const FQName& extended);
135 
136   private:
137     // This is the formatter to use for additional conversion output
138     static Formatter* notesFormatter;
139     static std::string fileHeader;
140     static bool expandExtended;
141 };
142 
143 }  // namespace android
144