aboutsummaryrefslogtreecommitdiffhomepage
path: root/js
diff options
context:
space:
mode:
Diffstat (limited to 'js')
-rw-r--r--js/binary/arith.js2
-rw-r--r--js/binary/constants.js19
-rw-r--r--js/binary/decoder.js12
-rw-r--r--js/binary/encoder.js4
-rw-r--r--js/binary/reader.js50
-rw-r--r--js/binary/utils.js12
-rw-r--r--js/binary/utils_test.js2
-rw-r--r--js/binary/writer.js112
-rw-r--r--js/binary/writer_test.js12
-rw-r--r--js/commonjs/export_testdeps.js1
-rw-r--r--js/debug.js11
-rw-r--r--js/debug_test.js11
-rw-r--r--js/map.js31
-rwxr-xr-xjs/maps_test.js40
-rw-r--r--js/message.js145
-rw-r--r--js/message_test.js23
-rw-r--r--js/package.json2
-rw-r--r--js/testbinary.proto32
18 files changed, 367 insertions, 154 deletions
diff --git a/js/binary/arith.js b/js/binary/arith.js
index 70257de7..62528a26 100644
--- a/js/binary/arith.js
+++ b/js/binary/arith.js
@@ -221,7 +221,7 @@ jspb.arith.UInt64.prototype.mul = function(a) {
* Divide a 64-bit number by a 32-bit number to produce a
* 64-bit quotient and a 32-bit remainder.
* @param {number} _divisor
- * @return {Array.<jspb.arith.UInt64>} array of [quotient, remainder],
+ * @return {Array<jspb.arith.UInt64>} array of [quotient, remainder],
* unless divisor is 0, in which case an empty array is returned.
*/
jspb.arith.UInt64.prototype.div = function(_divisor) {
diff --git a/js/binary/constants.js b/js/binary/constants.js
index 75a8a52c..21c5889c 100644
--- a/js/binary/constants.js
+++ b/js/binary/constants.js
@@ -60,14 +60,25 @@ goog.forwardDeclare('jsproto.BinaryExtension');
/**
- * Base interface class for all const messages. Does __not__ define any
- * methods, as doing so on a widely-used interface defeats dead-code
- * elimination.
+ * Base interface class for all const messages.
* @interface
*/
jspb.ConstBinaryMessage = function() {};
+/**
+ * Generate a debug string for this proto that is in proto2 text format.
+ * @return {string} The debug string.
+ */
+jspb.ConstBinaryMessage.prototype.toDebugString;
+/**
+ * Helper to generate a debug string for this proto at some indent level. The
+ * first line is not indented.
+ * @param {number} indentLevel The number of spaces by which to indent lines.
+ * @return {string} The debug string.
+ * @protected
+ */
+jspb.ConstBinaryMessage.prototype.toDebugStringInternal;
/**
* Base interface class for all messages. Does __not__ define any methods, as
@@ -97,6 +108,7 @@ jspb.ScalarFieldType;
* A repeated field in jspb is an array of scalars, blobs, or messages.
* @typedef {!Array<jspb.ScalarFieldType>|
!Array<!Uint8Array>|
+ !Array<!jspb.ConstBinaryMessage>|
!Array<!jspb.BinaryMessage>}
*/
jspb.RepeatedFieldType;
@@ -108,6 +120,7 @@ jspb.RepeatedFieldType;
* @typedef {jspb.ScalarFieldType|
jspb.RepeatedFieldType|
!Uint8Array|
+ !jspb.ConstBinaryMessage|
!jspb.BinaryMessage|
!jsproto.BinaryExtension}
*/
diff --git a/js/binary/decoder.js b/js/binary/decoder.js
index 4ec3cada..e33bf1be 100644
--- a/js/binary/decoder.js
+++ b/js/binary/decoder.js
@@ -58,7 +58,7 @@ goog.require('jspb.utils');
* @param {?jspb.BinaryDecoder=} opt_decoder
* @param {?function(this:jspb.BinaryDecoder):(number|boolean|string)=}
* opt_next The decoder method to use for next().
- * @param {?Array.<number|boolean|string>=} opt_elements
+ * @param {?Array<number|boolean|string>=} opt_elements
* @constructor
* @struct
*/
@@ -92,7 +92,7 @@ jspb.BinaryIterator = function(opt_decoder, opt_next, opt_elements) {
* @param {?jspb.BinaryDecoder=} opt_decoder
* @param {?function(this:jspb.BinaryDecoder):(number|boolean|string)=}
* opt_next The decoder method to use for next().
- * @param {?Array.<number|boolean|string>=} opt_elements
+ * @param {?Array<number|boolean|string>=} opt_elements
* @private
*/
jspb.BinaryIterator.prototype.init_ =
@@ -112,7 +112,7 @@ jspb.BinaryIterator.prototype.init_ =
/**
* Global pool of BinaryIterator instances.
- * @private {!Array.<!jspb.BinaryIterator>}
+ * @private {!Array<!jspb.BinaryIterator>}
*/
jspb.BinaryIterator.instanceCache_ = [];
@@ -123,7 +123,7 @@ jspb.BinaryIterator.instanceCache_ = [];
* @param {?jspb.BinaryDecoder=} opt_decoder
* @param {?function(this:jspb.BinaryDecoder):(number|boolean|string)=}
* opt_next The decoder method to use for next().
- * @param {?Array.<number|boolean|string>=} opt_elements
+ * @param {?Array<number|boolean|string>=} opt_elements
* @return {!jspb.BinaryIterator}
*/
jspb.BinaryIterator.alloc = function(opt_decoder, opt_next, opt_elements) {
@@ -274,7 +274,7 @@ jspb.BinaryDecoder = function(opt_bytes, opt_start, opt_length) {
/**
* Global pool of BinaryDecoder instances.
- * @private {!Array.<!jspb.BinaryDecoder>}
+ * @private {!Array<!jspb.BinaryDecoder>}
*/
jspb.BinaryDecoder.instanceCache_ = [];
@@ -986,7 +986,7 @@ jspb.BinaryDecoder.prototype.readString = function(length) {
codeUnits.push(high, low);
}
- // Avoid exceeding the maximum stack size when calling {@code apply}.
+ // Avoid exceeding the maximum stack size when calling `apply`.
if (codeUnits.length >= 8192) {
result += String.fromCharCode.apply(null, codeUnits);
codeUnits.length = 0;
diff --git a/js/binary/encoder.js b/js/binary/encoder.js
index 8e9f5bbc..b2013f63 100644
--- a/js/binary/encoder.js
+++ b/js/binary/encoder.js
@@ -51,7 +51,7 @@ goog.require('jspb.utils');
* @struct
*/
jspb.BinaryEncoder = function() {
- /** @private {!Array.<number>} */
+ /** @private {!Array<number>} */
this.buffer_ = [];
};
@@ -65,7 +65,7 @@ jspb.BinaryEncoder.prototype.length = function() {
/**
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryEncoder.prototype.end = function() {
var buffer = this.buffer_;
diff --git a/js/binary/reader.js b/js/binary/reader.js
index d5d698f7..2dc3eb70 100644
--- a/js/binary/reader.js
+++ b/js/binary/reader.js
@@ -97,7 +97,7 @@ jspb.BinaryReader = function(opt_bytes, opt_start, opt_length) {
/**
* User-defined reader callbacks.
- * @private {Object.<string, function(!jspb.BinaryReader):*>}
+ * @private {Object<string, function(!jspb.BinaryReader):*>}
*/
this.readCallbacks_ = null;
};
@@ -105,7 +105,7 @@ jspb.BinaryReader = function(opt_bytes, opt_start, opt_length) {
/**
* Global pool of BinaryReader instances.
- * @private {!Array.<!jspb.BinaryReader>}
+ * @private {!Array<!jspb.BinaryReader>}
*/
jspb.BinaryReader.instanceCache_ = [];
@@ -992,7 +992,7 @@ jspb.BinaryReader.prototype.readPackedField_ = function(decodeMethod) {
/**
* Reads a packed int32 field, which consists of a length header and a list of
* signed varints.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedInt32 = function() {
return this.readPackedField_(this.decoder_.readSignedVarint32);
@@ -1002,7 +1002,7 @@ jspb.BinaryReader.prototype.readPackedInt32 = function() {
/**
* Reads a packed int32 field, which consists of a length header and a list of
* signed varints. Returns a list of strings.
- * @return {!Array.<string>}
+ * @return {!Array<string>}
*/
jspb.BinaryReader.prototype.readPackedInt32String = function() {
return this.readPackedField_(this.decoder_.readSignedVarint32String);
@@ -1012,7 +1012,7 @@ jspb.BinaryReader.prototype.readPackedInt32String = function() {
/**
* Reads a packed int64 field, which consists of a length header and a list of
* signed varints.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedInt64 = function() {
return this.readPackedField_(this.decoder_.readSignedVarint64);
@@ -1022,7 +1022,7 @@ jspb.BinaryReader.prototype.readPackedInt64 = function() {
/**
* Reads a packed int64 field, which consists of a length header and a list of
* signed varints. Returns a list of strings.
- * @return {!Array.<string>}
+ * @return {!Array<string>}
*/
jspb.BinaryReader.prototype.readPackedInt64String = function() {
return this.readPackedField_(this.decoder_.readSignedVarint64String);
@@ -1032,7 +1032,7 @@ jspb.BinaryReader.prototype.readPackedInt64String = function() {
/**
* Reads a packed uint32 field, which consists of a length header and a list of
* unsigned varints.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedUint32 = function() {
return this.readPackedField_(this.decoder_.readUnsignedVarint32);
@@ -1042,7 +1042,7 @@ jspb.BinaryReader.prototype.readPackedUint32 = function() {
/**
* Reads a packed uint32 field, which consists of a length header and a list of
* unsigned varints. Returns a list of strings.
- * @return {!Array.<string>}
+ * @return {!Array<string>}
*/
jspb.BinaryReader.prototype.readPackedUint32String = function() {
return this.readPackedField_(this.decoder_.readUnsignedVarint32String);
@@ -1052,7 +1052,7 @@ jspb.BinaryReader.prototype.readPackedUint32String = function() {
/**
* Reads a packed uint64 field, which consists of a length header and a list of
* unsigned varints.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedUint64 = function() {
return this.readPackedField_(this.decoder_.readUnsignedVarint64);
@@ -1062,7 +1062,7 @@ jspb.BinaryReader.prototype.readPackedUint64 = function() {
/**
* Reads a packed uint64 field, which consists of a length header and a list of
* unsigned varints. Returns a list of strings.
- * @return {!Array.<string>}
+ * @return {!Array<string>}
*/
jspb.BinaryReader.prototype.readPackedUint64String = function() {
return this.readPackedField_(this.decoder_.readUnsignedVarint64String);
@@ -1072,7 +1072,7 @@ jspb.BinaryReader.prototype.readPackedUint64String = function() {
/**
* Reads a packed sint32 field, which consists of a length header and a list of
* zigzag varints.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedSint32 = function() {
return this.readPackedField_(this.decoder_.readZigzagVarint32);
@@ -1082,7 +1082,7 @@ jspb.BinaryReader.prototype.readPackedSint32 = function() {
/**
* Reads a packed sint64 field, which consists of a length header and a list of
* zigzag varints.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedSint64 = function() {
return this.readPackedField_(this.decoder_.readZigzagVarint64);
@@ -1092,7 +1092,7 @@ jspb.BinaryReader.prototype.readPackedSint64 = function() {
/**
* Reads a packed sint64 field, which consists of a length header and a list of
* zigzag varints. Returns a list of strings.
- * @return {!Array.<string>}
+ * @return {!Array<string>}
*/
jspb.BinaryReader.prototype.readPackedSint64String = function() {
return this.readPackedField_(this.decoder_.readZigzagVarint64String);
@@ -1102,7 +1102,7 @@ jspb.BinaryReader.prototype.readPackedSint64String = function() {
/**
* Reads a packed fixed32 field, which consists of a length header and a list
* of unsigned 32-bit ints.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedFixed32 = function() {
return this.readPackedField_(this.decoder_.readUint32);
@@ -1112,7 +1112,7 @@ jspb.BinaryReader.prototype.readPackedFixed32 = function() {
/**
* Reads a packed fixed64 field, which consists of a length header and a list
* of unsigned 64-bit ints.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedFixed64 = function() {
return this.readPackedField_(this.decoder_.readUint64);
@@ -1122,7 +1122,7 @@ jspb.BinaryReader.prototype.readPackedFixed64 = function() {
/**
* Reads a packed fixed64 field, which consists of a length header and a list
* of unsigned 64-bit ints. Returns a list of strings.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedFixed64String = function() {
return this.readPackedField_(this.decoder_.readUint64String);
@@ -1132,7 +1132,7 @@ jspb.BinaryReader.prototype.readPackedFixed64String = function() {
/**
* Reads a packed sfixed32 field, which consists of a length header and a list
* of 32-bit ints.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedSfixed32 = function() {
return this.readPackedField_(this.decoder_.readInt32);
@@ -1142,7 +1142,7 @@ jspb.BinaryReader.prototype.readPackedSfixed32 = function() {
/**
* Reads a packed sfixed64 field, which consists of a length header and a list
* of 64-bit ints.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedSfixed64 = function() {
return this.readPackedField_(this.decoder_.readInt64);
@@ -1152,7 +1152,7 @@ jspb.BinaryReader.prototype.readPackedSfixed64 = function() {
/**
* Reads a packed sfixed64 field, which consists of a length header and a list
* of 64-bit ints. Returns a list of strings.
- * @return {!Array.<string>}
+ * @return {!Array<string>}
*/
jspb.BinaryReader.prototype.readPackedSfixed64String = function() {
return this.readPackedField_(this.decoder_.readInt64String);
@@ -1162,7 +1162,7 @@ jspb.BinaryReader.prototype.readPackedSfixed64String = function() {
/**
* Reads a packed float field, which consists of a length header and a list of
* floats.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedFloat = function() {
return this.readPackedField_(this.decoder_.readFloat);
@@ -1172,7 +1172,7 @@ jspb.BinaryReader.prototype.readPackedFloat = function() {
/**
* Reads a packed double field, which consists of a length header and a list of
* doubles.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedDouble = function() {
return this.readPackedField_(this.decoder_.readDouble);
@@ -1182,7 +1182,7 @@ jspb.BinaryReader.prototype.readPackedDouble = function() {
/**
* Reads a packed bool field, which consists of a length header and a list of
* unsigned varints.
- * @return {!Array.<boolean>}
+ * @return {!Array<boolean>}
*/
jspb.BinaryReader.prototype.readPackedBool = function() {
return this.readPackedField_(this.decoder_.readBool);
@@ -1192,7 +1192,7 @@ jspb.BinaryReader.prototype.readPackedBool = function() {
/**
* Reads a packed enum field, which consists of a length header and a list of
* unsigned varints.
- * @return {!Array.<number>}
+ * @return {!Array<number>}
*/
jspb.BinaryReader.prototype.readPackedEnum = function() {
return this.readPackedField_(this.decoder_.readEnum);
@@ -1202,7 +1202,7 @@ jspb.BinaryReader.prototype.readPackedEnum = function() {
/**
* Reads a packed varint hash64 field, which consists of a length header and a
* list of varint hash64s.
- * @return {!Array.<string>}
+ * @return {!Array<string>}
*/
jspb.BinaryReader.prototype.readPackedVarintHash64 = function() {
return this.readPackedField_(this.decoder_.readVarintHash64);
@@ -1212,7 +1212,7 @@ jspb.BinaryReader.prototype.readPackedVarintHash64 = function() {
/**
* Reads a packed fixed hash64 field, which consists of a length header and a
* list of fixed hash64s.
- * @return {!Array.<string>}
+ * @return {!Array<string>}
*/
jspb.BinaryReader.prototype.readPackedFixedHash64 = function() {
return this.readPackedField_(this.decoder_.readFixedHash64);
diff --git a/js/binary/utils.js b/js/binary/utils.js
index c706bff4..55a9ccd4 100644
--- a/js/binary/utils.js
+++ b/js/binary/utils.js
@@ -431,7 +431,7 @@ jspb.utils.joinHash64 = function(bitsLow, bitsHigh) {
/**
* Individual digits for number->string conversion.
- * @const {!Array.<string>}
+ * @const {!Array<string>}
*/
jspb.utils.DIGITS = [
'0', '1', '2', '3', '4', '5', '6', '7',
@@ -554,10 +554,10 @@ jspb.utils.hash64ToDecimalString = function(hash, signed) {
/**
* Converts an array of 8-character hash strings into their decimal
* representations.
- * @param {!Array.<string>} hashes The array of hash strings to convert.
+ * @param {!Array<string>} hashes The array of hash strings to convert.
* @param {boolean} signed True if we should treat the hash string as encoding
* a signed integer.
- * @return {!Array.<string>}
+ * @return {!Array<string>}
*/
jspb.utils.hash64ArrayToDecimalStrings = function(hashes, signed) {
var result = new Array(hashes.length);
@@ -971,8 +971,12 @@ jspb.utils.byteSourceToUint8Array = function(data) {
return /** @type {!Uint8Array} */(new Uint8Array(data));
}
+ if (data.constructor === Buffer) {
+ return /** @type {!Uint8Array} */(new Uint8Array(data));
+ }
+
if (data.constructor === Array) {
- data = /** @type {!Array.<number>} */(data);
+ data = /** @type {!Array<number>} */(data);
return /** @type {!Uint8Array} */(new Uint8Array(data));
}
diff --git a/js/binary/utils_test.js b/js/binary/utils_test.js
index 6b481dce..13450644 100644
--- a/js/binary/utils_test.js
+++ b/js/binary/utils_test.js
@@ -657,7 +657,7 @@ describe('binaryUtilsTest', function() {
// Converting Uint8Arrays into Uint8Arrays should be a no-op.
assertEquals(sourceBytes, convert(sourceBytes));
- // Converting Array.<numbers> into Uint8Arrays should work.
+ // Converting Array<numbers> into Uint8Arrays should work.
check(convert(sourceData));
// Converting ArrayBuffers into Uint8Arrays should work.
diff --git a/js/binary/writer.js b/js/binary/writer.js
index 037e92b2..287d29c3 100644
--- a/js/binary/writer.js
+++ b/js/binary/writer.js
@@ -102,7 +102,7 @@ jspb.BinaryWriter = function() {
* A stack of bookmarks containing the parent blocks for each message started
* via beginSubMessage(), needed as bookkeeping for endSubMessage().
* TODO(aappleby): Deprecated, users should be calling writeMessage().
- * @private {!Array.<!Array.<number>>}
+ * @private {!Array<!Array<number>>}
*/
this.bookmarks_ = [];
};
@@ -126,7 +126,7 @@ jspb.BinaryWriter.prototype.appendUint8Array_ = function(arr) {
* Begins a new message by writing the field header and returning a bookmark
* which we will use to patch in the message length to in endDelimited_ below.
* @param {number} field
- * @return {!Array.<number>}
+ * @return {!Array<number>}
* @private
*/
jspb.BinaryWriter.prototype.beginDelimited_ = function(field) {
@@ -143,7 +143,7 @@ jspb.BinaryWriter.prototype.beginDelimited_ = function(field) {
* Ends a message by encoding the _change_ in length of the buffer to the
* parent block and adds the number of bytes needed to encode that length to
* the total byte length.
- * @param {!Array.<number>} bookmark
+ * @param {!Array<number>} bookmark
* @private
*/
jspb.BinaryWriter.prototype.endDelimited_ = function(bookmark) {
@@ -236,10 +236,12 @@ jspb.BinaryWriter.prototype.getResultBuffer = function() {
/**
* Converts the encoded data into a base64-encoded string.
+ * @param {boolean=} opt_webSafe True indicates we should use a websafe
+ * alphabet, which does not require escaping for use in URLs.
* @return {string}
*/
-jspb.BinaryWriter.prototype.getResultBase64String = function() {
- return goog.crypt.base64.encodeByteArray(this.getResultBuffer());
+jspb.BinaryWriter.prototype.getResultBase64String = function(opt_webSafe) {
+ return goog.crypt.base64.encodeByteArray(this.getResultBuffer(), opt_webSafe);
};
@@ -855,7 +857,7 @@ jspb.BinaryWriter.prototype.writeVarintHash64 = function(field, value) {
/**
* Writes an array of numbers to the buffer as a repeated 32-bit int field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedInt32 = function(field, value) {
if (value == null) return;
@@ -869,7 +871,7 @@ jspb.BinaryWriter.prototype.writeRepeatedInt32 = function(field, value) {
* Writes an array of numbers formatted as strings to the buffer as a repeated
* 32-bit int field.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of ints to write.
+ * @param {?Array<string>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedInt32String = function(field, value) {
if (value == null) return;
@@ -882,7 +884,7 @@ jspb.BinaryWriter.prototype.writeRepeatedInt32String = function(field, value) {
/**
* Writes an array of numbers to the buffer as a repeated 64-bit int field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedInt64 = function(field, value) {
if (value == null) return;
@@ -896,7 +898,7 @@ jspb.BinaryWriter.prototype.writeRepeatedInt64 = function(field, value) {
* Writes an array of numbers formatted as strings to the buffer as a repeated
* 64-bit int field.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of ints to write.
+ * @param {?Array<string>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedInt64String = function(field, value) {
if (value == null) return;
@@ -910,7 +912,7 @@ jspb.BinaryWriter.prototype.writeRepeatedInt64String = function(field, value) {
* Writes an array numbers to the buffer as a repeated unsigned 32-bit int
* field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedUint32 = function(field, value) {
if (value == null) return;
@@ -924,7 +926,7 @@ jspb.BinaryWriter.prototype.writeRepeatedUint32 = function(field, value) {
* Writes an array of numbers formatted as strings to the buffer as a repeated
* unsigned 32-bit int field.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of ints to write.
+ * @param {?Array<string>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedUint32String = function(field, value) {
if (value == null) return;
@@ -938,7 +940,7 @@ jspb.BinaryWriter.prototype.writeRepeatedUint32String = function(field, value) {
* Writes an array numbers to the buffer as a repeated unsigned 64-bit int
* field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedUint64 = function(field, value) {
if (value == null) return;
@@ -952,7 +954,7 @@ jspb.BinaryWriter.prototype.writeRepeatedUint64 = function(field, value) {
* Writes an array of numbers formatted as strings to the buffer as a repeated
* unsigned 64-bit int field.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of ints to write.
+ * @param {?Array<string>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedUint64String = function(field, value) {
if (value == null) return;
@@ -965,7 +967,7 @@ jspb.BinaryWriter.prototype.writeRepeatedUint64String = function(field, value) {
/**
* Writes an array numbers to the buffer as a repeated signed 32-bit int field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedSint32 = function(field, value) {
if (value == null) return;
@@ -978,7 +980,7 @@ jspb.BinaryWriter.prototype.writeRepeatedSint32 = function(field, value) {
/**
* Writes an array numbers to the buffer as a repeated signed 64-bit int field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedSint64 = function(field, value) {
if (value == null) return;
@@ -991,7 +993,7 @@ jspb.BinaryWriter.prototype.writeRepeatedSint64 = function(field, value) {
/**
* Writes an array numbers to the buffer as a repeated signed 64-bit int field.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of ints to write.
+ * @param {?Array<string>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedSint64String = function(field, value) {
if (value == null) return;
@@ -1005,7 +1007,7 @@ jspb.BinaryWriter.prototype.writeRepeatedSint64String = function(field, value) {
* Writes an array of numbers to the buffer as a repeated fixed32 field. This
* works for both signed and unsigned fixed32s.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedFixed32 = function(field, value) {
if (value == null) return;
@@ -1019,7 +1021,7 @@ jspb.BinaryWriter.prototype.writeRepeatedFixed32 = function(field, value) {
* Writes an array of numbers to the buffer as a repeated fixed64 field. This
* works for both signed and unsigned fixed64s.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedFixed64 = function(field, value) {
if (value == null) return;
@@ -1033,7 +1035,7 @@ jspb.BinaryWriter.prototype.writeRepeatedFixed64 = function(field, value) {
* Writes an array of numbers to the buffer as a repeated fixed64 field. This
* works for both signed and unsigned fixed64s.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of decimal strings to write.
+ * @param {?Array<string>} value The array of decimal strings to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedFixed64String = function(
field, value) {
@@ -1047,7 +1049,7 @@ jspb.BinaryWriter.prototype.writeRepeatedFixed64String = function(
/**
* Writes an array of numbers to the buffer as a repeated sfixed32 field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedSfixed32 = function(field, value) {
if (value == null) return;
@@ -1060,7 +1062,7 @@ jspb.BinaryWriter.prototype.writeRepeatedSfixed32 = function(field, value) {
/**
* Writes an array of numbers to the buffer as a repeated sfixed64 field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedSfixed64 = function(field, value) {
if (value == null) return;
@@ -1074,7 +1076,7 @@ jspb.BinaryWriter.prototype.writeRepeatedSfixed64 = function(field, value) {
* Writes an array of decimal strings to the buffer as a repeated sfixed64
* field.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of decimal strings to write.
+ * @param {?Array<string>} value The array of decimal strings to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedSfixed64String = function(field, value) {
if (value == null) return;
@@ -1087,7 +1089,7 @@ jspb.BinaryWriter.prototype.writeRepeatedSfixed64String = function(field, value)
/**
* Writes an array of numbers to the buffer as a repeated float field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedFloat = function(field, value) {
if (value == null) return;
@@ -1100,7 +1102,7 @@ jspb.BinaryWriter.prototype.writeRepeatedFloat = function(field, value) {
/**
* Writes an array of numbers to the buffer as a repeated double field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedDouble = function(field, value) {
if (value == null) return;
@@ -1113,7 +1115,7 @@ jspb.BinaryWriter.prototype.writeRepeatedDouble = function(field, value) {
/**
* Writes an array of booleans to the buffer as a repeated bool field.
* @param {number} field The field number.
- * @param {?Array.<boolean>} value The array of ints to write.
+ * @param {?Array<boolean>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedBool = function(field, value) {
if (value == null) return;
@@ -1126,7 +1128,7 @@ jspb.BinaryWriter.prototype.writeRepeatedBool = function(field, value) {
/**
* Writes an array of enums to the buffer as a repeated enum field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedEnum = function(field, value) {
if (value == null) return;
@@ -1139,7 +1141,7 @@ jspb.BinaryWriter.prototype.writeRepeatedEnum = function(field, value) {
/**
* Writes an array of strings to the buffer as a repeated string field.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of strings to write.
+ * @param {?Array<string>} value The array of strings to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedString = function(field, value) {
if (value == null) return;
@@ -1152,7 +1154,7 @@ jspb.BinaryWriter.prototype.writeRepeatedString = function(field, value) {
/**
* Writes an array of arbitrary byte fields to the buffer.
* @param {number} field The field number.
- * @param {?Array.<!jspb.ByteSource>} value The arrays of arrays of bytes to
+ * @param {?Array<!jspb.ByteSource>} value The arrays of arrays of bytes to
* write.
*/
jspb.BinaryWriter.prototype.writeRepeatedBytes = function(field, value) {
@@ -1167,7 +1169,7 @@ jspb.BinaryWriter.prototype.writeRepeatedBytes = function(field, value) {
* Writes an array of messages to the buffer.
* @template MessageType
* @param {number} field The field number.
- * @param {?Array.<MessageType>} value The array of messages to
+ * @param {?Array<MessageType>} value The array of messages to
* write.
* @param {function(MessageType, !jspb.BinaryWriter)} writerCallback
* Will be invoked with the value to write and the writer to write it with.
@@ -1187,7 +1189,7 @@ jspb.BinaryWriter.prototype.writeRepeatedMessage = function(
* Writes an array of group messages to the buffer.
* @template MessageType
* @param {number} field The field number.
- * @param {?Array.<MessageType>} value The array of messages to
+ * @param {?Array<MessageType>} value The array of messages to
* write.
* @param {function(MessageType, !jspb.BinaryWriter)} writerCallback
* Will be invoked with the value to write and the writer to write it with.
@@ -1207,7 +1209,7 @@ jspb.BinaryWriter.prototype.writeRepeatedGroup = function(
* Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
* the buffer.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of hashes to write.
+ * @param {?Array<string>} value The array of hashes to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedFixedHash64 =
function(field, value) {
@@ -1222,7 +1224,7 @@ jspb.BinaryWriter.prototype.writeRepeatedFixedHash64 =
* Writes a repeated 64-bit hash string field (8 characters @ 8 bits of data
* each) to the buffer.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of hashes to write.
+ * @param {?Array<string>} value The array of hashes to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedVarintHash64 =
function(field, value) {
@@ -1236,7 +1238,7 @@ jspb.BinaryWriter.prototype.writeRepeatedVarintHash64 =
/**
* Writes an array of numbers to the buffer as a packed 32-bit int field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedInt32 = function(field, value) {
if (value == null || !value.length) return;
@@ -1252,7 +1254,7 @@ jspb.BinaryWriter.prototype.writePackedInt32 = function(field, value) {
* Writes an array of numbers represented as strings to the buffer as a packed
* 32-bit int field.
* @param {number} field
- * @param {?Array.<string>} value
+ * @param {?Array<string>} value
*/
jspb.BinaryWriter.prototype.writePackedInt32String = function(field, value) {
if (value == null || !value.length) return;
@@ -1267,7 +1269,7 @@ jspb.BinaryWriter.prototype.writePackedInt32String = function(field, value) {
/**
* Writes an array of numbers to the buffer as a packed 64-bit int field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedInt64 = function(field, value) {
if (value == null || !value.length) return;
@@ -1283,7 +1285,7 @@ jspb.BinaryWriter.prototype.writePackedInt64 = function(field, value) {
* Writes an array of numbers represented as strings to the buffer as a packed
* 64-bit int field.
* @param {number} field
- * @param {?Array.<string>} value
+ * @param {?Array<string>} value
*/
jspb.BinaryWriter.prototype.writePackedInt64String = function(field, value) {
if (value == null || !value.length) return;
@@ -1299,7 +1301,7 @@ jspb.BinaryWriter.prototype.writePackedInt64String = function(field, value) {
/**
* Writes an array numbers to the buffer as a packed unsigned 32-bit int field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedUint32 = function(field, value) {
if (value == null || !value.length) return;
@@ -1315,7 +1317,7 @@ jspb.BinaryWriter.prototype.writePackedUint32 = function(field, value) {
* Writes an array of numbers represented as strings to the buffer as a packed
* unsigned 32-bit int field.
* @param {number} field
- * @param {?Array.<string>} value
+ * @param {?Array<string>} value
*/
jspb.BinaryWriter.prototype.writePackedUint32String =
function(field, value) {
@@ -1331,7 +1333,7 @@ jspb.BinaryWriter.prototype.writePackedUint32String =
/**
* Writes an array numbers to the buffer as a packed unsigned 64-bit int field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedUint64 = function(field, value) {
if (value == null || !value.length) return;
@@ -1347,7 +1349,7 @@ jspb.BinaryWriter.prototype.writePackedUint64 = function(field, value) {
* Writes an array of numbers represented as strings to the buffer as a packed
* unsigned 64-bit int field.
* @param {number} field
- * @param {?Array.<string>} value
+ * @param {?Array<string>} value
*/
jspb.BinaryWriter.prototype.writePackedUint64String =
function(field, value) {
@@ -1364,7 +1366,7 @@ jspb.BinaryWriter.prototype.writePackedUint64String =
/**
* Writes an array numbers to the buffer as a packed signed 32-bit int field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedSint32 = function(field, value) {
if (value == null || !value.length) return;
@@ -1379,7 +1381,7 @@ jspb.BinaryWriter.prototype.writePackedSint32 = function(field, value) {
/**
* Writes an array of numbers to the buffer as a packed signed 64-bit int field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedSint64 = function(field, value) {
if (value == null || !value.length) return;
@@ -1395,7 +1397,7 @@ jspb.BinaryWriter.prototype.writePackedSint64 = function(field, value) {
* Writes an array of decimal strings to the buffer as a packed signed 64-bit
* int field.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of decimal strings to write.
+ * @param {?Array<string>} value The array of decimal strings to write.
*/
jspb.BinaryWriter.prototype.writePackedSint64String = function(field, value) {
if (value == null || !value.length) return;
@@ -1411,7 +1413,7 @@ jspb.BinaryWriter.prototype.writePackedSint64String = function(field, value) {
/**
* Writes an array of numbers to the buffer as a packed fixed32 field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedFixed32 = function(field, value) {
if (value == null || !value.length) return;
@@ -1426,7 +1428,7 @@ jspb.BinaryWriter.prototype.writePackedFixed32 = function(field, value) {
/**
* Writes an array of numbers to the buffer as a packed fixed64 field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedFixed64 = function(field, value) {
if (value == null || !value.length) return;
@@ -1442,7 +1444,7 @@ jspb.BinaryWriter.prototype.writePackedFixed64 = function(field, value) {
* Writes an array of numbers represented as strings to the buffer as a packed
* fixed64 field.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of strings to write.
+ * @param {?Array<string>} value The array of strings to write.
*/
jspb.BinaryWriter.prototype.writePackedFixed64String = function(field, value) {
if (value == null || !value.length) return;
@@ -1458,7 +1460,7 @@ jspb.BinaryWriter.prototype.writePackedFixed64String = function(field, value) {
/**
* Writes an array of numbers to the buffer as a packed sfixed32 field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedSfixed32 = function(field, value) {
if (value == null || !value.length) return;
@@ -1473,7 +1475,7 @@ jspb.BinaryWriter.prototype.writePackedSfixed32 = function(field, value) {
/**
* Writes an array of numbers to the buffer as a packed sfixed64 field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedSfixed64 = function(field, value) {
if (value == null || !value.length) return;
@@ -1488,7 +1490,7 @@ jspb.BinaryWriter.prototype.writePackedSfixed64 = function(field, value) {
/**
* Writes an array of numbers to the buffer as a packed sfixed64 field.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of decimal strings to write.
+ * @param {?Array<string>} value The array of decimal strings to write.
*/
jspb.BinaryWriter.prototype.writePackedSfixed64String = function(field, value) {
if (value == null || !value.length) return;
@@ -1503,7 +1505,7 @@ jspb.BinaryWriter.prototype.writePackedSfixed64String = function(field, value) {
/**
* Writes an array of numbers to the buffer as a packed float field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedFloat = function(field, value) {
if (value == null || !value.length) return;
@@ -1518,7 +1520,7 @@ jspb.BinaryWriter.prototype.writePackedFloat = function(field, value) {
/**
* Writes an array of numbers to the buffer as a packed double field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedDouble = function(field, value) {
if (value == null || !value.length) return;
@@ -1533,7 +1535,7 @@ jspb.BinaryWriter.prototype.writePackedDouble = function(field, value) {
/**
* Writes an array of booleans to the buffer as a packed bool field.
* @param {number} field The field number.
- * @param {?Array.<boolean>} value The array of ints to write.
+ * @param {?Array<boolean>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedBool = function(field, value) {
if (value == null || !value.length) return;
@@ -1548,7 +1550,7 @@ jspb.BinaryWriter.prototype.writePackedBool = function(field, value) {
/**
* Writes an array of enums to the buffer as a packed enum field.
* @param {number} field The field number.
- * @param {?Array.<number>} value The array of ints to write.
+ * @param {?Array<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writePackedEnum = function(field, value) {
if (value == null || !value.length) return;
@@ -1564,7 +1566,7 @@ jspb.BinaryWriter.prototype.writePackedEnum = function(field, value) {
* Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
* the buffer.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of hashes to write.
+ * @param {?Array<string>} value The array of hashes to write.
*/
jspb.BinaryWriter.prototype.writePackedFixedHash64 = function(field, value) {
if (value == null || !value.length) return;
@@ -1580,7 +1582,7 @@ jspb.BinaryWriter.prototype.writePackedFixedHash64 = function(field, value) {
* Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
* the buffer.
* @param {number} field The field number.
- * @param {?Array.<string>} value The array of hashes to write.
+ * @param {?Array<string>} value The array of hashes to write.
*/
jspb.BinaryWriter.prototype.writePackedVarintHash64 = function(field, value) {
if (value == null || !value.length) return;
diff --git a/js/binary/writer_test.js b/js/binary/writer_test.js
index 118eecfc..8a9a1bb0 100644
--- a/js/binary/writer_test.js
+++ b/js/binary/writer_test.js
@@ -118,4 +118,16 @@ describe('binaryWriterTest', function() {
var buffer = writer.getResultBuffer();
assertEquals(expected, goog.crypt.byteArrayToHex(buffer));
});
+
+
+ /**
+ * Tests websafe encodings for base64 strings.
+ */
+ it('testWebSafeOption', function() {
+ var writer = new jspb.BinaryWriter();
+ writer.writeBytes(1, new Uint8Array([127]));
+ assertEquals('CgF/', writer.getResultBase64String());
+ assertEquals('CgF/', writer.getResultBase64String(false));
+ assertEquals('CgF_', writer.getResultBase64String(true));
+ });
});
diff --git a/js/commonjs/export_testdeps.js b/js/commonjs/export_testdeps.js
index 6f5cd083..96d3f347 100644
--- a/js/commonjs/export_testdeps.js
+++ b/js/commonjs/export_testdeps.js
@@ -12,6 +12,7 @@
goog.provide('jspb.ExportTestDeps');
goog.require('goog.crypt.base64');
+goog.require('goog.testing.PropertyReplacer');
goog.require('jspb.arith.Int64');
goog.require('jspb.arith.UInt64');
goog.require('jspb.BinaryEncoder');
diff --git a/js/debug.js b/js/debug.js
index 46b24853..ba51bbe0 100644
--- a/js/debug.js
+++ b/js/debug.js
@@ -42,7 +42,7 @@ goog.require('jspb.Message');
/**
* Turns a proto into a human readable object that can i.e. be written to the
- * console: {@code console.log(jspb.debug.dump(myProto))}.
+ * console: `console.log(jspb.debug.dump(myProto))`.
* This function makes a best effort and may not work in all cases. It will not
* work in obfuscated and or optimized code.
* Use this in environments where {@see jspb.Message.prototype.toObject} is
@@ -74,15 +74,22 @@ jspb.debug.dump = function(message) {
*/
jspb.debug.dump_ = function(thing) {
var type = goog.typeOf(thing);
+ var message = thing; // Copy because we don't want type inference on thing.
if (type == 'number' || type == 'string' || type == 'boolean' ||
type == 'null' || type == 'undefined') {
return thing;
}
+ if (typeof Uint8Array !== 'undefined') {
+ // Will fail on IE9, where Uint8Array doesn't exist.
+ if (message instanceof Uint8Array) {
+ return thing;
+ }
+ }
+
if (type == 'array') {
goog.asserts.assertArray(thing);
return goog.array.map(thing, jspb.debug.dump_);
}
- var message = thing; // Copy because we don't want type inference on thing.
goog.asserts.assert(message instanceof jspb.Message,
'Only messages expected: ' + thing);
var ctor = message.constructor;
diff --git a/js/debug_test.js b/js/debug_test.js
index 702cc76e..d0d646a5 100644
--- a/js/debug_test.js
+++ b/js/debug_test.js
@@ -41,6 +41,8 @@ goog.require('proto.jspb.test.IsExtension');
goog.require('proto.jspb.test.Simple1');
+// CommonJS-LoadFromFile: testbinary_pb
+goog.require('proto.jspb.test.TestAllTypes');
describe('debugTest', function() {
it('testSimple1', function() {
@@ -74,6 +76,15 @@ describe('debugTest', function() {
}, jspb.debug.dump(message));
});
+ it('testBytes', function() {
+ if (COMPILED || typeof Uint8Array == 'undefined') {
+ return;
+ }
+ var message = new proto.jspb.test.TestAllTypes();
+ var bytes = new Uint8Array(4);
+ message.setOptionalBytes(bytes);
+ assertEquals(jspb.debug.dump(message)['optionalBytes'], bytes);
+ });
it('testExtensions', function() {
if (COMPILED) {
diff --git a/js/map.js b/js/map.js
index d423499f..2fb14837 100644
--- a/js/map.js
+++ b/js/map.js
@@ -48,9 +48,9 @@ goog.forwardDeclare('jspb.BinaryWriter');
*
* @template K, V
*
- * @param {!Array<!Array<!Object>>} arr
+ * @param {!Array<!Array<?>>} arr
*
- * @param {?function(new:V)|function(new:V,?)=} opt_valueCtor
+ * @param {?function(new:V, ?=)=} opt_valueCtor
* The constructor for type V, if type V is a message type.
*
* @constructor
@@ -118,7 +118,7 @@ jspb.Map.prototype.toArray = function() {
strKeys.sort();
for (var i = 0; i < strKeys.length; i++) {
var entry = this.map_[strKeys[i]];
- var valueWrapper = /** @type {!Object} */ (entry.valueWrapper);
+ var valueWrapper = /** @type {?jspb.Message} */ (entry.valueWrapper);
if (valueWrapper) {
valueWrapper.toArray();
}
@@ -165,7 +165,7 @@ jspb.Map.prototype.toObject = function(includeInstance, valueToObject) {
*
* @template K, V
* @param {!Array<!Array<!Object>>} entries
- * @param {!function(new:V)|function(new:V,?)} valueCtor
+ * @param {!function(new:V,?=)} valueCtor
* The constructor for type V.
* @param {!function(!Object):V} valueFromObject
* The fromObject function for type V.
@@ -432,7 +432,8 @@ jspb.Map.prototype.serializeBinary = function(
valueWriterFn.call(writer, 2, this.wrapEntry_(entry),
opt_valueWriterCallback);
} else {
- valueWriterFn.call(writer, 2, entry.value);
+ /** @type {function(this:jspb.BinaryWriter,number,?)} */ (valueWriterFn)
+ .call(writer, 2, entry.value);
}
writer.endSubMessage();
}
@@ -442,7 +443,8 @@ jspb.Map.prototype.serializeBinary = function(
/**
* 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.
+ * when a key/value pair submessage is encountered. If the Key is undefined,
+ * we should default it to 0.
* @template K, V
* @param {!jspb.Map} map
* @param {!jspb.BinaryReader} reader
@@ -456,12 +458,17 @@ jspb.Map.prototype.serializeBinary = function(
* 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.
+ * The BinaryReader parsing callback for type V, if V is a message type
+ *
+ * @param {K=} opt_defaultKey
+ * The default value for the type of map keys. Accepting map
+ * entries with unset keys is required for maps to be backwards compatible
+ * with the repeated message representation described here: goo.gl/zuoLAC
*
*/
jspb.Map.deserializeBinary = function(map, reader, keyReaderFn, valueReaderFn,
- opt_valueReaderCallback) {
- var key = undefined;
+ opt_valueReaderCallback, opt_defaultKey) {
+ var key = opt_defaultKey;
var value = undefined;
while (reader.nextField()) {
@@ -469,16 +476,20 @@ jspb.Map.deserializeBinary = function(map, reader, keyReaderFn, valueReaderFn,
break;
}
var field = reader.getFieldNumber();
+
if (field == 1) {
// Key.
key = keyReaderFn.call(reader);
} else if (field == 2) {
// Value.
if (map.valueCtor_) {
+ goog.asserts.assert(opt_valueReaderCallback);
value = new map.valueCtor_();
valueReaderFn.call(reader, value, opt_valueReaderCallback);
} else {
- value = valueReaderFn.call(reader);
+ value =
+ (/** @type {function(this:jspb.BinaryReader):?} */ (valueReaderFn))
+ .call(reader);
}
}
}
diff --git a/js/maps_test.js b/js/maps_test.js
index e8dd2f21..e496f446 100755
--- a/js/maps_test.js
+++ b/js/maps_test.js
@@ -35,6 +35,11 @@ goog.require('goog.userAgent');
goog.require('proto.jspb.test.MapValueEnum');
goog.require('proto.jspb.test.MapValueMessage');
goog.require('proto.jspb.test.TestMapFields');
+goog.require('proto.jspb.test.TestMapFieldsOptionalKeys');
+goog.require('proto.jspb.test.MapEntryOptionalKeysStringKey');
+goog.require('proto.jspb.test.MapEntryOptionalKeysInt32Key');
+goog.require('proto.jspb.test.MapEntryOptionalKeysInt64Key');
+goog.require('proto.jspb.test.MapEntryOptionalKeysBoolKey');
// CommonJS-LoadFromFile: test_pb proto.jspb.test
goog.require('proto.jspb.test.MapValueMessageNoBinary');
@@ -76,7 +81,7 @@ function toArray(iter) {
* Helper: generate test methods for this TestMapFields class.
* @param {?} msgInfo
* @param {?} submessageCtor
- * @param {!string} suffix
+ * @param {string} suffix
*/
function makeTests(msgInfo, submessageCtor, suffix) {
/**
@@ -260,6 +265,39 @@ function makeTests(msgInfo, submessageCtor, suffix) {
var decoded = msgInfo.deserializeBinary(serialized);
checkMapFields(decoded);
});
+ /**
+ * Tests deserialization of undefined map keys go to default values in binary format.
+ */
+ it('testMapDeserializationForUndefinedKeys', function() {
+ var testMessageOptionalKeys = new proto.jspb.test.TestMapFieldsOptionalKeys();
+ var mapEntryStringKey = new proto.jspb.test.MapEntryOptionalKeysStringKey();
+ mapEntryStringKey.setValue("a");
+ testMessageOptionalKeys.setMapStringString(mapEntryStringKey);
+ var mapEntryInt32Key = new proto.jspb.test.MapEntryOptionalKeysInt32Key();
+ mapEntryInt32Key.setValue("b");
+ testMessageOptionalKeys.setMapInt32String(mapEntryInt32Key);
+ var mapEntryInt64Key = new proto.jspb.test.MapEntryOptionalKeysInt64Key();
+ mapEntryInt64Key.setValue("c");
+ testMessageOptionalKeys.setMapInt64String(mapEntryInt64Key);
+ var mapEntryBoolKey = new proto.jspb.test.MapEntryOptionalKeysBoolKey();
+ mapEntryBoolKey.setValue("d");
+ testMessageOptionalKeys.setMapBoolString(mapEntryBoolKey);
+ var deserializedMessage = msgInfo.deserializeBinary(
+ testMessageOptionalKeys.serializeBinary()
+ );
+ checkMapEquals(deserializedMessage.getMapStringStringMap(), [
+ ['', 'a']
+ ]);
+ checkMapEquals(deserializedMessage.getMapInt32StringMap(), [
+ [0, 'b']
+ ]);
+ checkMapEquals(deserializedMessage.getMapInt64StringMap(), [
+ [0, 'c']
+ ]);
+ checkMapEquals(deserializedMessage.getMapBoolStringMap(), [
+ [false, 'd']
+ ]);
+ });
}
diff --git a/js/message.js b/js/message.js
index 1484229d..86d18295 100644
--- a/js/message.js
+++ b/js/message.js
@@ -205,15 +205,14 @@ goog.define('jspb.Message.GENERATE_TO_STRING', true);
goog.define('jspb.Message.ASSUME_LOCAL_ARRAYS', false);
+// TODO(jakubvrana): Turn this off by default.
/**
- * @define {boolean} Turning on this flag does NOT change the behavior of JSPB
- * and only affects private internal state. It may, however, break some
- * tests that use naive deeply-equals algorithms, because using a proto
- * mutates its internal state.
- * Projects are advised to turn this flag always on.
+ * @define {boolean} Disabling the serialization of empty trailing fields
+ * reduces the size of serialized protos. The price is an extra iteration of
+ * the proto before serialization. This is enabled by default to be
+ * backwards compatible. Projects are advised to turn this flag always off.
*/
-goog.define('jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS', COMPILED);
-// TODO(b/19419436) Turn this on by default.
+goog.define('jspb.Message.SERIALIZE_EMPTY_TRAILING_FIELDS', true);
/**
@@ -278,6 +277,13 @@ jspb.Message.prototype.convertedFloatingPointFields_;
/**
+ * Repeated fields numbers.
+ * @protected {?Array<number>|undefined}
+ */
+jspb.Message.prototype.repeatedFields;
+
+
+/**
* The xid of this proto type (The same for all instances of a proto). Provides
* a way to identify a proto by stable obfuscated name.
* @see {xid}.
@@ -324,6 +330,18 @@ jspb.Message.getIndex_ = function(msg, fieldNumber) {
/**
+ * Returns the tag number based on the index in msg.array.
+ * @param {!jspb.Message} msg Message for which we're calculating an index.
+ * @param {number} index The tag number.
+ * @return {number} The field number.
+ * @private
+ */
+jspb.Message.getFieldNumber_ = function(msg, index) {
+ return index - msg.arrayIndexOffset_;
+};
+
+
+/**
* Initializes a JsPb Message.
* @param {!jspb.Message} msg The JsPb proto to modify.
* @param {Array|undefined} data An initial data array.
@@ -340,7 +358,7 @@ jspb.Message.getIndex_ = function(msg, fieldNumber) {
*/
jspb.Message.initialize = function(
msg, data, messageId, suggestedPivot, repeatedFields, opt_oneofFields) {
- msg.wrappers_ = jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ? null : {};
+ msg.wrappers_ = null;
if (!data) {
data = messageId ? [messageId] : [];
}
@@ -353,22 +371,24 @@ jspb.Message.initialize = function(
jspb.Message.initPivotAndExtensionObject_(msg, suggestedPivot);
msg.convertedFloatingPointFields_ = {};
+ if (!jspb.Message.SERIALIZE_EMPTY_TRAILING_FIELDS) {
+ // TODO(jakubvrana): This is same for all instances, move to prototype.
+ // TODO(jakubvrana): There are indexOf calls on this in serializtion,
+ // consider switching to a set.
+ msg.repeatedFields = repeatedFields;
+ }
+
if (repeatedFields) {
for (var i = 0; i < repeatedFields.length; i++) {
var fieldNumber = repeatedFields[i];
if (fieldNumber < msg.pivot_) {
var index = jspb.Message.getIndex_(msg, fieldNumber);
- msg.array[index] = msg.array[index] ||
- (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ?
- jspb.Message.EMPTY_LIST_SENTINEL_ :
- []);
+ msg.array[index] =
+ msg.array[index] || jspb.Message.EMPTY_LIST_SENTINEL_;
} else {
jspb.Message.maybeInitEmptyExtensionObject_(msg);
- msg.extensionObject_[fieldNumber] =
- msg.extensionObject_[fieldNumber] ||
- (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ?
- jspb.Message.EMPTY_LIST_SENTINEL_ :
- []);
+ msg.extensionObject_[fieldNumber] = msg.extensionObject_[fieldNumber] ||
+ jspb.Message.EMPTY_LIST_SENTINEL_;
}
}
}
@@ -376,8 +396,9 @@ jspb.Message.initialize = function(
if (opt_oneofFields && opt_oneofFields.length) {
// Compute the oneof case for each union. This ensures only one value is
// set in the union.
- goog.array.forEach(
- opt_oneofFields, goog.partial(jspb.Message.computeOneofCase, msg));
+ for (var i = 0; i < opt_oneofFields.length; i++) {
+ jspb.Message.computeOneofCase(msg, opt_oneofFields[i]);
+ }
}
};
@@ -428,7 +449,7 @@ jspb.Message.initPivotAndExtensionObject_ = function(msg, suggestedPivot) {
// in Safari on iOS 8. See the description of CL/86511464 for details.
if (obj && typeof obj == 'object' && !jspb.Message.isArray_(obj) &&
!(jspb.Message.SUPPORTS_UINT8ARRAY_ && obj instanceof Uint8Array)) {
- msg.pivot_ = foundIndex - msg.arrayIndexOffset_;
+ msg.pivot_ = jspb.Message.getFieldNumber_(msg, foundIndex);
msg.extensionObject_ = obj;
return;
}
@@ -480,8 +501,7 @@ jspb.Message.toObjectList = function(field, toObjectFn, opt_includeInstance) {
// And not using it here to avoid a function call.
var result = [];
for (var i = 0; i < field.length; i++) {
- result[i] = toObjectFn.call(field[i], opt_includeInstance,
- /** @type {!jspb.Message} */ (field[i]));
+ result[i] = toObjectFn.call(field[i], opt_includeInstance, field[i]);
}
return result;
};
@@ -514,10 +534,11 @@ jspb.Message.toObjectExtension = function(proto, obj, extensions,
} else {
if (fieldInfo.isRepeated) {
obj[name] = jspb.Message.toObjectList(
- /** @type {!Array<jspb.Message>} */ (value),
+ /** @type {!Array<!jspb.Message>} */ (value),
fieldInfo.toObjectFn, opt_includeInstance);
} else {
- obj[name] = fieldInfo.toObjectFn(opt_includeInstance, value);
+ obj[name] = fieldInfo.toObjectFn(
+ opt_includeInstance, /** @type {!jspb.Message} */ (value));
}
}
}
@@ -902,6 +923,17 @@ jspb.Message.setProto3IntField = function(msg, fieldNumber, value) {
/**
+ * Sets the value of a non-extension integer, handled as string, field of a proto3
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @param {number} value New value
+ * @protected
+ */
+jspb.Message.setProto3StringIntField = function(msg, fieldNumber, value) {
+ jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, '0');
+};
+
+/**
* Sets the value of a non-extension floating point field of a proto3
* @param {!jspb.Message} msg A jspb proto.
* @param {number} fieldNumber The field number.
@@ -1043,14 +1075,15 @@ jspb.Message.computeOneofCase = function(msg, oneof) {
var oneofField;
var oneofValue;
- goog.array.forEach(oneof, function(fieldNumber) {
+ for (var i = 0; i < oneof.length; i++) {
+ var fieldNumber = oneof[i];
var value = jspb.Message.getField(msg, fieldNumber);
- if (goog.isDefAndNotNull(value)) {
+ if (value != null) {
oneofField = fieldNumber;
oneofValue = value;
jspb.Message.setField(msg, fieldNumber, undefined);
}
- });
+ }
if (oneofField) {
// NB: We know the value is unique, so we can call jspb.Message.setField
@@ -1241,7 +1274,7 @@ jspb.Message.addToRepeatedWrapperField = function(
* dead code removal.
* @param {boolean=} opt_includeInstance Whether to include the JSPB instance
* for transitional soy proto support: http://goto/soy-param-migration
- * @return {!Object.<string, Object>} A map of proto or Soy objects.
+ * @return {!Object<string, Object>} A map of proto or Soy objects.
* @template T
*/
jspb.Message.toMap = function(
@@ -1318,7 +1351,7 @@ jspb.Message.prototype.toString = function() {
/**
* Gets the value of the extension field from the extended object.
- * @param {jspb.ExtensionFieldInfo.<T>} fieldInfo Specifies the field to get.
+ * @param {jspb.ExtensionFieldInfo<T>} fieldInfo Specifies the field to get.
* @return {T} The value of the field.
* @template T
*/
@@ -1381,7 +1414,7 @@ jspb.Message.prototype.setExtension = function(fieldInfo, value) {
if (fieldInfo.isMessageType()) {
self.wrappers_[fieldNumber] = value;
self.extensionObject_[fieldNumber] = goog.array.map(
- /** @type {Array<jspb.Message>} */ (value), function(msg) {
+ /** @type {!Array<!jspb.Message>} */ (value), function(msg) {
return msg.toArray();
});
} else {
@@ -1390,7 +1423,8 @@ jspb.Message.prototype.setExtension = function(fieldInfo, value) {
} else {
if (fieldInfo.isMessageType()) {
self.wrappers_[fieldNumber] = value;
- self.extensionObject_[fieldNumber] = value ? value.toArray() : value;
+ self.extensionObject_[fieldNumber] =
+ value ? /** @type {!jspb.Message} */ (value).toArray() : value;
} else {
self.extensionObject_[fieldNumber] = value;
}
@@ -1492,9 +1526,15 @@ jspb.Message.compareFields = function(field1, field2) {
// If the fields are trivially equal, they're equal.
if (field1 == field2) return true;
- // If the fields aren't trivially equal and one of them isn't an object,
- // they can't possibly be equal.
if (!goog.isObject(field1) || !goog.isObject(field2)) {
+ // NaN != NaN so we cover this case.
+ if ((goog.isNumber(field1) && isNaN(field1)) ||
+ (goog.isNumber(field2) && isNaN(field2))) {
+ // One of the fields might be a string 'NaN'.
+ return String(field1) == String(field2);
+ }
+ // If the fields aren't trivially equal and one of them isn't an object,
+ // they can't possibly be equal.
return false;
}
@@ -1517,24 +1557,26 @@ jspb.Message.compareFields = function(field1, field2) {
// If they're both Arrays, compare them element by element except for the
// optional extension objects at the end, which we compare separately.
if (field1.constructor === Array) {
+ var typedField1 = /** @type {!Array<?>} */ (field1);
+ var typedField2 = /** @type {!Array<?>} */ (field2);
var extension1 = undefined;
var extension2 = undefined;
- var length = Math.max(field1.length, field2.length);
+ var length = Math.max(typedField1.length, typedField2.length);
for (var i = 0; i < length; i++) {
- var val1 = field1[i];
- var val2 = field2[i];
+ var val1 = typedField1[i];
+ var val2 = typedField2[i];
if (val1 && (val1.constructor == Object)) {
goog.asserts.assert(extension1 === undefined);
- goog.asserts.assert(i === field1.length - 1);
+ goog.asserts.assert(i === typedField1.length - 1);
extension1 = val1;
val1 = undefined;
}
if (val2 && (val2.constructor == Object)) {
goog.asserts.assert(extension2 === undefined);
- goog.asserts.assert(i === field2.length - 1);
+ goog.asserts.assert(i === typedField2.length - 1);
extension2 = val2;
val2 = undefined;
}
@@ -1657,8 +1699,13 @@ jspb.Message.clone_ = function(obj) {
var clonedArray = new Array(obj.length);
// Use array iteration where possible because it is faster than for-in.
for (var i = 0; i < obj.length; i++) {
- if ((o = obj[i]) != null) {
- clonedArray[i] = typeof o == 'object' ? jspb.Message.clone_(o) : o;
+ o = obj[i];
+ if (o != null) {
+ // NOTE:redundant null check existing for NTI compatibility.
+ // see b/70515949
+ clonedArray[i] = (typeof o == 'object') ?
+ jspb.Message.clone_(goog.asserts.assert(o)) :
+ o;
}
}
return clonedArray;
@@ -1668,8 +1715,13 @@ jspb.Message.clone_ = function(obj) {
}
var clone = {};
for (var key in obj) {
- if ((o = obj[key]) != null) {
- clone[key] = typeof o == 'object' ? jspb.Message.clone_(o) : o;
+ o = obj[key];
+ if (o != null) {
+ // NOTE:redundant null check existing for NTI compatibility.
+ // see b/70515949
+ clone[key] = (typeof o == 'object') ?
+ jspb.Message.clone_(goog.asserts.assert(o)) :
+ o;
}
}
return clone;
@@ -1685,6 +1737,9 @@ jspb.Message.registerMessageType = function(id, constructor) {
jspb.Message.registry_[id] = constructor;
// This is needed so we can later access messageId directly on the contructor,
// otherwise it is not available due to 'property collapsing' by the compiler.
+ /**
+ * @suppress {strictMissingProperties} messageId is not defined on Function
+ */
constructor.messageId = id;
};
@@ -1705,7 +1760,11 @@ jspb.Message.registry_ = {};
* non-MessageSet. We special case MessageSet so that we do not need
* to goog.require MessageSet from classes that extends MessageSet.
*
- * @type {!Object.<number, jspb.ExtensionFieldInfo>}
+ * @type {!Object<number, jspb.ExtensionFieldInfo>}
*/
jspb.Message.messageSetExtensions = {};
+
+/**
+ * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
+ */
jspb.Message.messageSetExtensionsBinary = {};
diff --git a/js/message_test.js b/js/message_test.js
index 7d61dacb..1be41093 100644
--- a/js/message_test.js
+++ b/js/message_test.js
@@ -34,6 +34,7 @@ goog.setTestOnly();
goog.require('goog.json');
goog.require('goog.string');
+goog.require('goog.testing.PropertyReplacer');
goog.require('goog.testing.asserts');
goog.require('goog.userAgent');
@@ -85,6 +86,16 @@ goog.require('proto.jspb.test.TestExtensionsMessage');
describe('Message test suite', function() {
+ var stubs = new goog.testing.PropertyReplacer();
+
+ beforeEach(function() {
+ stubs.set(jspb.Message, 'SERIALIZE_EMPTY_TRAILING_FIELDS', false);
+ });
+
+ afterEach(function() {
+ stubs.reset();
+ });
+
it('testEmptyProto', function() {
var empty1 = new proto.jspb.test.Empty([]);
var empty2 = new proto.jspb.test.Empty([]);
@@ -407,6 +418,18 @@ describe('Message test suite', function() {
['hi',,, {100: [{200: 'a'}]}], ['hi', {100: [{200: 'a'}]}]));
});
+ it('testEqualsNonFinite', function() {
+ assertTrue(jspb.Message.compareFields(NaN, NaN));
+ assertTrue(jspb.Message.compareFields(NaN, 'NaN'));
+ assertTrue(jspb.Message.compareFields('NaN', NaN));
+ assertTrue(jspb.Message.compareFields(Infinity, Infinity));
+ assertTrue(jspb.Message.compareFields(Infinity, 'Infinity'));
+ assertTrue(jspb.Message.compareFields('-Infinity', -Infinity));
+ assertTrue(jspb.Message.compareFields([NaN], ['NaN']));
+ assertFalse(jspb.Message.compareFields(undefined, NaN));
+ assertFalse(jspb.Message.compareFields(NaN, undefined));
+ });
+
it('testToMap', function() {
var p1 = new proto.jspb.test.Simple1(['k', ['v']]);
var p2 = new proto.jspb.test.Simple1(['k1', ['v1', 'v2']]);
diff --git a/js/package.json b/js/package.json
index 5231c846..325f2dcc 100644
--- a/js/package.json
+++ b/js/package.json
@@ -1,6 +1,6 @@
{
"name": "google-protobuf",
- "version": "3.4.1",
+ "version": "3.6.0",
"description": "Protocol Buffers for JavaScript",
"main": "google-protobuf.js",
"files": [
diff --git a/js/testbinary.proto b/js/testbinary.proto
index 116f17fb..ed5bdfc6 100644
--- a/js/testbinary.proto
+++ b/js/testbinary.proto
@@ -201,6 +201,38 @@ message TestMapFields {
map<string, TestMapFields> map_string_testmapfields = 12;
}
+// These proto are 'mock map' entries to test the above map deserializing with
+// undefined keys. Make sure TestMapFieldsOptionalKeys is written to be
+// deserialized by TestMapFields
+message MapEntryOptionalKeysStringKey {
+ optional string key = 1;
+ optional string value = 2;
+}
+
+message MapEntryOptionalKeysInt32Key {
+ optional int32 key = 1;
+ optional string value = 2;
+}
+
+message MapEntryOptionalKeysInt64Key {
+ optional int64 key = 1;
+ optional string value = 2;
+}
+
+message MapEntryOptionalKeysBoolKey {
+ optional bool key = 1;
+ optional string value = 2;
+}
+
+message TestMapFieldsOptionalKeys {
+ optional MapEntryOptionalKeysStringKey map_string_string = 1;
+ optional MapEntryOptionalKeysInt32Key map_int32_string= 8;
+ optional MapEntryOptionalKeysInt64Key map_int64_string = 9;
+ optional MapEntryOptionalKeysBoolKey map_bool_string = 10;
+}
+
+// End mock-map entries
+
enum MapValueEnum {
MAP_VALUE_FOO = 0;
MAP_VALUE_BAR = 1;