Initial Commit
This commit is contained in:
404
node_modules/protobufjs/src/root.js
generated
vendored
Normal file
404
node_modules/protobufjs/src/root.js
generated
vendored
Normal file
@@ -0,0 +1,404 @@
|
||||
"use strict";
|
||||
module.exports = Root;
|
||||
|
||||
// extends Namespace
|
||||
var Namespace = require("./namespace");
|
||||
((Root.prototype = Object.create(Namespace.prototype)).constructor = Root).className = "Root";
|
||||
|
||||
var Field = require("./field"),
|
||||
Enum = require("./enum"),
|
||||
OneOf = require("./oneof"),
|
||||
util = require("./util");
|
||||
|
||||
var Type, // cyclic
|
||||
parse, // might be excluded
|
||||
common; // "
|
||||
|
||||
/**
|
||||
* Constructs a new root namespace instance.
|
||||
* @classdesc Root namespace wrapping all types, enums, services, sub-namespaces etc. that belong together.
|
||||
* @extends NamespaceBase
|
||||
* @constructor
|
||||
* @param {Object.<string,*>} [options] Top level options
|
||||
*/
|
||||
function Root(options) {
|
||||
Namespace.call(this, "", options);
|
||||
|
||||
/**
|
||||
* Deferred extension fields.
|
||||
* @type {Field[]}
|
||||
*/
|
||||
this.deferred = [];
|
||||
|
||||
/**
|
||||
* Resolved file names of loaded files.
|
||||
* @type {string[]}
|
||||
*/
|
||||
this.files = [];
|
||||
|
||||
/**
|
||||
* Edition, defaults to proto2 if unspecified.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this._edition = "proto2";
|
||||
|
||||
/**
|
||||
* Global lookup cache of fully qualified names.
|
||||
* @type {Object.<string,ReflectionObject>}
|
||||
* @private
|
||||
*/
|
||||
this._fullyQualifiedObjects = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a namespace descriptor into a root namespace.
|
||||
* @param {INamespace} json Namespace descriptor
|
||||
* @param {Root} [root] Root namespace, defaults to create a new one if omitted
|
||||
* @returns {Root} Root namespace
|
||||
*/
|
||||
Root.fromJSON = function fromJSON(json, root) {
|
||||
if (!root)
|
||||
root = new Root();
|
||||
if (json.options)
|
||||
root.setOptions(json.options);
|
||||
return root.addJSON(json.nested).resolveAll();
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolves the path of an imported file, relative to the importing origin.
|
||||
* This method exists so you can override it with your own logic in case your imports are scattered over multiple directories.
|
||||
* @function
|
||||
* @param {string} origin The file name of the importing file
|
||||
* @param {string} target The file name being imported
|
||||
* @returns {string|null} Resolved path to `target` or `null` to skip the file
|
||||
*/
|
||||
Root.prototype.resolvePath = util.path.resolve;
|
||||
|
||||
/**
|
||||
* Fetch content from file path or url
|
||||
* This method exists so you can override it with your own logic.
|
||||
* @function
|
||||
* @param {string} path File path or url
|
||||
* @param {FetchCallback} callback Callback function
|
||||
* @returns {undefined}
|
||||
*/
|
||||
Root.prototype.fetch = util.fetch;
|
||||
|
||||
// A symbol-like function to safely signal synchronous loading
|
||||
/* istanbul ignore next */
|
||||
function SYNC() {} // eslint-disable-line no-empty-function
|
||||
|
||||
/**
|
||||
* Loads one or multiple .proto or preprocessed .json files into this root namespace and calls the callback.
|
||||
* @param {string|string[]} filename Names of one or multiple files to load
|
||||
* @param {IParseOptions} options Parse options
|
||||
* @param {LoadCallback} callback Callback function
|
||||
* @returns {undefined}
|
||||
*/
|
||||
Root.prototype.load = function load(filename, options, callback) {
|
||||
if (typeof options === "function") {
|
||||
callback = options;
|
||||
options = undefined;
|
||||
}
|
||||
var self = this;
|
||||
if (!callback) {
|
||||
return util.asPromise(load, self, filename, options);
|
||||
}
|
||||
|
||||
var sync = callback === SYNC; // undocumented
|
||||
|
||||
// Finishes loading by calling the callback (exactly once)
|
||||
function finish(err, root) {
|
||||
/* istanbul ignore if */
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
if (sync) {
|
||||
throw err;
|
||||
}
|
||||
if (root) {
|
||||
root.resolveAll();
|
||||
}
|
||||
var cb = callback;
|
||||
callback = null;
|
||||
cb(err, root);
|
||||
}
|
||||
|
||||
// Bundled definition existence checking
|
||||
function getBundledFileName(filename) {
|
||||
var idx = filename.lastIndexOf("google/protobuf/");
|
||||
if (idx > -1) {
|
||||
var altname = filename.substring(idx);
|
||||
if (altname in common) return altname;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Processes a single file
|
||||
function process(filename, source) {
|
||||
try {
|
||||
if (util.isString(source) && source.charAt(0) === "{")
|
||||
source = JSON.parse(source);
|
||||
if (!util.isString(source))
|
||||
self.setOptions(source.options).addJSON(source.nested);
|
||||
else {
|
||||
parse.filename = filename;
|
||||
var parsed = parse(source, self, options),
|
||||
resolved,
|
||||
i = 0;
|
||||
if (parsed.imports)
|
||||
for (; i < parsed.imports.length; ++i)
|
||||
if (resolved = getBundledFileName(parsed.imports[i]) || self.resolvePath(filename, parsed.imports[i]))
|
||||
fetch(resolved);
|
||||
if (parsed.weakImports)
|
||||
for (i = 0; i < parsed.weakImports.length; ++i)
|
||||
if (resolved = getBundledFileName(parsed.weakImports[i]) || self.resolvePath(filename, parsed.weakImports[i]))
|
||||
fetch(resolved, true);
|
||||
}
|
||||
} catch (err) {
|
||||
finish(err);
|
||||
}
|
||||
if (!sync && !queued) {
|
||||
finish(null, self); // only once anyway
|
||||
}
|
||||
}
|
||||
|
||||
// Fetches a single file
|
||||
function fetch(filename, weak) {
|
||||
filename = getBundledFileName(filename) || filename;
|
||||
|
||||
// Skip if already loaded / attempted
|
||||
if (self.files.indexOf(filename) > -1) {
|
||||
return;
|
||||
}
|
||||
self.files.push(filename);
|
||||
|
||||
// Shortcut bundled definitions
|
||||
if (filename in common) {
|
||||
if (sync) {
|
||||
process(filename, common[filename]);
|
||||
} else {
|
||||
++queued;
|
||||
setTimeout(function() {
|
||||
--queued;
|
||||
process(filename, common[filename]);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise fetch from disk or network
|
||||
if (sync) {
|
||||
var source;
|
||||
try {
|
||||
source = util.fs.readFileSync(filename).toString("utf8");
|
||||
} catch (err) {
|
||||
if (!weak)
|
||||
finish(err);
|
||||
return;
|
||||
}
|
||||
process(filename, source);
|
||||
} else {
|
||||
++queued;
|
||||
self.fetch(filename, function(err, source) {
|
||||
--queued;
|
||||
/* istanbul ignore if */
|
||||
if (!callback) {
|
||||
return; // terminated meanwhile
|
||||
}
|
||||
if (err) {
|
||||
/* istanbul ignore else */
|
||||
if (!weak)
|
||||
finish(err);
|
||||
else if (!queued) // can't be covered reliably
|
||||
finish(null, self);
|
||||
return;
|
||||
}
|
||||
process(filename, source);
|
||||
});
|
||||
}
|
||||
}
|
||||
var queued = 0;
|
||||
|
||||
// Assembling the root namespace doesn't require working type
|
||||
// references anymore, so we can load everything in parallel
|
||||
if (util.isString(filename)) {
|
||||
filename = [ filename ];
|
||||
}
|
||||
for (var i = 0, resolved; i < filename.length; ++i)
|
||||
if (resolved = self.resolvePath("", filename[i]))
|
||||
fetch(resolved);
|
||||
if (sync) {
|
||||
self.resolveAll();
|
||||
return self;
|
||||
}
|
||||
if (!queued) {
|
||||
finish(null, self);
|
||||
}
|
||||
|
||||
return self;
|
||||
};
|
||||
// function load(filename:string, options:IParseOptions, callback:LoadCallback):undefined
|
||||
|
||||
/**
|
||||
* Loads one or multiple .proto or preprocessed .json files into this root namespace and calls the callback.
|
||||
* @function Root#load
|
||||
* @param {string|string[]} filename Names of one or multiple files to load
|
||||
* @param {LoadCallback} callback Callback function
|
||||
* @returns {undefined}
|
||||
* @variation 2
|
||||
*/
|
||||
// function load(filename:string, callback:LoadCallback):undefined
|
||||
|
||||
/**
|
||||
* Loads one or multiple .proto or preprocessed .json files into this root namespace and returns a promise.
|
||||
* @function Root#load
|
||||
* @param {string|string[]} filename Names of one or multiple files to load
|
||||
* @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
|
||||
* @returns {Promise<Root>} Promise
|
||||
* @variation 3
|
||||
*/
|
||||
// function load(filename:string, [options:IParseOptions]):Promise<Root>
|
||||
|
||||
/**
|
||||
* Synchronously loads one or multiple .proto or preprocessed .json files into this root namespace (node only).
|
||||
* @function Root#loadSync
|
||||
* @param {string|string[]} filename Names of one or multiple files to load
|
||||
* @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
|
||||
* @returns {Root} Root namespace
|
||||
* @throws {Error} If synchronous fetching is not supported (i.e. in browsers) or if a file's syntax is invalid
|
||||
*/
|
||||
Root.prototype.loadSync = function loadSync(filename, options) {
|
||||
if (!util.isNode)
|
||||
throw Error("not supported");
|
||||
return this.load(filename, options, SYNC);
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Root.prototype.resolveAll = function resolveAll() {
|
||||
if (!this._needsRecursiveResolve) return this;
|
||||
|
||||
if (this.deferred.length)
|
||||
throw Error("unresolvable extensions: " + this.deferred.map(function(field) {
|
||||
return "'extend " + field.extend + "' in " + field.parent.fullName;
|
||||
}).join(", "));
|
||||
return Namespace.prototype.resolveAll.call(this);
|
||||
};
|
||||
|
||||
// only uppercased (and thus conflict-free) children are exposed, see below
|
||||
var exposeRe = /^[A-Z]/;
|
||||
|
||||
/**
|
||||
* Handles a deferred declaring extension field by creating a sister field to represent it within its extended type.
|
||||
* @param {Root} root Root instance
|
||||
* @param {Field} field Declaring extension field witin the declaring type
|
||||
* @returns {boolean} `true` if successfully added to the extended type, `false` otherwise
|
||||
* @inner
|
||||
* @ignore
|
||||
*/
|
||||
function tryHandleExtension(root, field) {
|
||||
var extendedType = field.parent.lookup(field.extend);
|
||||
if (extendedType) {
|
||||
var sisterField = new Field(field.fullName, field.id, field.type, field.rule, undefined, field.options);
|
||||
//do not allow to extend same field twice to prevent the error
|
||||
if (extendedType.get(sisterField.name)) {
|
||||
return true;
|
||||
}
|
||||
sisterField.declaringField = field;
|
||||
field.extensionField = sisterField;
|
||||
extendedType.add(sisterField);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when any object is added to this root or its sub-namespaces.
|
||||
* @param {ReflectionObject} object Object added
|
||||
* @returns {undefined}
|
||||
* @private
|
||||
*/
|
||||
Root.prototype._handleAdd = function _handleAdd(object) {
|
||||
if (object instanceof Field) {
|
||||
|
||||
if (/* an extension field (implies not part of a oneof) */ object.extend !== undefined && /* not already handled */ !object.extensionField)
|
||||
if (!tryHandleExtension(this, object))
|
||||
this.deferred.push(object);
|
||||
|
||||
} else if (object instanceof Enum) {
|
||||
|
||||
if (exposeRe.test(object.name))
|
||||
object.parent[object.name] = object.values; // expose enum values as property of its parent
|
||||
|
||||
} else if (!(object instanceof OneOf)) /* everything else is a namespace */ {
|
||||
|
||||
if (object instanceof Type) // Try to handle any deferred extensions
|
||||
for (var i = 0; i < this.deferred.length;)
|
||||
if (tryHandleExtension(this, this.deferred[i]))
|
||||
this.deferred.splice(i, 1);
|
||||
else
|
||||
++i;
|
||||
for (var j = 0; j < /* initializes */ object.nestedArray.length; ++j) // recurse into the namespace
|
||||
this._handleAdd(object._nestedArray[j]);
|
||||
if (exposeRe.test(object.name))
|
||||
object.parent[object.name] = object; // expose namespace as property of its parent
|
||||
}
|
||||
|
||||
if (object instanceof Type || object instanceof Enum || object instanceof Field) {
|
||||
// Only store types and enums for quick lookup during resolve.
|
||||
this._fullyQualifiedObjects[object.fullName] = object;
|
||||
}
|
||||
|
||||
// The above also adds uppercased (and thus conflict-free) nested types, services and enums as
|
||||
// properties of namespaces just like static code does. This allows using a .d.ts generated for
|
||||
// a static module with reflection-based solutions where the condition is met.
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when any object is removed from this root or its sub-namespaces.
|
||||
* @param {ReflectionObject} object Object removed
|
||||
* @returns {undefined}
|
||||
* @private
|
||||
*/
|
||||
Root.prototype._handleRemove = function _handleRemove(object) {
|
||||
if (object instanceof Field) {
|
||||
|
||||
if (/* an extension field */ object.extend !== undefined) {
|
||||
if (/* already handled */ object.extensionField) { // remove its sister field
|
||||
object.extensionField.parent.remove(object.extensionField);
|
||||
object.extensionField = null;
|
||||
} else { // cancel the extension
|
||||
var index = this.deferred.indexOf(object);
|
||||
/* istanbul ignore else */
|
||||
if (index > -1)
|
||||
this.deferred.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (object instanceof Enum) {
|
||||
|
||||
if (exposeRe.test(object.name))
|
||||
delete object.parent[object.name]; // unexpose enum values
|
||||
|
||||
} else if (object instanceof Namespace) {
|
||||
|
||||
for (var i = 0; i < /* initializes */ object.nestedArray.length; ++i) // recurse into the namespace
|
||||
this._handleRemove(object._nestedArray[i]);
|
||||
|
||||
if (exposeRe.test(object.name))
|
||||
delete object.parent[object.name]; // unexpose namespaces
|
||||
|
||||
}
|
||||
|
||||
delete this._fullyQualifiedObjects[object.fullName];
|
||||
};
|
||||
|
||||
// Sets up cyclic dependencies (called in index-light)
|
||||
Root._configure = function(Type_, parse_, common_) {
|
||||
Type = Type_;
|
||||
parse = parse_;
|
||||
common = common_;
|
||||
};
|
||||
Reference in New Issue
Block a user