diff options
Diffstat (limited to 'third_party/protobuf/3.4.0/js/map.js')
-rw-r--r-- | third_party/protobuf/3.4.0/js/map.js | 531 |
1 files changed, 531 insertions, 0 deletions
diff --git a/third_party/protobuf/3.4.0/js/map.js b/third_party/protobuf/3.4.0/js/map.js new file mode 100644 index 0000000000..d423499f05 --- /dev/null +++ b/third_party/protobuf/3.4.0/js/map.js @@ -0,0 +1,531 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +goog.provide('jspb.Map'); + +goog.require('goog.asserts'); + +goog.forwardDeclare('jspb.BinaryReader'); +goog.forwardDeclare('jspb.BinaryWriter'); + + + +/** + * Constructs a new Map. A Map is a container that is used to implement map + * fields on message objects. It closely follows the ES6 Map API; however, + * it is distinct because we do not want to depend on external polyfills or + * on ES6 itself. + * + * This constructor should only be called from generated message code. It is not + * intended for general use by library consumers. + * + * @template K, V + * + * @param {!Array<!Array<!Object>>} arr + * + * @param {?function(new:V)|function(new:V,?)=} opt_valueCtor + * The constructor for type V, if type V is a message type. + * + * @constructor + * @struct + */ +jspb.Map = function(arr, opt_valueCtor) { + /** @const @private */ + this.arr_ = arr; + /** @const @private */ + this.valueCtor_ = opt_valueCtor; + + /** @type {!Object<string, !jspb.Map.Entry_<K,V>>} @private */ + this.map_ = {}; + + /** + * Is `this.arr_ updated with respect to `this.map_`? + * @type {boolean} + */ + this.arrClean = true; + + if (this.arr_.length > 0) { + this.loadFromArray_(); + } +}; + + +/** + * Load initial content from underlying array. + * @private + */ +jspb.Map.prototype.loadFromArray_ = function() { + for (var i = 0; i < this.arr_.length; i++) { + var record = this.arr_[i]; + var key = record[0]; + var value = record[1]; + this.map_[key.toString()] = new jspb.Map.Entry_(key, value); + } + this.arrClean = true; +}; + + +/** + * Synchronize content to underlying array, if needed, and return it. + * @return {!Array<!Array<!Object>>} + */ +jspb.Map.prototype.toArray = function() { + if (this.arrClean) { + if (this.valueCtor_) { + // We need to recursively sync maps in submessages to their arrays. + var m = this.map_; + for (var p in m) { + if (Object.prototype.hasOwnProperty.call(m, p)) { + var valueWrapper = /** @type {?jspb.Message} */ (m[p].valueWrapper); + if (valueWrapper) { + valueWrapper.toArray(); + } + } + } + } + } else { + // Delete all elements. + this.arr_.length = 0; + var strKeys = this.stringKeys_(); + // Output keys in deterministic (sorted) order. + strKeys.sort(); + for (var i = 0; i < strKeys.length; i++) { + var entry = this.map_[strKeys[i]]; + var valueWrapper = /** @type {!Object} */ (entry.valueWrapper); + if (valueWrapper) { + valueWrapper.toArray(); + } + this.arr_.push([entry.key, entry.value]); + } + this.arrClean = true; + } + return this.arr_; +}; + + +/** + * Returns the map formatted as an array of key-value pairs, suitable for the + * toObject() form of a message. + * + * @param {boolean=} includeInstance Whether to include the JSPB instance for + * transitional soy proto support: http://goto/soy-param-migration + * @param {!function((boolean|undefined),V):!Object=} valueToObject + * The static toObject() method, if V is a message type. + * @return {!Array<!Array<!Object>>} + */ +jspb.Map.prototype.toObject = function(includeInstance, valueToObject) { + var rawArray = this.toArray(); + var entries = []; + for (var i = 0; i < rawArray.length; i++) { + var entry = this.map_[rawArray[i][0].toString()]; + this.wrapEntry_(entry); + var valueWrapper = /** @type {V|undefined} */ (entry.valueWrapper); + if (valueWrapper) { + goog.asserts.assert(valueToObject); + entries.push([entry.key, valueToObject(includeInstance, valueWrapper)]); + } else { + entries.push([entry.key, entry.value]); + } + } + return entries; +}; + + +/** + * Returns a Map from the given array of key-value pairs when the values are of + * message type. The values in the array must match the format returned by their + * message type's toObject() method. + * + * @template K, V + * @param {!Array<!Array<!Object>>} entries + * @param {!function(new:V)|function(new:V,?)} valueCtor + * The constructor for type V. + * @param {!function(!Object):V} valueFromObject + * The fromObject function for type V. + * @return {!jspb.Map<K, V>} + */ +jspb.Map.fromObject = function(entries, valueCtor, valueFromObject) { + var result = new jspb.Map([], valueCtor); + for (var i = 0; i < entries.length; i++) { + var key = entries[i][0]; + var value = valueFromObject(entries[i][1]); + result.set(key, value); + } + return result; +}; + + +/** + * Helper: an IteratorIterable over an array. + * @template T + * @param {!Array<T>} arr the array + * @implements {IteratorIterable<T>} + * @constructor @struct + * @private + */ +jspb.Map.ArrayIteratorIterable_ = function(arr) { + /** @type {number} @private */ + this.idx_ = 0; + + /** @const @private */ + this.arr_ = arr; +}; + + +/** @override @final */ +jspb.Map.ArrayIteratorIterable_.prototype.next = function() { + if (this.idx_ < this.arr_.length) { + return {done: false, value: this.arr_[this.idx_++]}; + } else { + return {done: true, value: undefined}; + } +}; + +if (typeof(Symbol) != 'undefined') { + /** @override */ + jspb.Map.ArrayIteratorIterable_.prototype[Symbol.iterator] = function() { + return this; + }; +} + + +/** + * Returns the map's length (number of key/value pairs). + * @return {number} + */ +jspb.Map.prototype.getLength = function() { + return this.stringKeys_().length; +}; + + +/** + * Clears the map. + */ +jspb.Map.prototype.clear = function() { + this.map_ = {}; + this.arrClean = false; +}; + + +/** + * Deletes a particular key from the map. + * N.B.: differs in name from ES6 Map's `delete` because IE8 does not support + * reserved words as property names. + * @this {jspb.Map} + * @param {K} key + * @return {boolean} Whether any entry with this key was deleted. + */ +jspb.Map.prototype.del = function(key) { + var keyValue = key.toString(); + var hadKey = this.map_.hasOwnProperty(keyValue); + delete this.map_[keyValue]; + this.arrClean = false; + return hadKey; +}; + + +/** + * Returns an array of [key, value] pairs in the map. + * + * This is redundant compared to the plain entries() method, but we provide this + * to help out Angular 1.x users. Still evaluating whether this is the best + * option. + * + * @return {!Array<!Array<K|V>>} + */ +jspb.Map.prototype.getEntryList = function() { + var entries = []; + var strKeys = this.stringKeys_(); + strKeys.sort(); + for (var i = 0; i < strKeys.length; i++) { + var entry = this.map_[strKeys[i]]; + entries.push([entry.key, entry.value]); + } + return entries; +}; + + +/** + * Returns an iterator-iterable over [key, value] pairs in the map. + * Closure compiler sadly doesn't support tuples, ie. Iterator<[K,V]>. + * @return {!IteratorIterable<!Array<K|V>>} The iterator-iterable. + */ +jspb.Map.prototype.entries = function() { + var entries = []; + var strKeys = this.stringKeys_(); + strKeys.sort(); + for (var i = 0; i < strKeys.length; i++) { + var entry = this.map_[strKeys[i]]; + entries.push([entry.key, this.wrapEntry_(entry)]); + } + return new jspb.Map.ArrayIteratorIterable_(entries); +}; + + +/** + * Returns an iterator-iterable over keys in the map. + * @return {!IteratorIterable<K>} The iterator-iterable. + */ +jspb.Map.prototype.keys = function() { + var keys = []; + var strKeys = this.stringKeys_(); + strKeys.sort(); + for (var i = 0; i < strKeys.length; i++) { + var entry = this.map_[strKeys[i]]; + keys.push(entry.key); + } + return new jspb.Map.ArrayIteratorIterable_(keys); +}; + + +/** + * Returns an iterator-iterable over values in the map. + * @return {!IteratorIterable<V>} The iterator-iterable. + */ +jspb.Map.prototype.values = function() { + var values = []; + var strKeys = this.stringKeys_(); + strKeys.sort(); + for (var i = 0; i < strKeys.length; i++) { + var entry = this.map_[strKeys[i]]; + values.push(this.wrapEntry_(entry)); + } + return new jspb.Map.ArrayIteratorIterable_(values); +}; + + +/** + * Iterates over entries in the map, calling a function on each. + * @template T + * @param {function(this:T, V, K, ?jspb.Map<K, V>)} cb + * @param {T=} opt_thisArg + */ +jspb.Map.prototype.forEach = function(cb, opt_thisArg) { + var strKeys = this.stringKeys_(); + strKeys.sort(); + for (var i = 0; i < strKeys.length; i++) { + var entry = this.map_[strKeys[i]]; + cb.call(opt_thisArg, this.wrapEntry_(entry), entry.key, this); + } +}; + + +/** + * Sets a key in the map to the given value. + * @param {K} key The key + * @param {V} value The value + * @return {!jspb.Map<K,V>} + */ +jspb.Map.prototype.set = function(key, value) { + var entry = new jspb.Map.Entry_(key); + if (this.valueCtor_) { + entry.valueWrapper = value; + // .toArray() on a message returns a reference to the underlying array + // rather than a copy. + entry.value = value.toArray(); + } else { + entry.value = value; + } + this.map_[key.toString()] = entry; + this.arrClean = false; + return this; +}; + + +/** + * Helper: lazily construct a wrapper around an entry, if needed, and return the + * user-visible type. + * @param {!jspb.Map.Entry_<K,V>} entry + * @return {V} + * @private + */ +jspb.Map.prototype.wrapEntry_ = function(entry) { + if (this.valueCtor_) { + if (!entry.valueWrapper) { + entry.valueWrapper = new this.valueCtor_(entry.value); + } + return /** @type {V} */ (entry.valueWrapper); + } else { + return entry.value; + } +}; + + +/** + * Gets the value corresponding to a key in the map. + * @param {K} key + * @return {V|undefined} The value, or `undefined` if key not present + */ +jspb.Map.prototype.get = function(key) { + var keyValue = key.toString(); + var entry = this.map_[keyValue]; + if (entry) { + return this.wrapEntry_(entry); + } else { + return undefined; + } +}; + + +/** + * Determines whether the given key is present in the map. + * @param {K} key + * @return {boolean} `true` if the key is present + */ +jspb.Map.prototype.has = function(key) { + var keyValue = key.toString(); + return (keyValue in this.map_); +}; + + +/** + * Write this Map field in wire format to a BinaryWriter, using the given field + * number. + * @param {number} fieldNumber + * @param {!jspb.BinaryWriter} writer + * @param {!function(this:jspb.BinaryWriter,number,K)} keyWriterFn + * The method on BinaryWriter that writes type K to the stream. + * @param {!function(this:jspb.BinaryWriter,number,V,?=)| + * function(this:jspb.BinaryWriter,number,V,?)} valueWriterFn + * The method on BinaryWriter that writes type V to the stream. May be + * writeMessage, in which case the second callback arg form is used. + * @param {function(V,!jspb.BinaryWriter)=} opt_valueWriterCallback + * The BinaryWriter serialization callback for type V, if V is a message + * type. + */ +jspb.Map.prototype.serializeBinary = function( + fieldNumber, writer, keyWriterFn, valueWriterFn, opt_valueWriterCallback) { + var strKeys = this.stringKeys_(); + strKeys.sort(); + for (var i = 0; i < strKeys.length; i++) { + var entry = this.map_[strKeys[i]]; + writer.beginSubMessage(fieldNumber); + keyWriterFn.call(writer, 1, entry.key); + if (this.valueCtor_) { + valueWriterFn.call(writer, 2, this.wrapEntry_(entry), + opt_valueWriterCallback); + } else { + valueWriterFn.call(writer, 2, entry.value); + } + writer.endSubMessage(); + } +}; + + +/** + * Read one key/value message from the given BinaryReader. Compatible as the + * `reader` callback parameter to jspb.BinaryReader.readMessage, to be called + * when a key/value pair submessage is encountered. + * @template K, V + * @param {!jspb.Map} map + * @param {!jspb.BinaryReader} reader + * @param {!function(this:jspb.BinaryReader):K} keyReaderFn + * The method on BinaryReader that reads type K from the stream. + * + * @param {!function(this:jspb.BinaryReader):V| + * function(this:jspb.BinaryReader,V, + * function(V,!jspb.BinaryReader))} valueReaderFn + * The method on BinaryReader that reads type V from the stream. May be + * readMessage, in which case the second callback arg form is used. + * + * @param {?function(V,!jspb.BinaryReader)=} opt_valueReaderCallback + * The BinaryReader parsing callback for type V, if V is a message type. + * + */ +jspb.Map.deserializeBinary = function(map, reader, keyReaderFn, valueReaderFn, + opt_valueReaderCallback) { + var key = undefined; + var value = undefined; + + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + if (field == 1) { + // Key. + key = keyReaderFn.call(reader); + } else if (field == 2) { + // Value. + if (map.valueCtor_) { + value = new map.valueCtor_(); + valueReaderFn.call(reader, value, opt_valueReaderCallback); + } else { + value = valueReaderFn.call(reader); + } + } + } + + goog.asserts.assert(key != undefined); + goog.asserts.assert(value != undefined); + map.set(key, value); +}; + + +/** + * Helper: compute the list of all stringified keys in the underlying Object + * map. + * @return {!Array<string>} + * @private + */ +jspb.Map.prototype.stringKeys_ = function() { + var m = this.map_; + var ret = []; + for (var p in m) { + if (Object.prototype.hasOwnProperty.call(m, p)) { + ret.push(p); + } + } + return ret; +}; + + + +/** + * @param {K} key The entry's key. + * @param {V=} opt_value The entry's value wrapper. + * @constructor + * @struct + * @template K, V + * @private + */ +jspb.Map.Entry_ = function(key, opt_value) { + /** @const {K} */ + this.key = key; + + // The JSPB-serializable value. For primitive types this will be of type V. + // For message types it will be an array. + /** @type {V} */ + this.value = opt_value; + + // Only used for submessage values. + /** @type {V} */ + this.valueWrapper = undefined; +}; |