Home | History | Annotate | Download | only in hidl
      1 /*
      2  * Copyright (C) 2016 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 #ifndef AST_H_
     18 
     19 #define AST_H_
     20 
     21 #include <android-base/macros.h>
     22 #include <hidl-hash/Hash.h>
     23 #include <hidl-util/FQName.h>
     24 #include <functional>
     25 #include <map>
     26 #include <set>
     27 #include <string>
     28 #include <vector>
     29 
     30 #include "Scope.h"
     31 #include "Type.h"
     32 
     33 namespace android {
     34 
     35 struct Coordinator;
     36 struct ConstantExpression;
     37 struct EnumValue;
     38 struct Formatter;
     39 struct Interface;
     40 struct Location;
     41 struct Method;
     42 struct NamedType;
     43 template <class T>
     44 struct NamedReference;
     45 struct Type;
     46 
     47 struct AST {
     48     AST(const Coordinator* coordinator, const Hash* fileHash);
     49 
     50     bool setPackage(const char *package);
     51     bool addImport(const char *import);
     52 
     53     // package and version really.
     54     FQName package() const;
     55     bool isInterface() const;
     56     bool containsInterfaces() const;
     57 
     58     // Adds package, version and scope stack to local name
     59     FQName makeFullName(const char* localName, Scope* scope) const;
     60 
     61     void addScopedType(NamedType* type, Scope* scope);
     62 
     63     const std::string& getFilename() const;
     64     const Hash* getFileHash() const;
     65 
     66     // Look up local identifier.
     67     // It could be plain identifier or enum value as described by lookupEnumValue.
     68     LocalIdentifier* lookupLocalIdentifier(const Reference<LocalIdentifier>& ref, Scope* scope);
     69 
     70     // Look up an enum value by "FQName:valueName".
     71     EnumValue* lookupEnumValue(const FQName& fqName, std::string* errorMsg, Scope* scope);
     72 
     73     // Look up a type by FQName, "pure" names, i.e. those without package
     74     // or version are first looked up in the current scope chain.
     75     // After that lookup proceeds to imports.
     76     Type* lookupType(const FQName& fqName, Scope* scope);
     77 
     78     void addImportedAST(AST *ast);
     79 
     80     // Calls all passes after parsing required before
     81     // being ready to generate output.
     82     status_t postParse();
     83 
     84     // Recursive pass on constant expression tree
     85     status_t constantExpressionRecursivePass(
     86         const std::function<status_t(ConstantExpression*)>& func, bool processBeforeDependencies);
     87 
     88     // Recursive tree pass that looks up all referenced types
     89     status_t lookupTypes();
     90 
     91     // Recursive tree pass that looks up all referenced local identifiers
     92     status_t lookupLocalIdentifiers();
     93 
     94     // Recursive tree pass that validates that all defined types
     95     // have unique names in their scopes.
     96     status_t validateDefinedTypesUniqueNames() const;
     97 
     98     // Recursive tree pass that completes type declarations
     99     // that depend on super types
    100     status_t resolveInheritance();
    101 
    102     // Recursive tree pass that evaluates constant expressions
    103     status_t evaluate();
    104 
    105     // Recursive tree pass that validates all type-related
    106     // syntax restrictions
    107     status_t validate() const;
    108 
    109     // Recursive tree pass that ensures that type definitions and references
    110     // are acyclic and reorderes type definitions in reversed topological order.
    111     status_t topologicalReorder();
    112 
    113     // Recursive tree pass that ensures that constant expressions
    114     // are acyclic.
    115     status_t checkAcyclicConstantExpressions() const;
    116 
    117     // Recursive tree pass that checks C++ forward declaration restrictions.
    118     status_t checkForwardReferenceRestrictions() const;
    119 
    120     status_t gatherReferencedTypes();
    121 
    122     void generateCppSource(Formatter& out) const;
    123 
    124     void generateInterfaceHeader(Formatter& out) const;
    125     void generateHwBinderHeader(Formatter& out) const;
    126     void generateStubHeader(Formatter& out) const;
    127     void generateProxyHeader(Formatter& out) const;
    128     void generatePassthroughHeader(Formatter& out) const;
    129 
    130     void generateCppImplHeader(Formatter& out) const;
    131     void generateCppImplSource(Formatter& out) const;
    132 
    133     void generateCppAdapterHeader(Formatter& out) const;
    134     void generateCppAdapterSource(Formatter& out) const;
    135 
    136     void generateJava(Formatter& out, const std::string& limitToType) const;
    137     void generateJavaTypes(Formatter& out, const std::string& limitToType) const;
    138 
    139     void generateVts(Formatter& out) const;
    140 
    141     void getImportedPackages(std::set<FQName> *importSet) const;
    142 
    143     // Run getImportedPackages on this, then run getImportedPackages on
    144     // each AST in each package referenced in importSet.
    145     void getImportedPackagesHierarchy(std::set<FQName> *importSet) const;
    146 
    147     bool isJavaCompatible() const;
    148 
    149     // Warning: this only includes names explicitly referenced in code.
    150     //   It does not include all names which are imported.
    151     //
    152     // Currently, there is one valid usecase for this: importing exactly
    153     // the names which need to be imported in generated code. If you import
    154     // based on getAllImportedNamesGranular instead, you will import things
    155     // that aren't actually used in the resultant code.
    156     //
    157     // Get transitive closure of imported interface/types. This will add
    158     // everything exported by a package even if only a single type from
    159     // that package was explicitly imported!
    160     void getAllImportedNames(std::set<FQName> *allImportSet) const;
    161 
    162     // Get imported types, this includes those explicitly imported as well
    163     // as all types defined in imported packages.
    164     void getAllImportedNamesGranular(std::set<FQName> *allImportSet) const;
    165 
    166     void appendToExportedTypesVector(
    167             std::vector<const Type *> *exportedTypes) const;
    168 
    169     // used by the parser.
    170     void addSyntaxError();
    171     size_t syntaxErrors() const;
    172 
    173     bool isIBase() const;
    174 
    175     // or nullptr if not isInterface
    176     const Interface *getInterface() const;
    177 
    178     // types or Interface base name (e.x. Foo)
    179     std::string getBaseName() const;
    180 
    181     Scope* getRootScope();
    182 
    183     static void generateCppPackageInclude(Formatter& out, const FQName& package,
    184                                           const std::string& klass);
    185 
    186     void addDefinedTypes(std::set<FQName> *definedTypes) const;
    187     void addReferencedTypes(std::set<FQName> *referencedTypes) const;
    188 
    189     void addToImportedNamesGranular(const FQName &fqName);
    190 
    191    private:
    192     const Coordinator* mCoordinator;
    193     const Hash* mFileHash;
    194 
    195     RootScope mRootScope;
    196 
    197     FQName mPackage;
    198 
    199     // A set of all external interfaces/types that are _actually_ referenced
    200     // in this AST, this is a subset of those specified in import statements.
    201     // Note that this set only resolves to the granularity of either an
    202     // interface type or a whole package.
    203     std::set<FQName> mImportedNames;
    204 
    205     // This is the set of actually imported types.
    206     std::set<FQName> mImportedNamesGranular;
    207 
    208     // Warning: this only includes names explicitly referenced in code.
    209     //   It does not include all names which are imported.
    210     //
    211     // A set of all ASTs we explicitly or implicitly (types.hal) import.
    212     std::set<AST *> mImportedASTs;
    213 
    214     // If a single type (instead of the whole AST) is imported, the AST will be
    215     // present as a key to this map, with the value being a list of types
    216     // imported from this AST. If an AST appears in mImportedASTs but not in
    217     // mImportedTypes, then the whole AST is imported.
    218     std::map<AST *, std::set<Type *>> mImportedTypes;
    219 
    220     // Types keyed by full names defined in this AST.
    221     std::map<FQName, Type *> mDefinedTypesByFullName;
    222 
    223     // used by the parser.
    224     size_t mSyntaxErrors = 0;
    225 
    226     std::set<FQName> mReferencedTypeNames;
    227 
    228     // Helper functions for lookupType.
    229     Type* lookupTypeLocally(const FQName& fqName, Scope* scope);
    230     status_t lookupAutofilledType(const FQName &fqName, Type **returnedType);
    231     Type *lookupTypeFromImports(const FQName &fqName);
    232 
    233     // Find a type matching fqName (which may be partial) and if found
    234     // return the associated type and fill in the full "matchingName".
    235     // Only types defined in this very AST are considered.
    236     Type *findDefinedType(const FQName &fqName, FQName *matchingName) const;
    237 
    238     void getPackageComponents(std::vector<std::string> *components) const;
    239 
    240     void getPackageAndVersionComponents(
    241             std::vector<std::string> *components, bool cpp_compatible) const;
    242 
    243     std::string makeHeaderGuard(const std::string &baseName,
    244                                 bool indicateGenerated = true) const;
    245     void enterLeaveNamespace(Formatter &out, bool enter) const;
    246 
    247     static void generateCheckNonNull(Formatter &out, const std::string &nonNull);
    248 
    249     void generateTypeSource(Formatter& out, const std::string& ifaceName) const;
    250 
    251     // a method, and in which interface is it originally defined.
    252     // be careful of the case where method.isHidlReserved(), where interface
    253     // is effectively useless.
    254     using MethodGenerator = std::function<void(const Method*, const Interface*)>;
    255 
    256     void generateTemplatizationLink(Formatter& out) const;
    257     void generateCppTag(Formatter& out, const std::string& tag) const;
    258 
    259     void generateMethods(Formatter& out, const MethodGenerator& gen,
    260                          bool includeParents = true) const;
    261     void generateStubImplMethod(Formatter& out, const std::string& className,
    262                                 const Method* method) const;
    263     void generatePassthroughMethod(Formatter& out, const Method* method) const;
    264     void generateStaticProxyMethodSource(Formatter& out, const std::string& className,
    265                                          const Method* method) const;
    266     void generateProxyMethodSource(Formatter& out, const std::string& className,
    267                                    const Method* method, const Interface* superInterface) const;
    268     void generateAdapterMethod(Formatter& out, const Method* method) const;
    269 
    270     void generateFetchSymbol(Formatter &out, const std::string &ifaceName) const;
    271 
    272     void generateProxySource(Formatter& out, const FQName& fqName) const;
    273 
    274     void generateStubSource(Formatter& out, const Interface* iface) const;
    275 
    276     void generateStubSourceForMethod(Formatter& out, const Method* method,
    277                                      const Interface* superInterface) const;
    278     void generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
    279                                         const Method* method) const;
    280 
    281     void generatePassthroughSource(Formatter& out) const;
    282 
    283     void generateInterfaceSource(Formatter& out) const;
    284 
    285     enum InstrumentationEvent {
    286         SERVER_API_ENTRY = 0,
    287         SERVER_API_EXIT,
    288         CLIENT_API_ENTRY,
    289         CLIENT_API_EXIT,
    290         SYNC_CALLBACK_ENTRY,
    291         SYNC_CALLBACK_EXIT,
    292         ASYNC_CALLBACK_ENTRY,
    293         ASYNC_CALLBACK_EXIT,
    294         PASSTHROUGH_ENTRY,
    295         PASSTHROUGH_EXIT,
    296     };
    297 
    298     void generateCppAtraceCall(
    299             Formatter &out,
    300             InstrumentationEvent event,
    301             const Method *method) const;
    302 
    303     void generateCppInstrumentationCall(
    304             Formatter &out,
    305             InstrumentationEvent event,
    306             const Method *method) const;
    307 
    308     void declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& arg,
    309                                 bool forResults) const;
    310 
    311     void emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
    312                              const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
    313                              bool addPrefixToName) const;
    314 
    315     void emitCppResolveReferences(Formatter& out, const std::string& parcelObj,
    316                                   bool parcelObjIsPointer, const NamedReference<Type>* arg,
    317                                   bool isReader, Type::ErrorMode mode, bool addPrefixToName) const;
    318 
    319     void emitJavaReaderWriter(Formatter& out, const std::string& parcelObj,
    320                               const NamedReference<Type>* arg, bool isReader,
    321                               bool addPrefixToName) const;
    322 
    323     void emitTypeDeclarations(Formatter& out) const;
    324     void emitJavaTypeDeclarations(Formatter& out) const;
    325     void emitVtsTypeDeclarations(Formatter& out) const;
    326 
    327     DISALLOW_COPY_AND_ASSIGN(AST);
    328 };
    329 
    330 }  // namespace android
    331 
    332 #endif  // AST_H_
    333