CoolFace
Apppublic

HarshvardhanCn01/Voice-Assistant

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
namespace.js434 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 * @returns {Namespace} Created namespace33 * @throws {TypeError} If arguments are invalid34 */35Namespace.fromJSON = function fromJSON(name, json) {36    return new Namespace(name, json.options).addJSON(json.nested);37};38 39/**40 * Converts an array of reflection objects to JSON.41 * @memberof Namespace42 * @param {ReflectionObject[]} array Object array43 * @param {IToJSONOptions} [toJSONOptions] JSON conversion options44 * @returns {Object.<string,*>|undefined} JSON object or `undefined` when array is empty45 */46function arrayToJSON(array, toJSONOptions) {47    if (!(array && array.length))48        return undefined;49    var obj = {};50    for (var i = 0; i < array.length; ++i)51        obj[array[i].name] = array[i].toJSON(toJSONOptions);52    return obj;53}54 55Namespace.arrayToJSON = arrayToJSON;56 57/**58 * Tests if the specified id is reserved.59 * @param {Array.<number[]|string>|undefined} reserved Array of reserved ranges and names60 * @param {number} id Id to test61 * @returns {boolean} `true` if reserved, otherwise `false`62 */63Namespace.isReservedId = function isReservedId(reserved, id) {64    if (reserved)65        for (var i = 0; i < reserved.length; ++i)66            if (typeof reserved[i] !== "string" && reserved[i][0] <= id && reserved[i][1] > id)67                return true;68    return false;69};70 71/**72 * Tests if the specified name is reserved.73 * @param {Array.<number[]|string>|undefined} reserved Array of reserved ranges and names74 * @param {string} name Name to test75 * @returns {boolean} `true` if reserved, otherwise `false`76 */77Namespace.isReservedName = function isReservedName(reserved, name) {78    if (reserved)79        for (var i = 0; i < reserved.length; ++i)80            if (reserved[i] === name)81                return true;82    return false;83};84 85/**86 * Not an actual constructor. Use {@link Namespace} instead.87 * @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.88 * @exports NamespaceBase89 * @extends ReflectionObject90 * @abstract91 * @constructor92 * @param {string} name Namespace name93 * @param {Object.<string,*>} [options] Declared options94 * @see {@link Namespace}95 */96function Namespace(name, options) {97    ReflectionObject.call(this, name, options);98 99    /**100     * Nested objects by name.101     * @type {Object.<string,ReflectionObject>|undefined}102     */103    this.nested = undefined; // toJSON104 105    /**106     * Cached nested objects as an array.107     * @type {ReflectionObject[]|null}108     * @private109     */110    this._nestedArray = null;111}112 113function clearCache(namespace) {114    namespace._nestedArray = null;115    return namespace;116}117 118/**119 * Nested objects of this namespace as an array for iteration.120 * @name NamespaceBase#nestedArray121 * @type {ReflectionObject[]}122 * @readonly123 */124Object.defineProperty(Namespace.prototype, "nestedArray", {125    get: function() {126        return this._nestedArray || (this._nestedArray = util.toArray(this.nested));127    }128});129 130/**131 * Namespace descriptor.132 * @interface INamespace133 * @property {Object.<string,*>} [options] Namespace options134 * @property {Object.<string,AnyNestedObject>} [nested] Nested object descriptors135 */136 137/**138 * Any extension field descriptor.139 * @typedef AnyExtensionField140 * @type {IExtensionField|IExtensionMapField}141 */142 143/**144 * Any nested object descriptor.145 * @typedef AnyNestedObject146 * @type {IEnum|IType|IService|AnyExtensionField|INamespace|IOneOf}147 */148 149/**150 * Converts this namespace to a namespace descriptor.151 * @param {IToJSONOptions} [toJSONOptions] JSON conversion options152 * @returns {INamespace} Namespace descriptor153 */154Namespace.prototype.toJSON = function toJSON(toJSONOptions) {155    return util.toObject([156        "options" , this.options,157        "nested"  , arrayToJSON(this.nestedArray, toJSONOptions)158    ]);159};160 161/**162 * Adds nested objects to this namespace from nested object descriptors.163 * @param {Object.<string,AnyNestedObject>} nestedJson Any nested object descriptors164 * @returns {Namespace} `this`165 */166Namespace.prototype.addJSON = function addJSON(nestedJson) {167    var ns = this;168    /* istanbul ignore else */169    if (nestedJson) {170        for (var names = Object.keys(nestedJson), i = 0, nested; i < names.length; ++i) {171            nested = nestedJson[names[i]];172            ns.add( // most to least likely173                ( nested.fields !== undefined174                ? Type.fromJSON175                : nested.values !== undefined176                ? Enum.fromJSON177                : nested.methods !== undefined178                ? Service.fromJSON179                : nested.id !== undefined180                ? Field.fromJSON181                : Namespace.fromJSON )(names[i], nested)182            );183        }184    }185    return this;186};187 188/**189 * Gets the nested object of the specified name.190 * @param {string} name Nested object name191 * @returns {ReflectionObject|null} The reflection object or `null` if it doesn't exist192 */193Namespace.prototype.get = function get(name) {194    return this.nested && this.nested[name]195        || null;196};197 198/**199 * Gets the values of the nested {@link Enum|enum} of the specified name.200 * This methods differs from {@link Namespace#get|get} in that it returns an enum's values directly and throws instead of returning `null`.201 * @param {string} name Nested enum name202 * @returns {Object.<string,number>} Enum values203 * @throws {Error} If there is no such enum204 */205Namespace.prototype.getEnum = function getEnum(name) {206    if (this.nested && this.nested[name] instanceof Enum)207        return this.nested[name].values;208    throw Error("no such enum: " + name);209};210 211/**212 * Adds a nested object to this namespace.213 * @param {ReflectionObject} object Nested object to add214 * @returns {Namespace} `this`215 * @throws {TypeError} If arguments are invalid216 * @throws {Error} If there is already a nested object with this name217 */218Namespace.prototype.add = function add(object) {219 220    if (!(object instanceof Field && object.extend !== undefined || object instanceof Type  || object instanceof OneOf || object instanceof Enum || object instanceof Service || object instanceof Namespace))221        throw TypeError("object must be a valid nested object");222 223    if (!this.nested)224        this.nested = {};225    else {226        var prev = this.get(object.name);227        if (prev) {228            if (prev instanceof Namespace && object instanceof Namespace && !(prev instanceof Type || prev instanceof Service)) {229                // replace plain namespace but keep existing nested elements and options230                var nested = prev.nestedArray;231                for (var i = 0; i < nested.length; ++i)232                    object.add(nested[i]);233                this.remove(prev);234                if (!this.nested)235                    this.nested = {};236                object.setOptions(prev.options, true);237 238            } else239                throw Error("duplicate name '" + object.name + "' in " + this);240        }241    }242    this.nested[object.name] = object;243    object.onAdd(this);244    return clearCache(this);245};246 247/**248 * Removes a nested object from this namespace.249 * @param {ReflectionObject} object Nested object to remove250 * @returns {Namespace} `this`251 * @throws {TypeError} If arguments are invalid252 * @throws {Error} If `object` is not a member of this namespace253 */254Namespace.prototype.remove = function remove(object) {255 256    if (!(object instanceof ReflectionObject))257        throw TypeError("object must be a ReflectionObject");258    if (object.parent !== this)259        throw Error(object + " is not a member of " + this);260 261    delete this.nested[object.name];262    if (!Object.keys(this.nested).length)263        this.nested = undefined;264 265    object.onRemove(this);266    return clearCache(this);267};268 269/**270 * Defines additial namespaces within this one if not yet existing.271 * @param {string|string[]} path Path to create272 * @param {*} [json] Nested types to create from JSON273 * @returns {Namespace} Pointer to the last namespace created or `this` if path is empty274 */275Namespace.prototype.define = function define(path, json) {276 277    if (util.isString(path))278        path = path.split(".");279    else if (!Array.isArray(path))280        throw TypeError("illegal path");281    if (path && path.length && path[0] === "")282        throw Error("path must be relative");283 284    var ptr = this;285    while (path.length > 0) {286        var part = path.shift();287        if (ptr.nested && ptr.nested[part]) {288            ptr = ptr.nested[part];289            if (!(ptr instanceof Namespace))290                throw Error("path conflicts with non-namespace objects");291        } else292            ptr.add(ptr = new Namespace(part));293    }294    if (json)295        ptr.addJSON(json);296    return ptr;297};298 299/**300 * Resolves this namespace's and all its nested objects' type references. Useful to validate a reflection tree, but comes at a cost.301 * @returns {Namespace} `this`302 */303Namespace.prototype.resolveAll = function resolveAll() {304    var nested = this.nestedArray, i = 0;305    while (i < nested.length)306        if (nested[i] instanceof Namespace)307            nested[i++].resolveAll();308        else309            nested[i++].resolve();310    return this.resolve();311};312 313/**314 * Recursively looks up the reflection object matching the specified path in the scope of this namespace.315 * @param {string|string[]} path Path to look up316 * @param {*|Array.<*>} filterTypes Filter types, any combination of the constructors of `protobuf.Type`, `protobuf.Enum`, `protobuf.Service` etc.317 * @param {boolean} [parentAlreadyChecked=false] If known, whether the parent has already been checked318 * @returns {ReflectionObject|null} Looked up object or `null` if none could be found319 */320Namespace.prototype.lookup = function lookup(path, filterTypes, parentAlreadyChecked) {321 322    /* istanbul ignore next */323    if (typeof filterTypes === "boolean") {324        parentAlreadyChecked = filterTypes;325        filterTypes = undefined;326    } else if (filterTypes && !Array.isArray(filterTypes))327        filterTypes = [ filterTypes ];328 329    if (util.isString(path) && path.length) {330        if (path === ".")331            return this.root;332        path = path.split(".");333    } else if (!path.length)334        return this;335 336    // Start at root if path is absolute337    if (path[0] === "")338        return this.root.lookup(path.slice(1), filterTypes);339 340    // Test if the first part matches any nested object, and if so, traverse if path contains more341    var found = this.get(path[0]);342    if (found) {343        if (path.length === 1) {344            if (!filterTypes || filterTypes.indexOf(found.constructor) > -1)345                return found;346        } else if (found instanceof Namespace && (found = found.lookup(path.slice(1), filterTypes, true)))347            return found;348 349    // Otherwise try each nested namespace350    } else351        for (var i = 0; i < this.nestedArray.length; ++i)352            if (this._nestedArray[i] instanceof Namespace && (found = this._nestedArray[i].lookup(path, filterTypes, true)))353                return found;354 355    // If there hasn't been a match, try again at the parent356    if (this.parent === null || parentAlreadyChecked)357        return null;358    return this.parent.lookup(path, filterTypes);359};360 361/**362 * Looks up the reflection object at the specified path, relative to this namespace.363 * @name NamespaceBase#lookup364 * @function365 * @param {string|string[]} path Path to look up366 * @param {boolean} [parentAlreadyChecked=false] Whether the parent has already been checked367 * @returns {ReflectionObject|null} Looked up object or `null` if none could be found368 * @variation 2369 */370// lookup(path: string, [parentAlreadyChecked: boolean])371 372/**373 * Looks up the {@link Type|type} at the specified path, relative to this namespace.374 * Besides its signature, this methods differs from {@link Namespace#lookup|lookup} in that it throws instead of returning `null`.375 * @param {string|string[]} path Path to look up376 * @returns {Type} Looked up type377 * @throws {Error} If `path` does not point to a type378 */379Namespace.prototype.lookupType = function lookupType(path) {380    var found = this.lookup(path, [ Type ]);381    if (!found)382        throw Error("no such type: " + path);383    return found;384};385 386/**387 * Looks up the values of the {@link Enum|enum} at the specified path, relative to this namespace.388 * Besides its signature, this methods differs from {@link Namespace#lookup|lookup} in that it throws instead of returning `null`.389 * @param {string|string[]} path Path to look up390 * @returns {Enum} Looked up enum391 * @throws {Error} If `path` does not point to an enum392 */393Namespace.prototype.lookupEnum = function lookupEnum(path) {394    var found = this.lookup(path, [ Enum ]);395    if (!found)396        throw Error("no such Enum '" + path + "' in " + this);397    return found;398};399 400/**401 * Looks up the {@link Type|type} or {@link Enum|enum} at the specified path, relative to this namespace.402 * Besides its signature, this methods differs from {@link Namespace#lookup|lookup} in that it throws instead of returning `null`.403 * @param {string|string[]} path Path to look up404 * @returns {Type} Looked up type or enum405 * @throws {Error} If `path` does not point to a type or enum406 */407Namespace.prototype.lookupTypeOrEnum = function lookupTypeOrEnum(path) {408    var found = this.lookup(path, [ Type, Enum ]);409    if (!found)410        throw Error("no such Type or Enum '" + path + "' in " + this);411    return found;412};413 414/**415 * Looks up the {@link Service|service} at the specified path, relative to this namespace.416 * Besides its signature, this methods differs from {@link Namespace#lookup|lookup} in that it throws instead of returning `null`.417 * @param {string|string[]} path Path to look up418 * @returns {Service} Looked up service419 * @throws {Error} If `path` does not point to a service420 */421Namespace.prototype.lookupService = function lookupService(path) {422    var found = this.lookup(path, [ Service ]);423    if (!found)424        throw Error("no such Service '" + path + "' in " + this);425    return found;426};427 428// Sets up cyclic dependencies (called in index-light)429Namespace._configure = function(Type_, Service_, Enum_) {430    Type    = Type_;431    Service = Service_;432    Enum    = Enum_;433};434