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     // android.hardware.foo@1.0::IBar.Baz -> IBarBaz
67     static std::string getAidlName(const FQName& fqName);
68 
69     // getAidlPackage returns the AIDL package
70     // android.hardware.foo@1.x -> android.hardware.foo
71     // android.hardware.foo@2.x -> android.hardware.foo2
72     static std::string getAidlPackage(const FQName& fqName);
73     // returns getAidlPackage(fqName) with '.' replaced by '/'
74     // android.hardware.foo@1.x -> android/hardware/foo
75     static std::string getAidlPackagePath(const FQName& fqName);
76 
77     // getAidlFQName = getAidlPackage + "." + getAidlName
78     static std::optional<std::string> getAidlFQName(const FQName& fqName);
79 
80     // if a HIDL type is replaced, this returns the ReplacedTypeInfo for the new AIDL type
81     static std::optional<const ReplacedTypeInfo> getAidlReplacedType(const FQName& fqName);
82 
83     static void emitFileHeader(
84             Formatter& out, const NamedType& type,
85             const std::map<const NamedType*, const ProcessedCompoundType>& processedTypes);
86     static void importLocallyReferencedType(const Type& type, std::set<std::string>* imports);
87     static Formatter getFileWithHeader(
88             const NamedType& namedType, const Coordinator& coordinator,
89             const std::map<const NamedType*, const ProcessedCompoundType>& processedTypes);
90 
91     /* Methods for Type */
92     static std::string getAidlType(const Type& type, const FQName& relativeTo);
93 
94     /* Methods for NamedType */
95     static void emitAidl(
96             const NamedType& namedType, const Coordinator& coordinator,
97             const std::map<const NamedType*, const ProcessedCompoundType>& processedTypes);
98 
99     /* Methods for Interface */
100     static void emitAidl(const Interface& interface, const Coordinator& coordinator,
101                          const std::map<const NamedType*, const ProcessedCompoundType>&);
102     // Returns all methods that would exist in an AIDL equivalent interface
103     static std::vector<const Method*> getUserDefinedMethods(Formatter& out,
104                                                             const Interface& interface);
105 
106     static void processCompoundType(const CompoundType& compoundType,
107                                     ProcessedCompoundType* processedType,
108                                     const std::string& fieldNamePrefix);
109 
110     static Formatter& notes();
111     static void setNotes(Formatter* formatter);
112 
113     // return the full file names for the header/source files based on the backend
114     static std::string translateHeaderFile(const FQName& fqName, AidlBackend backend);
115     static std::string translateSourceFile(const FQName& fqName, AidlBackend backend);
116 
117     static void emitTranslation(
118             const Coordinator& coordinator, const FQName& fqName,
119             const std::set<const NamedType*>& namedTypesInPackage,
120             const std::map<const NamedType*, const ProcessedCompoundType>& processedTypes);
121     static void setFileHeader(const std::string& file);
122     static void emitFileHeader(Formatter& out);
setExpandExtendedAidlHelper123     static void setExpandExtended(bool expand) { expandExtended = expand; };
isExpandExtendedAidlHelper124     static bool isExpandExtended() { return expandExtended; };
125     static bool shouldBeExpanded(const FQName& source, const FQName& extended);
126 
127   private:
128     // This is the formatter to use for additional conversion output
129     static Formatter* notesFormatter;
130     static std::string fileHeader;
131     static bool expandExtended;
132 };
133 
134 }  // namespace android
135