"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TSDocConfigFile = void 0;
const tsdoc_1 = require("@microsoft/tsdoc");
const fs = __importStar(require("fs"));
const resolve = __importStar(require("resolve"));
const path = __importStar(require("path"));
const ajv_1 = __importDefault(require("ajv"));
const jju = __importStar(require("jju"));
const ajv = new ajv_1.default({ verbose: true });
function initializeSchemaValidator() {
    const jsonSchemaPath = resolve.sync('@microsoft/tsdoc/schemas/tsdoc.schema.json', { basedir: __dirname });
    const jsonSchemaContent = fs.readFileSync(jsonSchemaPath).toString();
    const jsonSchema = jju.parse(jsonSchemaContent, { mode: 'cjson' });
    return ajv.compile(jsonSchema);
}
// Warning: AJV has a fairly strange API.  Each time this function is called, the function  object's
// properties get overwritten with the results of the latest validation.  Thus we need to be careful
// to read the properties before a subsequent call may occur.
const tsdocSchemaValidator = initializeSchemaValidator();
/**
 * Represents an individual `tsdoc.json` file.
 *
 * @public
 */
class TSDocConfigFile {
    constructor() {
        this.log = new tsdoc_1.ParserMessageLog();
        this._extendsFiles = [];
        this._filePath = '';
        this._fileNotFound = false;
        this._hasErrors = false;
        this._fileMTime = 0;
        this._tsdocSchema = '';
        this._extendsPaths = [];
        this._noStandardTags = undefined;
        this._tagDefinitions = [];
        this._tagDefinitionNames = new Set();
        this._supportForTags = new Map();
    }
    /**
     * Other config files that this file extends from.
     */
    get extendsFiles() {
        return this._extendsFiles;
    }
    /**
     * The full path of the file that was attempted to load, or an empty string if the configuration was
     * loaded from a source that is not a file.
     */
    get filePath() {
        return this._filePath;
    }
    /**
     * If true, then the TSDocConfigFile object contains an empty state, because the `tsdoc.json` file
     * was not found by the loader.
     *
     * @remarks
     * A missing "tsdoc.json" file is not considered an error.  It simply means that the defaults will be used.
     */
    get fileNotFound() {
        return this._fileNotFound;
    }
    /**
     * If true, then at least one error was encountered while loading this file or one of its "extends" files.
     *
     * @remarks
     * You can use {@link TSDocConfigFile.getErrorSummary} to report these errors.
     *
     * The individual messages can be retrieved from the {@link TSDocConfigFile.log} property of each `TSDocConfigFile`
     * object (including the {@link TSDocConfigFile.extendsFiles} tree).
     */
    get hasErrors() {
        return this._hasErrors;
    }
    /**
     * The `$schema` field from the `tsdoc.json` file.
     */
    get tsdocSchema() {
        return this._tsdocSchema;
    }
    /**
     * The `extends` field from the `tsdoc.json` file.  For the parsed file contents,
     * use the `extendsFiles` property instead.
     */
    get extendsPaths() {
        return this._extendsPaths;
    }
    /**
     * By default, the config file loader will predefine all of the standardized TSDoc tags.  To disable this and
     * start with a completely empty configuration, set `noStandardTags` to true.
     *
     * @remarks
     * If a config file uses `"extends"` to include settings from base config files, then its setting will
     * override any settings from the base config files.  If `"noStandardTags"` is not specified, then this
     * property will be `undefined`.  The config files are applied in the order they are processed (a depth-first
     * traversal of the `"extends"` references), and files processed later can override earlier files.
     * If no config file specifies `noStandardTags` then the default value is `false`.
     */
    get noStandardTags() {
        return this._noStandardTags;
    }
    set noStandardTags(value) {
        this._noStandardTags = value;
    }
    get tagDefinitions() {
        return this._tagDefinitions;
    }
    get supportForTags() {
        return this._supportForTags;
    }
    get supportedHtmlElements() {
        return this._supportedHtmlElements && Array.from(this._supportedHtmlElements);
    }
    get reportUnsupportedHtmlElements() {
        return this._reportUnsupportedHtmlElements;
    }
    set reportUnsupportedHtmlElements(value) {
        this._reportUnsupportedHtmlElements = value;
    }
    /**
     * Removes all items from the `tagDefinitions` array.
     */
    clearTagDefinitions() {
        this._tagDefinitions.length = 0;
        this._tagDefinitionNames.clear();
    }
    /**
     * Adds a new item to the `tagDefinitions` array.
     */
    addTagDefinition(parameters) {
        // This validates the tag name
        const tagDefinition = new tsdoc_1.TSDocTagDefinition(parameters);
        if (this._tagDefinitionNames.has(tagDefinition.tagNameWithUpperCase)) {
            throw new Error(`A tag definition was already added with the tag name "${parameters.tagName}"`);
        }
        this._tagDefinitionNames.add(tagDefinition.tagName);
        this._tagDefinitions.push(tagDefinition);
    }
    // Similar to addTagDefinition() but reports errors using _reportError()
    _addTagDefinitionForLoad(parameters) {
        let tagDefinition;
        try {
            // This validates the tag name
            tagDefinition = new tsdoc_1.TSDocTagDefinition(parameters);
        }
        catch (error) {
            this._reportError({
                messageId: tsdoc_1.TSDocMessageId.ConfigFileInvalidTagName,
                messageText: error.message,
                textRange: tsdoc_1.TextRange.empty,
            });
            return;
        }
        if (this._tagDefinitionNames.has(tagDefinition.tagNameWithUpperCase)) {
            this._reportError({
                messageId: tsdoc_1.TSDocMessageId.ConfigFileDuplicateTagName,
                messageText: `The "tagDefinitions" field specifies more than one tag with the name "${parameters.tagName}"`,
                textRange: tsdoc_1.TextRange.empty,
            });
        }
        this._tagDefinitionNames.add(tagDefinition.tagNameWithUpperCase);
        this._tagDefinitions.push(tagDefinition);
    }
    /**
     * Adds a new item to the `supportedHtmlElements` array.
     */
    addSupportedHtmlElement(htmlElement) {
        if (!this._supportedHtmlElements) {
            this._supportedHtmlElements = new Set();
        }
        this._supportedHtmlElements.add(htmlElement);
    }
    /**
     * Removes the explicit list of allowed html elements.
     */
    clearSupportedHtmlElements() {
        this._supportedHtmlElements = undefined;
    }
    /**
     * Removes all entries from the "supportForTags" map.
     */
    clearSupportForTags() {
        this._supportForTags.clear();
    }
    /**
     * Sets an entry in the "supportForTags" map.
     */
    setSupportForTag(tagName, supported) {
        tsdoc_1.TSDocTagDefinition.validateTSDocTagName(tagName);
        this._supportForTags.set(tagName, supported);
    }
    /**
     * This can be used for cache eviction.  It returns true if the modification timestamp has changed for
     * any of the files that were read when loading this `TSDocConfigFile`, which indicates that the file should be
     * reloaded.  It does not consider cases where `TSDocConfigFile.fileNotFound` was `true`.
     *
     * @remarks
     * This can be used for cache eviction.  An example eviction strategy might be like this:
     *
     * - call `checkForModifiedFiles()` once per second, and reload the configuration if it returns true
     *
     * - otherwise, reload the configuration when it is more than 10 seconds old (to handle less common cases such
     *   as creation of a missing file, or creation of a file at an earlier location in the search path).
     */
    checkForModifiedFiles() {
        if (this._checkForModifiedFile()) {
            return true;
        }
        for (const extendsFile of this.extendsFiles) {
            if (extendsFile.checkForModifiedFiles()) {
                return true;
            }
        }
        return false;
    }
    /**
     * Checks the last modification time for `TSDocConfigFile.filePath` and returns `true` if it has changed
     * since the file was loaded.  If the file is missing, this returns `false`.  If the timestamp cannot be read,
     * then this returns `true`.
     */
    _checkForModifiedFile() {
        if (this._fileNotFound || !this._filePath) {
            return false;
        }
        try {
            const mtimeMs = fs.statSync(this._filePath).mtimeMs;
            return mtimeMs !== this._fileMTime;
        }
        catch (error) {
            return true;
        }
    }
    _reportError(parserMessageParameters) {
        this.log.addMessage(new tsdoc_1.ParserMessage(parserMessageParameters));
        this._hasErrors = true;
    }
    _loadJsonObject(configJson) {
        if (configJson.$schema !== TSDocConfigFile.CURRENT_SCHEMA_URL) {
            this._reportError({
                messageId: tsdoc_1.TSDocMessageId.ConfigFileUnsupportedSchema,
                messageText: `Unsupported JSON "$schema" value; expecting "${TSDocConfigFile.CURRENT_SCHEMA_URL}"`,
                textRange: tsdoc_1.TextRange.empty,
            });
            return;
        }
        const success = tsdocSchemaValidator(configJson);
        if (!success) {
            const description = ajv.errorsText(tsdocSchemaValidator.errors);
            this._reportError({
                messageId: tsdoc_1.TSDocMessageId.ConfigFileSchemaError,
                messageText: 'Error loading config file: ' + description,
                textRange: tsdoc_1.TextRange.empty,
            });
            return;
        }
        this._tsdocSchema = configJson.$schema;
        if (configJson.extends) {
            this._extendsPaths.push(...configJson.extends);
        }
        this.noStandardTags = configJson.noStandardTags;
        for (const jsonTagDefinition of configJson.tagDefinitions || []) {
            let syntaxKind;
            switch (jsonTagDefinition.syntaxKind) {
                case 'inline':
                    syntaxKind = tsdoc_1.TSDocTagSyntaxKind.InlineTag;
                    break;
                case 'block':
                    syntaxKind = tsdoc_1.TSDocTagSyntaxKind.BlockTag;
                    break;
                case 'modifier':
                    syntaxKind = tsdoc_1.TSDocTagSyntaxKind.ModifierTag;
                    break;
                default:
                    // The JSON schema should have caught this error
                    throw new Error('Unexpected tag kind');
            }
            this._addTagDefinitionForLoad({
                tagName: jsonTagDefinition.tagName,
                syntaxKind: syntaxKind,
                allowMultiple: jsonTagDefinition.allowMultiple,
            });
        }
        if (configJson.supportedHtmlElements) {
            this._supportedHtmlElements = new Set();
            for (const htmlElement of configJson.supportedHtmlElements) {
                this.addSupportedHtmlElement(htmlElement);
            }
        }
        this._reportUnsupportedHtmlElements = configJson.reportUnsupportedHtmlElements;
        if (configJson.supportForTags) {
            for (const tagName of Object.keys(configJson.supportForTags)) {
                const supported = configJson.supportForTags[tagName];
                this._supportForTags.set(tagName, supported);
            }
        }
    }
    _loadWithExtends(configFilePath, referencingConfigFile, alreadyVisitedPaths) {
        // In case an exception is thrown, start by assuming that the file was not found; we'll revise
        // this later upon success
        this._fileNotFound = true;
        if (!configFilePath) {
            this._reportError({
                messageId: tsdoc_1.TSDocMessageId.ConfigFileNotFound,
                messageText: 'File not found',
                textRange: tsdoc_1.TextRange.empty,
            });
            return;
        }
        this._filePath = path.resolve(configFilePath);
        if (!fs.existsSync(this._filePath)) {
            this._reportError({
                messageId: tsdoc_1.TSDocMessageId.ConfigFileNotFound,
                messageText: 'File not found',
                textRange: tsdoc_1.TextRange.empty,
            });
            return;
        }
        const configJsonContent = fs.readFileSync(this._filePath).toString();
        this._fileMTime = fs.statSync(this._filePath).mtimeMs;
        this._fileNotFound = false;
        const hashKey = fs.realpathSync(this._filePath);
        if (referencingConfigFile && alreadyVisitedPaths.has(hashKey)) {
            this._reportError({
                messageId: tsdoc_1.TSDocMessageId.ConfigFileCyclicExtends,
                messageText: `Circular reference encountered for "extends" field of "${referencingConfigFile.filePath}"`,
                textRange: tsdoc_1.TextRange.empty,
            });
            return;
        }
        alreadyVisitedPaths.add(hashKey);
        let configJson;
        try {
            configJson = jju.parse(configJsonContent, { mode: 'cjson' });
        }
        catch (e) {
            this._reportError({
                messageId: tsdoc_1.TSDocMessageId.ConfigInvalidJson,
                messageText: 'Error parsing JSON input: ' + e.message,
                textRange: tsdoc_1.TextRange.empty,
            });
            return;
        }
        this._loadJsonObject(configJson);
        const configFileFolder = path.dirname(this.filePath);
        for (const extendsField of this.extendsPaths) {
            let resolvedExtendsPath;
            try {
                resolvedExtendsPath = resolve.sync(extendsField, { basedir: configFileFolder });
            }
            catch (e) {
                this._reportError({
                    messageId: tsdoc_1.TSDocMessageId.ConfigFileUnresolvedExtends,
                    messageText: `Unable to resolve "extends" reference to "${extendsField}": ` + e.message,
                    textRange: tsdoc_1.TextRange.empty,
                });
                return;
            }
            const baseConfigFile = new TSDocConfigFile();
            baseConfigFile._loadWithExtends(resolvedExtendsPath, this, alreadyVisitedPaths);
            if (baseConfigFile.fileNotFound) {
                this._reportError({
                    messageId: tsdoc_1.TSDocMessageId.ConfigFileUnresolvedExtends,
                    messageText: `Unable to resolve "extends" reference to "${extendsField}"`,
                    textRange: tsdoc_1.TextRange.empty,
                });
            }
            this._extendsFiles.push(baseConfigFile);
            if (baseConfigFile.hasErrors) {
                this._hasErrors = true;
            }
        }
    }
    /**
     * For the given folder, look for the relevant tsdoc.json file (if any), and return its path.
     *
     * @param folderPath - the path to a folder where the search should start
     * @returns the (possibly relative) path to tsdoc.json, or an empty string if not found
     */
    static findConfigPathForFolder(folderPath) {
        if (folderPath) {
            let foundFolder = folderPath;
            for (;;) {
                const tsconfigJsonPath = path.join(foundFolder, 'tsconfig.json');
                if (fs.existsSync(tsconfigJsonPath)) {
                    // Stop when we reach a folder containing tsconfig.json
                    return path.join(foundFolder, TSDocConfigFile.FILENAME);
                }
                const packageJsonPath = path.join(foundFolder, 'package.json');
                if (fs.existsSync(packageJsonPath)) {
                    // Stop when we reach a folder containing package.json; this avoids crawling out of the current package
                    return path.join(foundFolder, TSDocConfigFile.FILENAME);
                }
                const previousFolder = foundFolder;
                foundFolder = path.dirname(foundFolder);
                if (!foundFolder || foundFolder === previousFolder) {
                    // Give up if we reach the filesystem root directory
                    break;
                }
            }
        }
        return '';
    }
    /**
     * Calls `TSDocConfigFile.findConfigPathForFolder()` to find the relevant tsdoc.json config file, if one exists.
     * Then calls `TSDocConfigFile.findConfigPathForFolder()` to return the loaded result.
     *
     * @remarks
     * This API does not report loading errors by throwing exceptions.  Instead, the caller is expected to check
     * for errors using {@link TSDocConfigFile.hasErrors}, {@link TSDocConfigFile.log},
     * or {@link TSDocConfigFile.getErrorSummary}.
     *
     * @param folderPath - the path to a folder where the search should start
     */
    static loadForFolder(folderPath) {
        const rootConfigPath = TSDocConfigFile.findConfigPathForFolder(folderPath);
        return TSDocConfigFile.loadFile(rootConfigPath);
    }
    /**
     * Loads the specified tsdoc.json and any base files that it refers to using the "extends" option.
     *
     * @remarks
     * This API does not report loading errors by throwing exceptions.  Instead, the caller is expected to check
     * for errors using {@link TSDocConfigFile.hasErrors}, {@link TSDocConfigFile.log},
     * or {@link TSDocConfigFile.getErrorSummary}.
     *
     * @param tsdocJsonFilePath - the path to the tsdoc.json config file
     */
    static loadFile(tsdocJsonFilePath) {
        const configFile = new TSDocConfigFile();
        const alreadyVisitedPaths = new Set();
        configFile._loadWithExtends(tsdocJsonFilePath, undefined, alreadyVisitedPaths);
        return configFile;
    }
    /**
     * Loads the object state from a JSON-serializable object as produced by {@link TSDocConfigFile.saveToObject}.
     *
     * @remarks
     * The serialized object has the same structure as `tsdoc.json`; however the `"extends"` field is not allowed.
     *
     * This API does not report loading errors by throwing exceptions.  Instead, the caller is expected to check
     * for errors using {@link TSDocConfigFile.hasErrors}, {@link TSDocConfigFile.log},
     * or {@link TSDocConfigFile.getErrorSummary}.
     */
    static loadFromObject(jsonObject) {
        const configFile = new TSDocConfigFile();
        configFile._loadJsonObject(jsonObject);
        if (configFile.extendsPaths.length > 0) {
            throw new Error('The "extends" field cannot be used with TSDocConfigFile.loadFromObject()');
        }
        return configFile;
    }
    /**
     * Initializes a TSDocConfigFile object using the state from the provided `TSDocConfiguration` object.
     *
     * @remarks
     * This API does not report loading errors by throwing exceptions.  Instead, the caller is expected to check
     * for errors using {@link TSDocConfigFile.hasErrors}, {@link TSDocConfigFile.log},
     * or {@link TSDocConfigFile.getErrorSummary}.
     */
    static loadFromParser(configuration) {
        const configFile = new TSDocConfigFile();
        // The standard tags will be mixed together with custom definitions,
        // so set noStandardTags=true to avoid defining them twice.
        configFile.noStandardTags = true;
        for (const tagDefinition of configuration.tagDefinitions) {
            configFile.addTagDefinition({
                syntaxKind: tagDefinition.syntaxKind,
                tagName: tagDefinition.tagName,
                allowMultiple: tagDefinition.allowMultiple,
            });
        }
        for (const tagDefinition of configuration.supportedTagDefinitions) {
            configFile.setSupportForTag(tagDefinition.tagName, true);
        }
        for (const htmlElement of configuration.supportedHtmlElements) {
            configFile.addSupportedHtmlElement(htmlElement);
        }
        configFile.reportUnsupportedHtmlElements = configuration.validation.reportUnsupportedHtmlElements;
        return configFile;
    }
    /**
     * Writes the config file content to a JSON file with the specified file path.
     */
    saveFile(jsonFilePath) {
        const jsonObject = this.saveToObject();
        const jsonContent = JSON.stringify(jsonObject, undefined, 2);
        fs.writeFileSync(jsonFilePath, jsonContent);
    }
    /**
     * Writes the object state into a JSON-serializable object.
     */
    saveToObject() {
        const configJson = {
            $schema: TSDocConfigFile.CURRENT_SCHEMA_URL,
        };
        if (this.noStandardTags !== undefined) {
            configJson.noStandardTags = this.noStandardTags;
        }
        if (this.tagDefinitions.length > 0) {
            configJson.tagDefinitions = [];
            for (const tagDefinition of this.tagDefinitions) {
                configJson.tagDefinitions.push(TSDocConfigFile._serializeTagDefinition(tagDefinition));
            }
        }
        if (this.supportForTags.size > 0) {
            configJson.supportForTags = {};
            this.supportForTags.forEach((supported, tagName) => {
                configJson.supportForTags[tagName] = supported;
            });
        }
        if (this.supportedHtmlElements) {
            configJson.supportedHtmlElements = [...this.supportedHtmlElements];
        }
        if (this._reportUnsupportedHtmlElements !== undefined) {
            configJson.reportUnsupportedHtmlElements = this._reportUnsupportedHtmlElements;
        }
        return configJson;
    }
    static _serializeTagDefinition(tagDefinition) {
        let syntaxKind;
        switch (tagDefinition.syntaxKind) {
            case tsdoc_1.TSDocTagSyntaxKind.InlineTag:
                syntaxKind = 'inline';
                break;
            case tsdoc_1.TSDocTagSyntaxKind.BlockTag:
                syntaxKind = 'block';
                break;
            case tsdoc_1.TSDocTagSyntaxKind.ModifierTag:
                syntaxKind = 'modifier';
                break;
            default:
                throw new Error('Unimplemented TSDocTagSyntaxKind');
        }
        const tagConfigJson = {
            tagName: tagDefinition.tagName,
            syntaxKind,
        };
        if (tagDefinition.allowMultiple) {
            tagConfigJson.allowMultiple = true;
        }
        return tagConfigJson;
    }
    /**
     * Returns a report of any errors that occurred while attempting to load this file or any files
     * referenced via the "extends" field.
     *
     * @remarks
     * Use {@link TSDocConfigFile.hasErrors} to determine whether any errors occurred.
     */
    getErrorSummary() {
        if (!this._hasErrors) {
            return 'No errors.';
        }
        let result = '';
        if (this.log.messages.length > 0) {
            const errorNoun = this.log.messages.length > 1 ? 'Errors' : 'Error';
            if (this.filePath) {
                result += `${errorNoun} encountered for ${this.filePath}:\n`;
            }
            else {
                result += `${errorNoun} encountered when loading TSDoc configuration:\n`;
            }
            for (const message of this.log.messages) {
                result += `  ${message.text}\n`;
            }
        }
        for (const extendsFile of this.extendsFiles) {
            if (extendsFile.hasErrors) {
                if (result !== '') {
                    result += '\n';
                }
                result += extendsFile.getErrorSummary();
            }
        }
        return result;
    }
    /**
     * Applies the settings from this config file to a TSDoc parser configuration.
     * Any `extendsFile` settings will also applied.
     *
     * @remarks
     * Additional validation is performed during this operation.  The caller is expected to check for errors
     * using {@link TSDocConfigFile.hasErrors}, {@link TSDocConfigFile.log}, or {@link TSDocConfigFile.getErrorSummary}.
     */
    configureParser(configuration) {
        if (this._getNoStandardTagsWithExtends()) {
            // Do not define standard tags
            configuration.clear(true);
        }
        else {
            // Define standard tags (the default behavior)
            configuration.clear(false);
        }
        this.updateParser(configuration);
    }
    /**
     * This is the same as {@link configureParser}, but it preserves any previous state.
     *
     * @remarks
     * Additional validation is performed during this operation.  The caller is expected to check for errors
     * using {@link TSDocConfigFile.hasErrors}, {@link TSDocConfigFile.log}, or {@link TSDocConfigFile.getErrorSummary}.
     */
    updateParser(configuration) {
        // First apply the base config files
        for (const extendsFile of this.extendsFiles) {
            extendsFile.updateParser(configuration);
        }
        // Then apply this one
        for (const tagDefinition of this.tagDefinitions) {
            configuration.addTagDefinition(tagDefinition);
        }
        this.supportForTags.forEach((supported, tagName) => {
            const tagDefinition = configuration.tryGetTagDefinition(tagName);
            if (tagDefinition) {
                // Note that setSupportForTag() automatically enables configuration.validation.reportUnsupportedTags
                configuration.setSupportForTag(tagDefinition, supported);
            }
            else {
                // Note that this validation may depend partially on the preexisting state of the TSDocConfiguration
                // object, so it cannot be performed during the TSConfigFile.loadFile() stage.
                this._reportError({
                    messageId: tsdoc_1.TSDocMessageId.ConfigFileUndefinedTag,
                    messageText: `The "supportForTags" field refers to an undefined tag ${JSON.stringify(tagName)}.`,
                    textRange: tsdoc_1.TextRange.empty,
                });
            }
        });
        if (this.supportedHtmlElements) {
            configuration.setSupportedHtmlElements([...this.supportedHtmlElements]);
        }
        if (this._reportUnsupportedHtmlElements === false) {
            configuration.validation.reportUnsupportedHtmlElements = false;
        }
        else if (this._reportUnsupportedHtmlElements === true) {
            configuration.validation.reportUnsupportedHtmlElements = true;
        }
    }
    _getNoStandardTagsWithExtends() {
        if (this.noStandardTags !== undefined) {
            return this.noStandardTags;
        }
        // This config file does not specify "noStandardTags", so consider any base files referenced using "extends"
        let result = undefined;
        for (const extendsFile of this.extendsFiles) {
            const extendedValue = extendsFile._getNoStandardTagsWithExtends();
            if (extendedValue !== undefined) {
                result = extendedValue;
            }
        }
        if (result === undefined) {
            // If no config file specifies noStandardTags, then it defaults to false
            result = false;
        }
        return result;
    }
}
exports.TSDocConfigFile = TSDocConfigFile;
TSDocConfigFile.FILENAME = 'tsdoc.json';
TSDocConfigFile.CURRENT_SCHEMA_URL = 'https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json';
//# sourceMappingURL=TSDocConfigFile.js.map