CoolFace
Datasetpublic

basant307/AI_Governance_Project

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
0likes48downloads
namespace.js559 linesDownload Raw Back to src
1"use strict";2module.exports = Namespace;3 4// extends ReflectionObject5var ReflectionObject = require("./object");6((Namespace.prototype = Object.create(ReflectionObject.prototype)).constructor = Namespace).className = "Namespace";7 8var Field    = require("./field"),9    util     = require("./util"),10    OneOf    = require("./oneof");11 12var Type,    // cyclic13    Service,14    Enum;15 16/**17 * Constructs a new namespace instance.18 * @name Namespace19 * @classdesc Reflected namespace.20 * @extends NamespaceBase21 * @constructor22 * @param {string} name Namespace name23 * @param {Object.<string,*>} [options] Declared options24 */25 26/**27 * Constructs a namespace from JSON.28 * @memberof Namespace29 * @function30 * @param {string} name Namespace name31 * @param {Object.<string,*>} json JSON object32 * @param {number} [depth] Current nesting depth, defaults to `0`33 * @returns {Namespace} Created namespace34 * @throws {TypeError} If arguments are invalid35 */36Namespace.fromJSON = function fromJSON(name, json, depth) {37    depth = util.checkDepth(depth);38    return new Namespace(name, json.options).addJSON(json.nested, depth);39};40 41/**42 * Converts an array of reflection objects to JSON.43 * @memberof Namespace44 * @param {ReflectionObject[]} array Object array45 * @param {IToJSONOptions} [toJSONOptions] JSON conversion options46 * @returns {Object.<string,*>|undefined} JSON object or `undefined` when array is empty47 */48function arrayToJSON(array, toJSONOptions) {49    if (!(array && array.length))50        return undefined;51    var obj = {};52    for (var i = 0; i < array.length; ++i)53        obj[array[i].name] = array[i].toJSON(toJSONOptions);54    return obj;55}56 57Namespace.arrayToJSON = arrayToJSON;58 59/**60 * Tests if the specified id is reserved.61 * @param {Array.<number[]|string>|undefined} reserved Array of reserved ranges and names62 * @param {number} id Id to test63 * @returns {boolean} `true` if reserved, otherwise `false`64 */65Namespace.isReservedId = function isReservedId(reserved, id) {66    if (reserved)67        for (var i = 0; i < reserved.length; ++i)68            if (typeof reserved[i] !== "string" && reserved[i][0] <= id && reserved[i][1] > id)69                return true;70    return false;71};72 73/**74 * Tests if the specified name is reserved.75 * @param {Array.<number[]|string>|undefined} reserved Array of reserved ranges and names76 * @param {string} name Name to test77 * @returns {boolean} `true` if reserved, otherwise `false`78 */79Namespace.isReservedName = function isReservedName(reserved, name) {80    if (reserved)81        for (var i = 0; i < reserved.length; ++i)82            if (reserved[i] === name)83                return true;84    return false;85};86 87/**88 * Not an actual constructor. Use {@link Namespace} instead.89 * @classdesc Base class of all reflection objects containing nested objects. This is not an actual class but here for the sake of having consistent type definitions.90 * @exports NamespaceBase91 * @extends ReflectionObject92 * @abstract93 * @constructor94 * @param {string} name Namespace name95 * @param {Object.<string,*>} [options] Declared options96 * @see {@link Namespace}97 */98function Namespace(name, options) {99    ReflectionObject.call(this, name, options);100 101    /**102     * Nested objects by name.103     * @type {Object.<string,ReflectionObject>|undefined}104     */105    this.nested = undefined; // toJSON106 107    /**108     * Cached nested objects as an array.109     * @type {ReflectionObject[]|null}110     * @private111     */112    this._nestedArray = null;113 114    /**115     * Cache lookup calls for any objects contains anywhere under this namespace.116     * This drastically speeds up resolve for large cross-linked protos where the same117     * types are looked up repeatedly.118     * @type {Object.<string,ReflectionObject|null>}119     * @private120     */121    this._lookupCache = Object.create(null);122 123    /**124     * Whether or not objects contained in this namespace need feature resolution.125     * @type {boolean}126     * @protected127     */128    this._needsRecursiveFeatureResolution = true;129 130    /**131     * Whether or not objects contained in this namespace need a resolve.132     * @type {boolean}133     * @protected134     */135    this._needsRecursiveResolve = true;136}137 138function clearCache(namespace) {139    namespace._nestedArray = null;140    namespace._lookupCache = Object.create(null);141 142    // Also clear parent caches, since they include nested lookups.143    var parent = namespace;144    while(parent = parent.parent) {145        parent._lookupCache = Object.create(null);146    }147    return namespace;148}149 150/**151 * Nested objects of this namespace as an array for iteration.152 * @name NamespaceBase#nestedArray153 * @type {ReflectionObject[]}154 * @readonly155 */156Object.defineProperty(Namespace.prototype, "nestedArray", {157    get: function() {158        return this._nestedArray || (this._nestedArray = util.toArray(this.nested));159    }160});161 162/**163 * Namespace descriptor.164 * @interface INamespace165 * @property {Object.<string,*>} [options] Namespace options166 * @property {Object.<string,AnyNestedObject>} [nested] Nested object descriptors167 */168 169/**170 * Any extension field descriptor.171 * @typedef AnyExtensionField172 * @type {IExtensionField|IExtensionMapField}173 */174 175/**176 * Any nested object descriptor.177 * @typedef AnyNestedObject178 * @type {IEnum|IType|IService|AnyExtensionField|INamespace|IOneOf}179 */180 181/**182 * Converts this namespace to a namespace descriptor.183 * @param {IToJSONOptions} [toJSONOptions] JSON conversion options184 * @returns {INamespace} Namespace descriptor185 */186Namespace.prototype.toJSON = function toJSON(toJSONOptions) {187    return util.toObject([188        "options" , this.options,189        "nested"  , arrayToJSON(this.nestedArray, toJSONOptions)190    ]);191};192 193/**194 * Adds nested objects to this namespace from nested object descriptors.195 * @param {Object.<string,AnyNestedObject>} nestedJson Any nested object descriptors196 * @param {number} [depth] Current nesting depth, defaults to `0`197 * @returns {Namespace} `this`198 */199Namespace.prototype.addJSON = function addJSON(nestedJson, depth) {200    depth = util.checkDepth(depth);201    var ns = this;202    /* istanbul ignore else */203    if (nestedJson) {204        for (var names = Object.keys(nestedJson), i = 0, nested; i < names.length; ++i) {205            nested = nestedJson[names[i]];206            ns.add( // most to least likely207                ( nested.fields !== undefined208                ? Type.fromJSON209                : nested.values !== undefined210                ? Enum.fromJSON211                : nested.methods !== undefined212                ? Service.fromJSON213                : nested.id !== undefined214                ? Field.fromJSON215                : Namespace.fromJSON )(names[i], nested, depth + 1)216            );217        }218    }219    return this;220};221 222/**223 * Gets the nested object of the specified name.224 * @param {string} name Nested object name225 * @returns {ReflectionObject|null} The reflection object or `null` if it doesn't exist226 */227Namespace.prototype.get = function get(name) {228    return this.nested && Object.prototype.hasOwnProperty.call(this.nested, name)229        ? this.nested[name]230        : null;231};232 233/**234 * Gets the values of the nested {@link Enum|enum} of the specified name.235 * This methods differs from {@link Namespace#get|get} in that it returns an enum's values directly and throws instead of returning `null`.236 * @param {string} name Nested enum name237 * @returns {Object.<string,number>} Enum values238 * @throws {Error} If there is no such enum239 */240Namespace.prototype.getEnum = function getEnum(name) {241    if (this.nested && Object.prototype.hasOwnProperty.call(this.nested, name) && this.nested[name] instanceof Enum)242        return this.nested[name].values;243    throw Error("no such enum: " + name);244};245 246/**247 * Adds a nested object to this namespace.248 * @param {ReflectionObject} object Nested object to add249 * @returns {Namespace} `this`250 * @throws {TypeError} If arguments are invalid251 * @throws {Error} If there is already a nested object with this name252 */253Namespace.prototype.add = function add(object) {254 255    if (!(object instanceof Field && object.extend !== undefined || object instanceof Type  || object instanceof OneOf || object instanceof Enum || object instanceof Service || object instanceof Namespace))256        throw TypeError("object must be a valid nested object");257 258    if (object.name === "__proto__")259        return this;260 261    if (!this.nested)262        this.nested = {};263    else {264        var prev = this.get(object.name);265        if (prev) {266            if (prev instanceof Namespace && object instanceof Namespace && !(prev instanceof Type || prev instanceof Service)) {267                // replace plain namespace but keep existing nested elements and options268                var nested = prev.nestedArray;269                for (var i = 0; i < nested.length; ++i)270                    object.add(nested[i]);271                this.remove(prev);272                if (!this.nested)273                    this.nested = {};274                object.setOptions(prev.options, true);275 276            } else277                throw Error("duplicate name '" + object.name + "' in " + this);278        }279    }280    this.nested[object.name] = object;281 282    if (!(this instanceof Type || this instanceof Service || this instanceof Enum || this instanceof Field)) {283        // This is a package or a root namespace.284        if (!object._edition) {285            // Make sure that some edition is set if it hasn't already been specified.286            object._edition = object._defaultEdition;287        }288    }289 290    this._needsRecursiveFeatureResolution = true;291    this._needsRecursiveResolve = true;292 293    // Also clear parent caches, since they need to recurse down.294    var parent = this;295    while(parent = parent.parent) {296        parent._needsRecursiveFeatureResolution = true;297        parent._needsRecursiveResolve = true;298    }299 300    object.onAdd(this);301    return clearCache(this);302};303 304/**305 * Removes a nested object from this namespace.306 * @param {ReflectionObject} object Nested object to remove307 * @returns {Namespace} `this`308 * @throws {TypeError} If arguments are invalid309 * @throws {Error} If `object` is not a member of this namespace310 */311Namespace.prototype.remove = function remove(object) {312 313    if (!(object instanceof ReflectionObject))314        throw TypeError("object must be a ReflectionObject");315    if (object.parent !== this)316        throw Error(object + " is not a member of " + this);317 318    delete this.nested[object.name];319    if (!Object.keys(this.nested).length)320        this.nested = undefined;321 322    object.onRemove(this);323    return clearCache(this);324};325 326/**327 * Defines additial namespaces within this one if not yet existing.328 * @param {string|string[]} path Path to create329 * @param {*} [json] Nested types to create from JSON330 * @returns {Namespace} Pointer to the last namespace created or `this` if path is empty331 */332Namespace.prototype.define = function define(path, json) {333 334    if (util.isString(path))335        path = path.split(".");336    else if (!Array.isArray(path))337        throw TypeError("illegal path");338    if (path && path.length && path[0] === "")339        throw Error("path must be relative");340    if (path.length > util.recursionLimit)341        throw Error("max depth exceeded");342 343    var ptr = this;344    while (path.length > 0) {345        var part = path.shift();346        if (ptr.nested && ptr.nested[part]) {347            ptr = ptr.nested[part];348            if (!(ptr instanceof Namespace))349                throw Error("path conflicts with non-namespace objects");350        } else351            ptr.add(ptr = new Namespace(part));352    }353    if (json)354        ptr.addJSON(json);355    return ptr;356};357 358/**359 * Resolves this namespace's and all its nested objects' type references. Useful to validate a reflection tree, but comes at a cost.360 * @returns {Namespace} `this`361 */362Namespace.prototype.resolveAll = function resolveAll() {363    if (!this._needsRecursiveResolve) return this;364 365    this._resolveFeaturesRecursive(this._edition);366 367    var nested = this.nestedArray, i = 0;368    this.resolve();369    while (i < nested.length)370        if (nested[i] instanceof Namespace)371            nested[i++].resolveAll();372        else373            nested[i++].resolve();374    this._needsRecursiveResolve = false;375    return this;376};377 378/**379 * @override380 */381Namespace.prototype._resolveFeaturesRecursive = function _resolveFeaturesRecursive(edition) {382    if (!this._needsRecursiveFeatureResolution) return this;383    this._needsRecursiveFeatureResolution = false;384 385    edition = this._edition || edition;386 387    ReflectionObject.prototype._resolveFeaturesRecursive.call(this, edition);388    this.nestedArray.forEach(nested => {389        nested._resolveFeaturesRecursive(edition);390    });391    return this;392};393 394/**395 * Recursively looks up the reflection object matching the specified path in the scope of this namespace.396 * @param {string|string[]} path Path to look up397 * @param {*|Array.<*>} filterTypes Filter types, any combination of the constructors of `protobuf.Type`, `protobuf.Enum`, `protobuf.Service` etc.398 * @param {boolean} [parentAlreadyChecked=false] If known, whether the parent has already been checked399 * @returns {ReflectionObject|null} Looked up object or `null` if none could be found400 */401Namespace.prototype.lookup = function lookup(path, filterTypes, parentAlreadyChecked) {402    /* istanbul ignore next */403    if (typeof filterTypes === "boolean") {404        parentAlreadyChecked = filterTypes;405        filterTypes = undefined;406    } else if (filterTypes && !Array.isArray(filterTypes))407        filterTypes = [ filterTypes ];408 409    if (util.isString(path) && path.length) {410        if (path === ".")411            return this.root;412        path = path.split(".");413    } else if (!path.length)414        return this;415 416    var flatPath = path.join(".");417 418    // Start at root if path is absolute419    if (path[0] === "")420        return this.root.lookup(path.slice(1), filterTypes);421 422    // Early bailout for objects with matching absolute paths423    var found = this.root._fullyQualifiedObjects && this.root._fullyQualifiedObjects["." + flatPath];424    if (found && (!filterTypes || filterTypes.indexOf(found.constructor) > -1)) {425        return found;426    }427 428    // Do a regular lookup at this namespace and below429    found = this._lookupImpl(path, flatPath);430    if (found && (!filterTypes || filterTypes.indexOf(found.constructor) > -1)) {431        return found;432    }433 434    if (parentAlreadyChecked)435        return null;436 437    // If there hasn't been a match, walk up the tree and look more broadly438    var current = this;439    while (current.parent) {440        found = current.parent._lookupImpl(path, flatPath);441        if (found && (!filterTypes || filterTypes.indexOf(found.constructor) > -1)) {442            return found;443        }444        current = current.parent;445    }446    return null;447};448 449/**450 * Internal helper for lookup that handles searching just at this namespace and below along with caching.451 * @param {string[]} path Path to look up452 * @param {string} flatPath Flattened version of the path to use as a cache key453 * @returns {ReflectionObject|null} Looked up object or `null` if none could be found454 * @private455 */456Namespace.prototype._lookupImpl = function lookup(path, flatPath) {457    if(Object.prototype.hasOwnProperty.call(this._lookupCache, flatPath)) {458        return this._lookupCache[flatPath];459    }460 461    // Test if the first part matches any nested object, and if so, traverse if path contains more462    var found = this.get(path[0]);463    var exact = null;464    if (found) {465        if (path.length === 1) {466            exact = found;467        } else if (found instanceof Namespace) {468            path = path.slice(1);469            exact = found._lookupImpl(path, path.join("."));470        }471 472    // Otherwise try each nested namespace473    } else {474        for (var i = 0; i < this.nestedArray.length; ++i)475            if (this._nestedArray[i] instanceof Namespace && (found = this._nestedArray[i]._lookupImpl(path, flatPath))) {476                exact = found;477                break;478            }479    }480 481    // Set this even when null, so that when we walk up the tree we can quickly bail on repeated checks back down.482    this._lookupCache[flatPath] = exact;483    return exact;484};485 486/**487 * Looks up the reflection object at the specified path, relative to this namespace.488 * @name NamespaceBase#lookup489 * @function490 * @param {string|string[]} path Path to look up491 * @param {boolean} [parentAlreadyChecked=false] Whether the parent has already been checked492 * @returns {ReflectionObject|null} Looked up object or `null` if none could be found493 * @variation 2494 */495// lookup(path: string, [parentAlreadyChecked: boolean])496 497/**498 * Looks up the {@link Type|type} at the specified path, relative to this namespace.499 * Besides its signature, this methods differs from {@link Namespace#lookup|lookup} in that it throws instead of returning `null`.500 * @param {string|string[]} path Path to look up501 * @returns {Type} Looked up type502 * @throws {Error} If `path` does not point to a type503 */504Namespace.prototype.lookupType = function lookupType(path) {505    var found = this.lookup(path, [ Type ]);506    if (!found)507        throw Error("no such type: " + path);508    return found;509};510 511/**512 * Looks up the values of the {@link Enum|enum} at the specified path, relative to this namespace.513 * Besides its signature, this methods differs from {@link Namespace#lookup|lookup} in that it throws instead of returning `null`.514 * @param {string|string[]} path Path to look up515 * @returns {Enum} Looked up enum516 * @throws {Error} If `path` does not point to an enum517 */518Namespace.prototype.lookupEnum = function lookupEnum(path) {519    var found = this.lookup(path, [ Enum ]);520    if (!found)521        throw Error("no such Enum '" + path + "' in " + this);522    return found;523};524 525/**526 * Looks up the {@link Type|type} or {@link Enum|enum} at the specified path, relative to this namespace.527 * Besides its signature, this methods differs from {@link Namespace#lookup|lookup} in that it throws instead of returning `null`.528 * @param {string|string[]} path Path to look up529 * @returns {Type} Looked up type or enum530 * @throws {Error} If `path` does not point to a type or enum531 */532Namespace.prototype.lookupTypeOrEnum = function lookupTypeOrEnum(path) {533    var found = this.lookup(path, [ Type, Enum ]);534    if (!found)535        throw Error("no such Type or Enum '" + path + "' in " + this);536    return found;537};538 539/**540 * Looks up the {@link Service|service} at the specified path, relative to this namespace.541 * Besides its signature, this methods differs from {@link Namespace#lookup|lookup} in that it throws instead of returning `null`.542 * @param {string|string[]} path Path to look up543 * @returns {Service} Looked up service544 * @throws {Error} If `path` does not point to a service545 */546Namespace.prototype.lookupService = function lookupService(path) {547    var found = this.lookup(path, [ Service ]);548    if (!found)549        throw Error("no such Service '" + path + "' in " + this);550    return found;551};552 553// Sets up cyclic dependencies (called in index-light)554Namespace._configure = function(Type_, Service_, Enum_) {555    Type    = Type_;556    Service = Service_;557    Enum    = Enum_;558};559 
basant307/AI_Governance_Project · CoolFace