"use strict";
module.exports = Enum;
var ReflectionObject = require("./object");
((Enum.prototype = Object.create(ReflectionObject.prototype)).constructor = Enum).className = "Enum";
var Namespace = require("./namespace"),
util = require("./util");
function Enum(name, values, options, comment, comments, valuesOptions) {
ReflectionObject.call(this, name, options);
if (values && typeof values !== "object")
throw TypeError("values must be an object");
this.valuesById = {};
this.values = Object.create(this.valuesById);
this.comment = comment;
this.comments = comments || {};
this.valuesOptions = valuesOptions;
this._valuesFeatures = {};
this.reserved = undefined;
if (values)
for (var keys = Object.keys(values), i = 0; i < keys.length; ++i)
if (typeof values[keys[i]] === "number") this.valuesById[ this.values[keys[i]] = values[keys[i]] ] = keys[i];
}
Enum.prototype._resolveFeatures = function _resolveFeatures(edition) {
edition = this._edition || edition;
ReflectionObject.prototype._resolveFeatures.call(this, edition);
Object.keys(this.values).forEach(key => {
var parentFeaturesCopy = Object.assign({}, this._features);
this._valuesFeatures[key] = Object.assign(parentFeaturesCopy, this.valuesOptions && this.valuesOptions[key] && this.valuesOptions[key].features);
});
return this;
};
Enum.fromJSON = function fromJSON(name, json) {
var enm = new Enum(name, json.values, json.options, json.comment, json.comments);
enm.reserved = json.reserved;
if (json.edition)
enm._edition = json.edition;
enm._defaultEdition = "proto3"; return enm;
};
Enum.prototype.toJSON = function toJSON(toJSONOptions) {
var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
return util.toObject([
"edition" , this._editionToJSON(),
"options" , this.options,
"valuesOptions" , this.valuesOptions,
"values" , this.values,
"reserved" , this.reserved && this.reserved.length ? this.reserved : undefined,
"comment" , keepComments ? this.comment : undefined,
"comments" , keepComments ? this.comments : undefined
]);
};
Enum.prototype.add = function add(name, id, comment, options) {
if (!util.isString(name))
throw TypeError("name must be a string");
if (!util.isInteger(id))
throw TypeError("id must be an integer");
if (this.values[name] !== undefined)
throw Error("duplicate name '" + name + "' in " + this);
if (this.isReservedId(id))
throw Error("id " + id + " is reserved in " + this);
if (this.isReservedName(name))
throw Error("name '" + name + "' is reserved in " + this);
if (this.valuesById[id] !== undefined) {
if (!(this.options && this.options.allow_alias))
throw Error("duplicate id " + id + " in " + this);
this.values[name] = id;
} else
this.valuesById[this.values[name] = id] = name;
if (options) {
if (this.valuesOptions === undefined)
this.valuesOptions = {};
this.valuesOptions[name] = options || null;
}
this.comments[name] = comment || null;
return this;
};
Enum.prototype.remove = function remove(name) {
if (!util.isString(name))
throw TypeError("name must be a string");
var val = this.values[name];
if (val == null)
throw Error("name '" + name + "' does not exist in " + this);
delete this.valuesById[val];
delete this.values[name];
delete this.comments[name];
if (this.valuesOptions)
delete this.valuesOptions[name];
return this;
};
Enum.prototype.isReservedId = function isReservedId(id) {
return Namespace.isReservedId(this.reserved, id);
};
Enum.prototype.isReservedName = function isReservedName(name) {
return Namespace.isReservedName(this.reserved, name);
};