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 
isFloat16ParameterParameterDefinition123     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 
VersionInfoVersionInfo137     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. */
includesVersionVersionInfo144     bool includesVersion(unsigned 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 
getName()170     std::string getName() const { return mName; }
deprecated()171     bool deprecated() const { return mDeprecatedApiLevel > 0; }
getDeprecatedApiLevel()172     int getDeprecatedApiLevel() const { return mDeprecatedApiLevel; }
getDeprecatedMessage()173     std::string getDeprecatedMessage() const { return mDeprecatedMessage; }
hidden()174     bool hidden() const { return mHidden; }
getSummary()175     std::string getSummary() const { return mSummary; }
getDescription()176     const std::vector<std::string>& getDescription() const { return mDescription; }
getUrl()177     std::string getUrl() const { return mUrl; }
getFinalVersion()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:
Constant(const std::string & name)193     Constant(const std::string& name) : Definition(name) {}
194     ~Constant();
195 
getSpecifications()196     const std::vector<ConstantSpecification*> getSpecifications() const { return mSpecifications; }
197     // This method should only be called by the scanning code.
addSpecification(ConstantSpecification * spec)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:
Type(const std::string & name)209     Type(const std::string& name) : Definition(name) {}
210     ~Type();
211 
getSpecifications()212     const std::vector<TypeSpecification*> getSpecifications() const { return mSpecifications; }
213     // This method should only be called by the scanning code.
addSpecification(TypeSpecification * spec)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 
getCapitalizedName()235     std::string getCapitalizedName() const { return mCapitalizedName; }
getParameters()236     const std::vector<ParameterEntry*>& getParameters() const { return mParameters; }
getReturnDocumentation()237     std::string getReturnDocumentation() const { return mReturnDocumentation; }
getSpecifications()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);
addSpecification(FunctionSpecification * spec)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:
getVersionInfo()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:
ConstantSpecification(Constant * constant)271     ConstantSpecification(Constant* constant) : mConstant(constant) {}
272 
getConstant()273     Constant* getConstant() const { return mConstant; }
getValue()274     std::string getValue() const { return mValue; }
getType()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:
TypeSpecification(Type * type)311     TypeSpecification(Type* type) : mType(type) {}
312 
getType()313     Type* getType() const { return mType; }
getKind()314     TypeKind getKind() const { return mKind; }
getSimpleType()315     std::string getSimpleType() const { return mSimpleType; }
getStructName()316     std::string getStructName() const { return mStructName; }
getFields()317     const std::vector<std::string>& getFields() const { return mFields; }
getFieldComments()318     const std::vector<std::string>& getFieldComments() const { return mFieldComments; }
getAttribute()319     std::string getAttribute() const { return mAttribute; }
getEnumName()320     std::string getEnumName() const { return mEnumName; }
getValues()321     const std::vector<std::string>& getValues() const { return mValues; }
getValueComments()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:
FunctionSpecification(Function * function)406     FunctionSpecification(Function* function) : mFunction(function), mInternal(false),
407         mIntrinsic(false), mReturn(nullptr) {}
408     ~FunctionSpecification();
409 
getFunction()410     Function* getFunction() const { return mFunction; }
isInternal()411     bool isInternal() const { return mInternal; }
isIntrinsic()412     bool isIntrinsic() const { return mIntrinsic; }
getAttribute()413     std::string getAttribute() const { return mAttribute; }
getTest()414     std::string getTest() const { return mTest; }
getPrecisionLimit()415     std::string getPrecisionLimit() const { return mPrecisionLimit; }
416 
getPermutations()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;
getNumberOfParams()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 
hasInline()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      */
isOverloadable()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 
getName()487     std::string getName() const { return mName; }
getNameTrunk()488     std::string getNameTrunk() const { return mNameTrunk; }
getTest()489     std::string getTest() const { return mTest; }
getPrecisionLimit()490     std::string getPrecisionLimit() const { return mPrecisionLimit; }
491 
getInline()492     const std::vector<std::string>& getInline() const { return mInline; }
getReturn()493     const ParameterDefinition* getReturn() const { return mReturn; }
getInputCount()494     int getInputCount() const { return mInputCount; }
getOutputCount()495     int getOutputCount() const { return mOutputCount; }
hasFloatAnswers()496     bool hasFloatAnswers() const { return mHasFloatAnswers; }
497 
getParams()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 
getSpecFileName()534     std::string getSpecFileName() const { return mSpecFileName; }
getHeaderFileName()535     std::string getHeaderFileName() const { return mHeaderFileName; }
getDetailedDocumentationUrl()536     std::string getDetailedDocumentationUrl() const { return mDetailedDocumentationUrl; }
getBriefDescription()537     const std::string getBriefDescription() const { return mBriefDescription; }
getFullDescription()538     const std::vector<std::string>& getFullDescription() const { return mFullDescription; }
getVerbatimInclude()539     const std::vector<std::string>& getVerbatimInclude() const { return mVerbatimInclude; }
540 
getConstantSpecifications()541     const std::list<ConstantSpecification*>& getConstantSpecifications() const {
542         return mConstantSpecificationsList;
543     }
getTypeSpecifications()544     const std::list<TypeSpecification*>& getTypeSpecifications() const {
545         return mTypeSpecificationsList;
546     }
getFunctionSpecifications()547     const std::list<FunctionSpecification*>& getFunctionSpecifications() const {
548         return mFunctionSpecificationsList;
549     }
getDocumentedConstants()550     const std::map<std::string, Constant*>& getDocumentedConstants() const {
551         return mDocumentedConstants;
552     }
getDocumentedTypes()553     const std::map<std::string, Type*>& getDocumentedTypes() const { return mDocumentedTypes; }
getDocumentedFunctions()554     const std::map<std::string, Function*>& getDocumentedFunctions() const {
555         return mDocumentedFunctions;
556     }
557 
hasSpecifications()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(unsigned int maxApiLevel) const;
601 
getSpecFiles()602     const std::vector<SpecFile*>& getSpecFiles() const { return mSpecFiles; }
getConstants()603     const std::map<std::string, Constant*>& getConstants() const { return mConstants; }
getTypes()604     const std::map<std::string, Type*>& getTypes() const { return mTypes; }
getFunctions()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