Home | History | Annotate | Download | only in script_api
      1 /*
      2  * Copyright (C) 2015 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 ANDROID_RS_API_GENERATOR_SPECIFICATION_H
     18 #define ANDROID_RS_API_GENERATOR_SPECIFICATION_H
     19 
     20 // See Generator.cpp for documentation of the .spec file format.
     21 
     22 #include <climits>
     23 #include <fstream>
     24 #include <list>
     25 #include <map>
     26 #include <string>
     27 #include <vector>
     28 
     29 class Constant;
     30 class ConstantSpecification;
     31 class Function;
     32 class FunctionPermutation;
     33 class FunctionSpecification;
     34 class SpecFile;
     35 class Specification;
     36 class Scanner;
     37 class SystemSpecification;
     38 class Type;
     39 class TypeSpecification;
     40 
     41 enum NumberKind { SIGNED_INTEGER, UNSIGNED_INTEGER, FLOATING_POINT };
     42 
     43 // Table of type equivalences.
     44 struct NumericalType {
     45     const char* specType;    // Name found in the .spec file
     46     const char* rsDataType;  // RS data type
     47     const char* cType;       // Type in a C file
     48     const char* javaType;    // Type in a Java file
     49     NumberKind kind;
     50     /* For integers, number of bits of the number, excluding the sign bit.
     51      * For floats, number of implied bits of the mantissa.
     52      */
     53     int significantBits;
     54     // For floats, number of bits of the exponent.  0 for integer types.
     55     int exponentBits;
     56 };
     57 
     58 /* Corresponds to one parameter line in a .spec file.  These will be parsed when
     59  * we instantiate the FunctionPermutation(s) that correspond to one FunctionSpecification.
     60  */
     61 struct ParameterEntry {
     62     std::string type;
     63     std::string name;
     64     /* Optional information on how to generate test values for this parameter.  Can be:
     65      * - range(low, high): Generates values between these two limits only.
     66      * - above(other_parameter): The values must be greater than those of the named parameter.
     67      *       Used for clamp.
     68      * - compatible(type): The values must also be fully representable in the specified type.
     69      * - conditional: Don't verify this value the function return NaN.
     70      */
     71     std::string testOption;
     72     std::string documentation;
     73     int lineNumber;
     74 };
     75 
     76 /* Information about a parameter to a function.  The values of all the fields should only be set by
     77  * parseParameterDefinition.
     78  */
     79 struct ParameterDefinition {
     80     std::string rsType;        // The Renderscript type, e.g. "uint3"
     81     std::string rsBaseType;    // As above but without the number, e.g. "uint"
     82     std::string javaBaseType;  // The type we need to declare in Java, e.g. "unsigned int"
     83     std::string specType;      // The type found in the spec, e.g. "f16"
     84     bool isFloatType;          // True if it's a floating point value
     85     /* The number of entries in the vector.  It should be either "1", "2", "3", or "4".  It's also
     86      * "1" for scalars.
     87      */
     88     std::string mVectorSize;
     89     /* The space the vector takes in an array.  It's the same as the vector size, except for size
     90      * "3", where the width is "4".
     91      */
     92     std::string vectorWidth;
     93 
     94     std::string specName;       // e.g. x, as found in the spec file
     95     std::string variableName;   // e.g. inX, used both in .rs and .java
     96     std::string rsAllocName;    // e.g. gAllocInX
     97     std::string javaAllocName;  // e.g. inX
     98     std::string javaArrayName;  // e.g. arrayInX
     99     std::string doubleVariableName; // e.g. inXDouble, used in .java for storing Float16 parameters
    100                                     // in double.
    101 
    102     // If non empty, the mininum and maximum values to be used when generating the test data.
    103     std::string minValue;
    104     std::string maxValue;
    105     /* If non empty, contains the name of another parameter that should be smaller or equal to this
    106      * parameter, i.e.  value(smallerParameter) <= value(this).  This is used when testing clamp.
    107      */
    108     std::string smallerParameter;
    109 
    110     bool isOutParameter;       // True if this parameter returns data from the script.
    111     bool undefinedIfOutIsNan;  // If true, we don't validate if 'out' is NaN.
    112 
    113     int typeIndex;            // Index in the TYPES array. Negative if not found in the array.
    114     int compatibleTypeIndex;  // Index in TYPES for which the test data must also fit.
    115 
    116     /* Fill this object from the type, name, and testOption.
    117      * isReturn is true if we're processing the "return:"
    118      */
    119     void parseParameterDefinition(const std::string& type, const std::string& name,
    120                                   const std::string& testOption, int lineNumber, bool isReturn,
    121                                   Scanner* scanner);
    122 
    123     bool isFloat16Parameter() const { return specType.compare("f16") == 0; }
    124 };
    125 
    126 struct VersionInfo {
    127     /* The range of versions a specification applies to. Zero if there's no restriction,
    128      * so an API that became available at 12 and is still valid would have min:12 max:0.
    129      * If non zero, both versions should be at least 9, the API level that introduced
    130      * RenderScript.
    131      */
    132     unsigned int minVersion;
    133     unsigned int maxVersion;
    134     // Either 0, 32 or 64.  If 0, this definition is valid for both 32 and 64 bits.
    135     int intSize;
    136 
    137     VersionInfo() : minVersion(0), maxVersion(0), intSize(0) {}
    138     /* Scan the version info from the spec file.  maxApiLevel specifies the maximum level
    139      * we are interested in.  This may alter maxVersion.  This method returns false if the
    140      * minVersion is greater than the maxApiLevel.
    141      */
    142     bool scan(Scanner* scanner, unsigned int maxApiLevel);
    143     /* Return true if the target can be found whitin the range. */
    144     bool includesVersion(int target) const {
    145         return (minVersion == 0 || target >= minVersion) &&
    146                (maxVersion == 0 || target <= maxVersion);
    147     }
    148 
    149     static constexpr unsigned int kUnreleasedVersion = UINT_MAX;
    150 };
    151 
    152 // We have three type of definitions
    153 class Definition {
    154 protected:
    155     std::string mName;
    156     /* If greater than 0, this definition is deprecated.  It's the API level at which
    157      * we added the deprecation warning.
    158      */
    159     int mDeprecatedApiLevel;
    160     std::string mDeprecatedMessage;         // Optional specific warning if the API is deprecated
    161     bool mHidden;                           // True if it should not be documented
    162     std::string mSummary;                   // A one-line description
    163     std::vector<std::string> mDescription;  // The comments to be included in the header
    164     std::string mUrl;                       // The URL of the detailed documentation
    165     int mFinalVersion;  // API level at which this API was removed, 0 if API is still valid
    166 
    167 public:
    168     Definition(const std::string& name);
    169 
    170     std::string getName() const { return mName; }
    171     bool deprecated() const { return mDeprecatedApiLevel > 0; }
    172     int getDeprecatedApiLevel() const { return mDeprecatedApiLevel; }
    173     std::string getDeprecatedMessage() const { return mDeprecatedMessage; }
    174     bool hidden() const { return mHidden; }
    175     std::string getSummary() const { return mSummary; }
    176     const std::vector<std::string>& getDescription() const { return mDescription; }
    177     std::string getUrl() const { return mUrl; }
    178     int getFinalVersion() const { return mFinalVersion; }
    179 
    180     void scanDocumentationTags(Scanner* scanner, bool firstOccurence, const SpecFile* specFile);
    181     // Keep track of the final version of this API, if any.
    182     void updateFinalVersion(const VersionInfo& info);
    183 };
    184 
    185 /* Represents a constant, like M_PI.  This is a grouping of the version specific specifications.
    186  * We'll only have one instance of Constant for each name.
    187  */
    188 class Constant : public Definition {
    189 private:
    190     std::vector<ConstantSpecification*> mSpecifications;  // Owned
    191 
    192 public:
    193     Constant(const std::string& name) : Definition(name) {}
    194     ~Constant();
    195 
    196     const std::vector<ConstantSpecification*> getSpecifications() const { return mSpecifications; }
    197     // This method should only be called by the scanning code.
    198     void addSpecification(ConstantSpecification* spec) { mSpecifications.push_back(spec); }
    199 };
    200 
    201 /* Represents a type, like "float4".  This is a grouping of the version specific specifications.
    202  * We'll only have one instance of Type for each name.
    203  */
    204 class Type : public Definition {
    205 private:
    206     std::vector<TypeSpecification*> mSpecifications;  // Owned
    207 
    208 public:
    209     Type(const std::string& name) : Definition(name) {}
    210     ~Type();
    211 
    212     const std::vector<TypeSpecification*> getSpecifications() const { return mSpecifications; }
    213     // This method should only be called by the scanning code.
    214     void addSpecification(TypeSpecification* spec) { mSpecifications.push_back(spec); }
    215 };
    216 
    217 /* Represents a function, like "clamp".  Even though the spec file contains many entries for clamp,
    218  * we'll only have one clamp instance.
    219  */
    220 class Function : public Definition {
    221 private:
    222     // mName in the base class contains the lower case name, e.g. native_log
    223     std::string mCapitalizedName;  // The capitalized name, e.g. NativeLog
    224 
    225     // The unique parameters between all the specifications.  NOT OWNED.
    226     std::vector<ParameterEntry*> mParameters;
    227     std::string mReturnDocumentation;
    228 
    229     std::vector<FunctionSpecification*> mSpecifications;  // Owned
    230 
    231 public:
    232     Function(const std::string& name);
    233     ~Function();
    234 
    235     std::string getCapitalizedName() const { return mCapitalizedName; }
    236     const std::vector<ParameterEntry*>& getParameters() const { return mParameters; }
    237     std::string getReturnDocumentation() const { return mReturnDocumentation; }
    238     const std::vector<FunctionSpecification*> getSpecifications() const { return mSpecifications; }
    239 
    240     bool someParametersAreDocumented() const;
    241 
    242     // The following methods should only be called by the scanning code.
    243     void addParameter(ParameterEntry* entry, Scanner* scanner);
    244     void addReturn(ParameterEntry* entry, Scanner* scanner);
    245     void addSpecification(FunctionSpecification* spec) { mSpecifications.push_back(spec); }
    246 };
    247 
    248 /* Base class for TypeSpecification, ConstantSpecification, and FunctionSpecification.
    249  * A specification can be specific to a range of RenderScript version or 32bits vs 64 bits.
    250  * This base class contains code to parse and store this version information.
    251  */
    252 class Specification {
    253 protected:
    254     VersionInfo mVersionInfo;
    255     void scanVersionInfo(Scanner* scanner);
    256 
    257 public:
    258     VersionInfo getVersionInfo() const { return mVersionInfo; }
    259 };
    260 
    261 /* Defines one of the many variations of a constant.  There's a one to one correspondence between
    262  * ConstantSpecification objects and entries in the spec file.
    263  */
    264 class ConstantSpecification : public Specification {
    265 private:
    266     Constant* mConstant;  // Not owned
    267 
    268     std::string mValue;  // E.g. "3.1415"
    269     std::string mType;   // E.g. "float"
    270 public:
    271     ConstantSpecification(Constant* constant) : mConstant(constant) {}
    272 
    273     Constant* getConstant() const { return mConstant; }
    274     std::string getValue() const { return mValue; }
    275     std::string getType() const { return mType; }
    276 
    277     // Parse a constant specification and add it to specFile.
    278     static void scanConstantSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel);
    279 };
    280 
    281 enum TypeKind {
    282     SIMPLE,
    283     RS_OBJECT,
    284     STRUCT,
    285     ENUM,
    286 };
    287 
    288 /* Defines one of the many variations of a type.  There's a one to one correspondence between
    289  * TypeSpecification objects and entries in the spec file.
    290  */
    291 class TypeSpecification : public Specification {
    292 private:
    293     Type* mType;  // Not owned
    294 
    295     TypeKind mKind;  // The kind of type specification
    296 
    297     // If mKind is SIMPLE:
    298     std::string mSimpleType;  // The definition of the type
    299 
    300     // If mKind is STRUCT:
    301     std::string mStructName;                  // The name found after the struct keyword
    302     std::vector<std::string> mFields;         // One entry per struct field
    303     std::vector<std::string> mFieldComments;  // One entry per struct field
    304     std::string mAttribute;                   // Some structures may have attributes
    305 
    306     // If mKind is ENUM:
    307     std::string mEnumName;                    // The name found after the enum keyword
    308     std::vector<std::string> mValues;         // One entry per enum value
    309     std::vector<std::string> mValueComments;  // One entry per enum value
    310 public:
    311     TypeSpecification(Type* type) : mType(type) {}
    312 
    313     Type* getType() const { return mType; }
    314     TypeKind getKind() const { return mKind; }
    315     std::string getSimpleType() const { return mSimpleType; }
    316     std::string getStructName() const { return mStructName; }
    317     const std::vector<std::string>& getFields() const { return mFields; }
    318     const std::vector<std::string>& getFieldComments() const { return mFieldComments; }
    319     std::string getAttribute() const { return mAttribute; }
    320     std::string getEnumName() const { return mEnumName; }
    321     const std::vector<std::string>& getValues() const { return mValues; }
    322     const std::vector<std::string>& getValueComments() const { return mValueComments; }
    323 
    324     // Parse a type specification and add it to specFile.
    325     static void scanTypeSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel);
    326 };
    327 
    328 // Maximum number of placeholders (like #1, #2) in function specifications.
    329 const int MAX_REPLACEABLES = 4;
    330 
    331 /* Defines one of the many variations of the function.  There's a one to one correspondence between
    332  * FunctionSpecification objects and entries in the spec file.  Some of the strings that are parts
    333  * of a FunctionSpecification can include placeholders, which are "#1", "#2", "#3", and "#4".  We'll
    334  * replace these by values before generating the files.
    335  */
    336 class FunctionSpecification : public Specification {
    337 private:
    338     Function* mFunction;  // Not owned
    339 
    340     /* How to test.  One of:
    341      * "scalar": Generate test code that checks entries of each vector indepently.  E.g. for
    342      *           sin(float3), the test code will call the CoreMathVerfier.computeSin 3 times.
    343      * "limited": Like "scalar" but we don't generate extreme values.  This is not currently
    344      *            enabled as we were generating to many errors.
    345      * "custom": Like "scalar" but instead of calling CoreMathVerifier.computeXXX() to compute
    346      *           the expected value, we call instead CoreMathVerifier.verifyXXX().  This method
    347      *           returns a string that contains the error message, null if there's no error.
    348      * "vector": Generate test code that calls the CoreMathVerifier only once for each vector.
    349      *           This is useful for APIs like dot() or length().
    350      * "noverify": Generate test code that calls the API but don't verify the returned value.
    351      *             This can discover unresolved references.
    352      * "": Don't test.  This is the default.
    353      */
    354     std::string mTest;
    355     bool mInternal;               // Internal. Not visible to users. (Default: false)
    356     bool mIntrinsic;              // Compiler intrinsic that is lowered to an internal API.
    357                                   // (Default: false)
    358     std::string mAttribute;       // Function attributes.
    359     std::string mPrecisionLimit;  // Maximum precision required when checking output of this
    360                                   // function.
    361 
    362     // The vectors of values with which we'll replace #1, #2, ...
    363     std::vector<std::vector<std::string> > mReplaceables;
    364 
    365     // i-th entry is true if each entry in mReplaceables[i] has an equivalent
    366     // RS numerical type (i.e. present in TYPES global)
    367     std::vector<bool> mIsRSTAllowed;
    368 
    369     /* The collection of permutations for this specification, i.e. this class instantianted
    370      * for specific values of #1, #2, etc.  Owned.
    371      */
    372     std::vector<FunctionPermutation*> mPermutations;
    373 
    374     // The following fields may contain placeholders that will be replaced using the mReplaceables.
    375 
    376     /* As of this writing, convert_... is the only function with #1 in its name.
    377      * The related Function object contains the name of the function without #n, e.g. convert.
    378      * This is the name with the #, e.g. convert_#1_#2
    379      */
    380     std::string mUnexpandedName;
    381     ParameterEntry* mReturn;                   // The return type. The name should be empty.  Owned.
    382     std::vector<ParameterEntry*> mParameters;  // The parameters.  Owned.
    383     std::vector<std::string> mInline;          // The inline code to be included in the header
    384 
    385     /* Substitute the placeholders in the strings (e.g. #1, #2, ...) by the
    386      * corresponding entries in mReplaceables.  Substitute placeholders for RS
    387      * types (#RST_1, #RST_2, ...) by the RS Data type strings (UNSIGNED_8,
    388      * FLOAT_32 etc.) of the corresponding types in mReplaceables.
    389      * indexOfReplaceable1 selects with value to use for #1, same for 2, 3, and
    390      * 4.
    391      */
    392     std::string expandString(std::string s, int indexOfReplaceable[MAX_REPLACEABLES]) const;
    393     void expandStringVector(const std::vector<std::string>& in,
    394                             int replacementIndexes[MAX_REPLACEABLES],
    395                             std::vector<std::string>* out) const;
    396 
    397     // Helper function used by expandString to perform #RST_* substitution
    398     std::string expandRSTypeInString(const std::string &s,
    399                                      const std::string &pattern,
    400                                      const std::string &cTypeStr) const;
    401 
    402     // Fill the mPermutations field.
    403     void createPermutations(Function* function, Scanner* scanner);
    404 
    405 public:
    406     FunctionSpecification(Function* function) : mFunction(function), mInternal(false),
    407         mIntrinsic(false), mReturn(nullptr) {}
    408     ~FunctionSpecification();
    409 
    410     Function* getFunction() const { return mFunction; }
    411     bool isInternal() const { return mInternal; }
    412     bool isIntrinsic() const { return mIntrinsic; }
    413     std::string getAttribute() const { return mAttribute; }
    414     std::string getTest() const { return mTest; }
    415     std::string getPrecisionLimit() const { return mPrecisionLimit; }
    416 
    417     const std::vector<FunctionPermutation*>& getPermutations() const { return mPermutations; }
    418 
    419     std::string getName(int replacementIndexes[MAX_REPLACEABLES]) const;
    420     void getReturn(int replacementIndexes[MAX_REPLACEABLES], std::string* retType,
    421                    int* lineNumber) const;
    422     size_t getNumberOfParams() const { return mParameters.size(); }
    423     void getParam(size_t index, int replacementIndexes[MAX_REPLACEABLES], std::string* type,
    424                   std::string* name, std::string* testOption, int* lineNumber) const;
    425     void getInlines(int replacementIndexes[MAX_REPLACEABLES],
    426                     std::vector<std::string>* inlines) const;
    427 
    428     // Parse the "test:" line.
    429     void parseTest(Scanner* scanner);
    430 
    431     // Return true if we need to generate tests for this function.
    432     bool hasTests(unsigned int versionOfTestFiles) const;
    433 
    434     bool hasInline() const { return mInline.size() > 0; }
    435 
    436     /* Return true if this function can be overloaded.  This is added by default to all
    437      * specifications, so except for the very few exceptions that start the attributes
    438      * with an '=' to avoid this, we'll return true.
    439      */
    440     bool isOverloadable() const {
    441         return mAttribute.empty() || mAttribute[0] != '=';
    442     }
    443 
    444     /* Check if RST_i is present in 's' and report an error if 'allow' is false
    445      * or the i-th replacement list is not a valid candidate for RST_i
    446      * replacement
    447      */
    448     void checkRSTPatternValidity(const std::string &s, bool allow, Scanner *scanner);
    449 
    450     // Parse a function specification and add it to specFile.
    451     static void scanFunctionSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel);
    452 };
    453 
    454 /* A concrete version of a function specification, where all placeholders have been replaced by
    455  * actual values.
    456  */
    457 class FunctionPermutation {
    458 private:
    459     // These are the expanded version of those found on FunctionSpecification
    460     std::string mName;
    461     std::string mNameTrunk;  // The name without any expansion, e.g. convert
    462     std::string mTest;       // How to test.  One of "scalar", "vector", "noverify", "limited", and
    463                              // "none".
    464     std::string mPrecisionLimit;  // Maximum precision required when checking output of this
    465                                   // function.
    466 
    467     // The parameters of the function.  This does not include the return type.  Owned.
    468     std::vector<ParameterDefinition*> mParams;
    469     // The return type.  nullptr if a void function.  Owned.
    470     ParameterDefinition* mReturn;
    471 
    472     // The number of input and output parameters.  mOutputCount counts the return type.
    473     int mInputCount;
    474     int mOutputCount;
    475 
    476     // Whether one of the output parameters is a float.
    477     bool mHasFloatAnswers;
    478 
    479     // The inline code that implements this function.  Will be empty if not an inline.
    480     std::vector<std::string> mInline;
    481 
    482 public:
    483     FunctionPermutation(Function* function, FunctionSpecification* specification,
    484                         int replacementIndexes[MAX_REPLACEABLES], Scanner* scanner);
    485     ~FunctionPermutation();
    486 
    487     std::string getName() const { return mName; }
    488     std::string getNameTrunk() const { return mNameTrunk; }
    489     std::string getTest() const { return mTest; }
    490     std::string getPrecisionLimit() const { return mPrecisionLimit; }
    491 
    492     const std::vector<std::string>& getInline() const { return mInline; }
    493     const ParameterDefinition* getReturn() const { return mReturn; }
    494     int getInputCount() const { return mInputCount; }
    495     int getOutputCount() const { return mOutputCount; }
    496     bool hasFloatAnswers() const { return mHasFloatAnswers; }
    497 
    498     const std::vector<ParameterDefinition*> getParams() const { return mParams; }
    499 };
    500 
    501 // An entire spec file and the methods to process it.
    502 class SpecFile {
    503 private:
    504     std::string mSpecFileName;
    505     std::string mHeaderFileName;
    506     std::string mDetailedDocumentationUrl;
    507     std::string mBriefDescription;
    508     std::vector<std::string> mFullDescription;
    509     // Text to insert as-is in the generated header.
    510     std::vector<std::string> mVerbatimInclude;
    511 
    512     /* The constants, types, and functions specifications declared in this
    513      *  file, in the order they are found in the file.  This matters for
    514      * header generation, as some types and inline functions depend
    515      * on each other.  Pointers not owned.
    516      */
    517     std::list<ConstantSpecification*> mConstantSpecificationsList;
    518     std::list<TypeSpecification*> mTypeSpecificationsList;
    519     std::list<FunctionSpecification*> mFunctionSpecificationsList;
    520 
    521     /* The constants, types, and functions that are documented in this file.
    522      * In very rare cases, specifications for an API are split across multiple
    523      * files, e.g. currently for ClearObject().  The documentation for
    524      * that function must be found in the first spec file encountered, so the
    525      * order of the files on the command line matters.
    526      */
    527     std::map<std::string, Constant*> mDocumentedConstants;
    528     std::map<std::string, Type*> mDocumentedTypes;
    529     std::map<std::string, Function*> mDocumentedFunctions;
    530 
    531 public:
    532     explicit SpecFile(const std::string& specFileName);
    533 
    534     std::string getSpecFileName() const { return mSpecFileName; }
    535     std::string getHeaderFileName() const { return mHeaderFileName; }
    536     std::string getDetailedDocumentationUrl() const { return mDetailedDocumentationUrl; }
    537     const std::string getBriefDescription() const { return mBriefDescription; }
    538     const std::vector<std::string>& getFullDescription() const { return mFullDescription; }
    539     const std::vector<std::string>& getVerbatimInclude() const { return mVerbatimInclude; }
    540 
    541     const std::list<ConstantSpecification*>& getConstantSpecifications() const {
    542         return mConstantSpecificationsList;
    543     }
    544     const std::list<TypeSpecification*>& getTypeSpecifications() const {
    545         return mTypeSpecificationsList;
    546     }
    547     const std::list<FunctionSpecification*>& getFunctionSpecifications() const {
    548         return mFunctionSpecificationsList;
    549     }
    550     const std::map<std::string, Constant*>& getDocumentedConstants() const {
    551         return mDocumentedConstants;
    552     }
    553     const std::map<std::string, Type*>& getDocumentedTypes() const { return mDocumentedTypes; }
    554     const std::map<std::string, Function*>& getDocumentedFunctions() const {
    555         return mDocumentedFunctions;
    556     }
    557 
    558     bool hasSpecifications() const {
    559         return !mDocumentedConstants.empty() || !mDocumentedTypes.empty() ||
    560                !mDocumentedFunctions.empty();
    561     }
    562 
    563     bool readSpecFile(unsigned int maxApiLevel);
    564 
    565     /* These are called by the parser to keep track of the specifications defined in this file.
    566      * hasDocumentation is true if this specification containes the documentation.
    567      */
    568     void addConstantSpecification(ConstantSpecification* spec, bool hasDocumentation);
    569     void addTypeSpecification(TypeSpecification* spec, bool hasDocumentation);
    570     void addFunctionSpecification(FunctionSpecification* spec, bool hasDocumentation);
    571 };
    572 
    573 // The collection of all the spec files.
    574 class SystemSpecification {
    575 private:
    576     std::vector<SpecFile*> mSpecFiles;
    577 
    578     /* Entries in the table of contents.  We accumulate them in a map to sort them.
    579      * Pointers are owned.
    580      */
    581     std::map<std::string, Constant*> mConstants;
    582     std::map<std::string, Type*> mTypes;
    583     std::map<std::string, Function*> mFunctions;
    584 
    585 public:
    586     ~SystemSpecification();
    587 
    588     /* These are called the parser to create unique instances per name.  Set *created to true
    589      * if the named specification did not already exist.
    590      */
    591     Constant* findOrCreateConstant(const std::string& name, bool* created);
    592     Type* findOrCreateType(const std::string& name, bool* created);
    593     Function* findOrCreateFunction(const std::string& name, bool* created);
    594 
    595     /* Parse the spec file and create the object hierarchy, adding a pointer to mSpecFiles.
    596      * We won't include information passed the specified level.
    597      */
    598     bool readSpecFile(const std::string& fileName, unsigned int maxApiLevel);
    599     // Generate all the files.
    600     bool generateFiles(bool forVerification, unsigned int maxApiLevel) const;
    601 
    602     const std::vector<SpecFile*>& getSpecFiles() const { return mSpecFiles; }
    603     const std::map<std::string, Constant*>& getConstants() const { return mConstants; }
    604     const std::map<std::string, Type*>& getTypes() const { return mTypes; }
    605     const std::map<std::string, Function*>& getFunctions() const { return mFunctions; }
    606 
    607     // Returns "<a href='...'> for the named specification, or empty if not found.
    608     std::string getHtmlAnchor(const std::string& name) const;
    609 
    610     // Returns the maximum API level specified in any spec file.
    611     unsigned int getMaximumApiLevel();
    612 };
    613 
    614 // Singleton that represents the collection of all the specs we're processing.
    615 extern SystemSpecification systemSpecification;
    616 
    617 // Table of equivalences of numerical types.
    618 extern const NumericalType TYPES[];
    619 extern const int NUM_TYPES;
    620 
    621 /* Given a renderscript type (string) calculate the vector size and base type. If the type
    622  * is not a vector the vector size is 1 and baseType is just the type itself.
    623  */
    624 void getVectorSizeAndBaseType(const std::string& type, std::string& vectorSize,
    625                               std::string& baseType);
    626 
    627 #endif  // ANDROID_RS_API_GENERATOR_SPECIFICATION_H
    628