| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef AST_H_ |
| |
| #define AST_H_ |
| |
| #include <android-base/macros.h> |
| #include <map> |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include "FQName.h" |
| #include "Type.h" |
| |
| namespace android { |
| |
| struct Coordinator; |
| struct Formatter; |
| struct Interface; |
| struct Location; |
| struct Method; |
| struct NamedType; |
| struct TypedVar; |
| struct Scope; |
| struct EnumValue; |
| |
| struct AST { |
| AST(Coordinator *coordinator, const std::string &path); |
| ~AST(); |
| |
| bool setPackage(const char *package); |
| bool addImport(const char *import); |
| |
| // package and version really. |
| FQName package() const; |
| bool isInterface(std::string *ifaceName) const; |
| bool containsInterfaces() const; |
| |
| void enterScope(Scope *container); |
| void leaveScope(); |
| Scope *scope(); |
| |
| // Returns true iff successful. |
| bool addTypeDef(const char *localName, Type *type, const Location &location, |
| std::string *errorMsg); |
| |
| // Returns true iff successful. |
| bool addScopedType(NamedType *type, std::string *errorMsg); |
| |
| void *scanner(); |
| void setScanner(void *scanner); |
| |
| const std::string &getFilename() const; |
| |
| // Look up an enum value by "FQName:valueName". |
| EnumValue *lookupEnumValue(const FQName &fqName, std::string *errorMsg); |
| |
| // Look up a type by FQName, "pure" names, i.e. those without package |
| // or version are first looked up in the current scope chain. |
| // After that lookup proceeds to imports. |
| Type *lookupType(const FQName &fqName); |
| |
| void addImportedAST(AST *ast); |
| |
| status_t generateCpp(const std::string &outputPath) const; |
| status_t generateCppImpl(const std::string &outputPath) const; |
| |
| status_t generateJava( |
| const std::string &outputPath, |
| const std::string &limitToType) const; |
| |
| status_t generateJavaTypes( |
| const std::string &outputPath, |
| const std::string &limitToType) const; |
| |
| void getImportedPackages(std::set<FQName> *importSet) const; |
| |
| // Run getImportedPackages on this, then run getImportedPackages on |
| // each AST in each package referenced in importSet. |
| void getImportedPackagesHierarchy(std::set<FQName> *importSet) const; |
| |
| status_t generateVts(const std::string &outputPath) const; |
| |
| bool isJavaCompatible() const; |
| |
| // Return the set of FQNames for those interfaces and types that are |
| // actually referenced in the AST, not merely imported. |
| |
| const std::set<FQName>& getImportedNames() const { |
| return mImportedNames; |
| } |
| |
| void appendToExportedTypesVector( |
| std::vector<const Type *> *exportedTypes) const; |
| |
| // used by the parser. |
| void addSyntaxError(); |
| size_t syntaxErrors() const; |
| |
| bool isIBase() const; |
| |
| private: |
| Coordinator *mCoordinator; |
| std::string mPath; |
| std::vector<Scope *> mScopePath; |
| |
| void *mScanner; |
| Scope *mRootScope; |
| |
| FQName mPackage; |
| |
| // A set of all external interfaces/types that are _actually_ referenced |
| // in this AST, this is a subset of those specified in import statements. |
| std::set<FQName> mImportedNames; |
| |
| // A set of all ASTs we explicitly or implicitly (types.hal) import. |
| std::set<AST *> mImportedASTs; |
| |
| // If a single type (instead of the whole AST) is imported, the AST will be |
| // present as a key to this map, with the value being a list of types |
| // imported from this AST. If an AST appears in mImportedASTs but not in |
| // mImportedTypes, then the whole AST is imported. |
| std::map<AST *, std::set<Type *>> mImportedTypes; |
| |
| // Types keyed by full names defined in this AST. |
| std::map<FQName, Type *> mDefinedTypesByFullName; |
| |
| // used by the parser. |
| size_t mSyntaxErrors = 0; |
| |
| bool addScopedTypeInternal( |
| NamedType *type, |
| std::string *errorMsg); |
| |
| // Find a type matching fqName (which may be partial) and if found |
| // return the associated type and fill in the full "matchingName". |
| // Only types defined in this very AST are considered. |
| Type *findDefinedType(const FQName &fqName, FQName *matchingName) const; |
| |
| void getPackageComponents(std::vector<std::string> *components) const; |
| |
| void getPackageAndVersionComponents( |
| std::vector<std::string> *components, bool cpp_compatible) const; |
| |
| static void generateCppPackageInclude( |
| Formatter &out, |
| const FQName &package, |
| const std::string &klass); |
| |
| std::string makeHeaderGuard(const std::string &baseName, |
| bool indicateGenerated = true) const; |
| void enterLeaveNamespace(Formatter &out, bool enter) const; |
| |
| static void generateCheckNonNull(Formatter &out, const std::string &nonNull); |
| |
| status_t generateInterfaceHeader(const std::string &outputPath) const; |
| status_t generateHwBinderHeader(const std::string &outputPath) const; |
| status_t generateStubHeader(const std::string &outputPath) const; |
| status_t generateProxyHeader(const std::string &outputPath) const; |
| status_t generateAllSource(const std::string &outputPath) const; |
| status_t generatePassthroughHeader(const std::string &outputPath) const; |
| |
| status_t generateTypeSource( |
| Formatter &out, const std::string &ifaceName) const; |
| |
| // a method, and in which interface is it originally defined. |
| // be careful of the case where method.isHidlReserved(), where interface |
| // is effectively useless. |
| using MethodGenerator = std::function<status_t(const Method *, const Interface *)>; |
| |
| status_t generateStubImplHeader(const std::string &outputPath) const; |
| status_t generateStubImplSource(const std::string &outputPath) const; |
| |
| status_t generateMethods(Formatter &out, MethodGenerator gen) const; |
| status_t generateStubMethod(Formatter &out, |
| const Method *method) const; |
| status_t generateStubImplMethod(Formatter &out, |
| const std::string &className, |
| const Method *method) const; |
| status_t generatePassthroughMethod(Formatter &out, |
| const Method *method) const; |
| status_t generateProxyMethodSource(Formatter &out, |
| const std::string &className, |
| const Method *method, |
| const Interface *superInterface) const; |
| |
| void generateFetchSymbol(Formatter &out, const std::string &ifaceName) const; |
| |
| status_t generateProxySource( |
| Formatter &out, const std::string &baseName) const; |
| |
| status_t generateStubSource( |
| Formatter &out, const std::string &baseName) const; |
| |
| status_t generateStubSourceForMethod( |
| Formatter &out, const Interface *iface, const Method *method) const; |
| |
| status_t generatePassthroughSource(Formatter &out) const; |
| |
| status_t generateInterfaceSource(Formatter &out) const; |
| |
| enum InstrumentationEvent { |
| SERVER_API_ENTRY = 0, |
| SERVER_API_EXIT, |
| CLIENT_API_ENTRY, |
| CLIENT_API_EXIT, |
| SYNC_CALLBACK_ENTRY, |
| SYNC_CALLBACK_EXIT, |
| ASYNC_CALLBACK_ENTRY, |
| ASYNC_CALLBACK_EXIT, |
| PASSTHROUGH_ENTRY, |
| PASSTHROUGH_EXIT, |
| }; |
| |
| status_t generateCppAtraceCall( |
| Formatter &out, |
| InstrumentationEvent event, |
| const Method *method) const; |
| |
| status_t generateCppInstrumentationCall( |
| Formatter &out, |
| InstrumentationEvent event, |
| const Method *method) const; |
| |
| void declareCppReaderLocals( |
| Formatter &out, |
| const std::vector<TypedVar *> &arg, |
| bool forResults) const; |
| |
| void emitCppReaderWriter( |
| Formatter &out, |
| const std::string &parcelObj, |
| bool parcelObjIsPointer, |
| const TypedVar *arg, |
| bool isReader, |
| Type::ErrorMode mode, |
| bool addPrefixToName) const; |
| |
| void emitCppResolveReferences( |
| Formatter &out, |
| const std::string &parcelObj, |
| bool parcelObjIsPointer, |
| const TypedVar *arg, |
| bool isReader, |
| Type::ErrorMode mode, |
| bool addPrefixToName) const; |
| |
| void emitJavaReaderWriter( |
| Formatter &out, |
| const std::string &parcelObj, |
| const TypedVar *arg, |
| bool isReader) const; |
| |
| status_t emitTypeDeclarations(Formatter &out) const; |
| status_t emitJavaTypeDeclarations(Formatter &out) const; |
| status_t emitVtsTypeDeclarations(Formatter &out) const; |
| |
| // Helper function that generates vts type declaration from the current |
| // AST and the transitive closure of imported ASTs. |
| status_t emitVtsTypeDeclarationsHelper( |
| Formatter &out, |
| std::set<AST*> *allImportSet) const; |
| |
| DISALLOW_COPY_AND_ASSIGN(AST); |
| }; |
| |
| } // namespace android |
| |
| #endif // AST_H_ |