// 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.

/**
 * @fileoverview Test cases for jspb's binary protocol buffer reader.
 *
 * There are two particular magic numbers that need to be pointed out -
 * 2^64-1025 is the largest number representable as both a double and an
 * unsigned 64-bit integer, and 2^63-513 is the largest number representable as
 * both a double and a signed 64-bit integer.
 *
 * Test suite is written using Jasmine -- see http://jasmine.github.io/
 *
 * @author aappleby@google.com (Austin Appleby)
 */

goog.require('goog.testing.asserts');
goog.require('jspb.BinaryConstants');
goog.require('jspb.BinaryDecoder');
goog.require('jspb.BinaryReader');
goog.require('jspb.BinaryWriter');



describe('binaryReaderTest', function() {
  /**
   * Tests the reader instance cache.
   */
  it('testInstanceCaches', /** @suppress {visibility} */ function() {
    var writer = new jspb.BinaryWriter();
    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
    writer.writeMessage(1, dummyMessage, goog.nullFunction);
    writer.writeMessage(2, dummyMessage, goog.nullFunction);

    var buffer = writer.getResultBuffer();

    // Empty the instance caches.
    jspb.BinaryReader.instanceCache_ = [];

    // Allocating and then freeing three decoders should leave us with three in
    // the cache.

    var decoder1 = jspb.BinaryDecoder.alloc();
    var decoder2 = jspb.BinaryDecoder.alloc();
    var decoder3 = jspb.BinaryDecoder.alloc();
    decoder1.free();
    decoder2.free();
    decoder3.free();

    assertEquals(3, jspb.BinaryDecoder.instanceCache_.length);
    assertEquals(0, jspb.BinaryReader.instanceCache_.length);

    // Allocating and then freeing a reader should remove one decoder from its
    // cache, but it should stay stuck to the reader afterwards since we can't
    // have a reader without a decoder.
    jspb.BinaryReader.alloc().free();

    assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
    assertEquals(1, jspb.BinaryReader.instanceCache_.length);

    // Allocating a reader should remove a reader from the cache.
    var reader = jspb.BinaryReader.alloc(buffer);

    assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
    assertEquals(0, jspb.BinaryReader.instanceCache_.length);

    // Processing the message reuses the current reader.
    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    reader.readMessage(dummyMessage, function() {
      assertEquals(0, jspb.BinaryReader.instanceCache_.length);
    });

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    reader.readMessage(dummyMessage, function() {
      assertEquals(0, jspb.BinaryReader.instanceCache_.length);
    });

    assertEquals(false, reader.nextField());

    assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
    assertEquals(0, jspb.BinaryReader.instanceCache_.length);

    // Freeing the reader should put it back into the cache.
    reader.free();

    assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
    assertEquals(1, jspb.BinaryReader.instanceCache_.length);
  });


  /**
   * @param {number} x
   * @return {number}
   */
  function truncate(x) {
    var temp = new Float32Array(1);
    temp[0] = x;
    return temp[0];
  }


  /**
   * Verifies that misuse of the reader class triggers assertions.
   */
  it('testReadErrors', /** @suppress {checkTypes|visibility} */ function() {
    // Calling readMessage on a non-delimited field should trigger an
    // assertion.
    var reader = jspb.BinaryReader.alloc([8, 1]);
    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
    reader.nextField();
    assertThrows(function() {
      reader.readMessage(dummyMessage, goog.nullFunction);
    });

    // Reading past the end of the stream should trigger an assertion.
    reader = jspb.BinaryReader.alloc([9, 1]);
    reader.nextField();
    assertThrows(function() {reader.readFixed64()});

    // Reading past the end of a submessage should trigger an assertion.
    reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]);
    reader.nextField();
    reader.readMessage(dummyMessage, function() {
      reader.nextField();
      assertThrows(function() {reader.readFixed32()});
    });

    // Skipping an invalid field should trigger an assertion.
    reader = jspb.BinaryReader.alloc([12, 1]);
    reader.nextWireType_ = 1000;
    assertThrows(function() {reader.skipField()});

    // Reading fields with the wrong wire type should assert.
    reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]);
    reader.nextField();
    assertThrows(function() {reader.readInt32()});
    assertThrows(function() {reader.readInt32String()});
    assertThrows(function() {reader.readInt64()});
    assertThrows(function() {reader.readInt64String()});
    assertThrows(function() {reader.readUint32()});
    assertThrows(function() {reader.readUint32String()});
    assertThrows(function() {reader.readUint64()});
    assertThrows(function() {reader.readUint64String()});
    assertThrows(function() {reader.readSint32()});
    assertThrows(function() {reader.readBool()});
    assertThrows(function() {reader.readEnum()});

    reader = jspb.BinaryReader.alloc([8, 1]);
    reader.nextField();
    assertThrows(function() {reader.readFixed32()});
    assertThrows(function() {reader.readFixed64()});
    assertThrows(function() {reader.readSfixed32()});
    assertThrows(function() {reader.readSfixed64()});
    assertThrows(function() {reader.readFloat()});
    assertThrows(function() {reader.readDouble()});

    assertThrows(function() {reader.readString()});
    assertThrows(function() {reader.readBytes()});
  });


  /**
   * Tests encoding and decoding of unsigned field types.
   * @param {Function} readField
   * @param {Function} writeField
   * @param {number} epsilon
   * @param {number} upperLimit
   * @param {Function} filter
   * @private
   * @suppress {missingProperties}
   */
  var doTestUnsignedField_ = function(readField,
      writeField, epsilon, upperLimit, filter) {
    assertNotNull(readField);
    assertNotNull(writeField);

    var writer = new jspb.BinaryWriter();

    // Encode zero and limits.
    writeField.call(writer, 1, filter(0));
    writeField.call(writer, 2, filter(epsilon));
    writeField.call(writer, 3, filter(upperLimit));

    // Encode positive values.
    for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
      writeField.call(writer, 4, filter(cursor));
    }

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    // Check zero and limits.
    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    assertEquals(filter(0), readField.call(reader));

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    assertEquals(filter(epsilon), readField.call(reader));

    reader.nextField();
    assertEquals(3, reader.getFieldNumber());
    assertEquals(filter(upperLimit), readField.call(reader));

    // Check positive values.
    for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
      reader.nextField();
      if (4 != reader.getFieldNumber()) throw 'fail!';
      if (filter(cursor) != readField.call(reader)) throw 'fail!';
    }
  };


  /**
   * Tests encoding and decoding of signed field types.
   * @param {Function} readField
   * @param {Function} writeField
   * @param {number} epsilon
   * @param {number} lowerLimit
   * @param {number} upperLimit
   * @param {Function} filter
   * @private
   * @suppress {missingProperties}
   */
  var doTestSignedField_ = function(readField,
      writeField, epsilon, lowerLimit, upperLimit, filter) {
    var writer = new jspb.BinaryWriter();

    // Encode zero and limits.
    writeField.call(writer, 1, filter(lowerLimit));
    writeField.call(writer, 2, filter(-epsilon));
    writeField.call(writer, 3, filter(0));
    writeField.call(writer, 4, filter(epsilon));
    writeField.call(writer, 5, filter(upperLimit));

    var inputValues = [];

    // Encode negative values.
    for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
      var val = filter(cursor);
      writeField.call(writer, 6, val);
      inputValues.push({
        fieldNumber: 6,
        value: val
      });
    }

    // Encode positive values.
    for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
      var val = filter(cursor);
      writeField.call(writer, 7, val);
      inputValues.push({
        fieldNumber: 7,
        value: val
      });
    }

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    // Check zero and limits.
    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    assertEquals(filter(lowerLimit), readField.call(reader));

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    assertEquals(filter(-epsilon), readField.call(reader));

    reader.nextField();
    assertEquals(3, reader.getFieldNumber());
    assertEquals(filter(0), readField.call(reader));

    reader.nextField();
    assertEquals(4, reader.getFieldNumber());
    assertEquals(filter(epsilon), readField.call(reader));

    reader.nextField();
    assertEquals(5, reader.getFieldNumber());
    assertEquals(filter(upperLimit), readField.call(reader));

    for (var i = 0; i < inputValues.length; i++) {
      var expected = inputValues[i];
      reader.nextField();
      assertEquals(expected.fieldNumber, reader.getFieldNumber());
      assertEquals(expected.value, readField.call(reader));
    }
  };


  /**
   * Tests fields that use varint encoding.
   */
  it('testVarintFields', function() {
    assertNotUndefined(jspb.BinaryReader.prototype.readUint32);
    assertNotUndefined(jspb.BinaryWriter.prototype.writeUint32);
    assertNotUndefined(jspb.BinaryReader.prototype.readUint64);
    assertNotUndefined(jspb.BinaryWriter.prototype.writeUint64);
    assertNotUndefined(jspb.BinaryReader.prototype.readBool);
    assertNotUndefined(jspb.BinaryWriter.prototype.writeBool);
    doTestUnsignedField_(
        jspb.BinaryReader.prototype.readUint32,
        jspb.BinaryWriter.prototype.writeUint32,
        1, Math.pow(2, 32) - 1, Math.round);

    doTestUnsignedField_(
        jspb.BinaryReader.prototype.readUint64,
        jspb.BinaryWriter.prototype.writeUint64,
        1, Math.pow(2, 64) - 1025, Math.round);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readInt32,
        jspb.BinaryWriter.prototype.writeInt32,
        1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readInt64,
        jspb.BinaryWriter.prototype.writeInt64,
        1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readEnum,
        jspb.BinaryWriter.prototype.writeEnum,
        1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);

    doTestUnsignedField_(
        jspb.BinaryReader.prototype.readBool,
        jspb.BinaryWriter.prototype.writeBool,
        1, 1, function(x) { return !!x; });
  });


  /**
   * Tests reading a field from hexadecimal string (format: '08 BE EF').
   * @param {Function} readField
   * @param {number} expected
   * @param {string} hexString
   */
  function doTestHexStringVarint_(readField, expected, hexString) {
    var bytesCount = (hexString.length + 1) / 3;
    var bytes = new Uint8Array(bytesCount);
    for (var i = 0; i < bytesCount; i++) {
      bytes[i] = parseInt(hexString.substring(i * 3, i * 3 + 2), 16);
    }
    var reader = jspb.BinaryReader.alloc(bytes);
    reader.nextField();
    assertEquals(expected, readField.call(reader));
  }


  /**
   * Tests non-canonical redundant varint decoding.
   */
  it('testRedundantVarintFields', function() {
    assertNotNull(jspb.BinaryReader.prototype.readUint32);
    assertNotNull(jspb.BinaryReader.prototype.readUint64);
    assertNotNull(jspb.BinaryReader.prototype.readSint32);
    assertNotNull(jspb.BinaryReader.prototype.readSint64);

    // uint32 and sint32 take no more than 5 bytes
    // 08 - field prefix (type = 0 means varint)
    doTestHexStringVarint_(
      jspb.BinaryReader.prototype.readUint32,
      12, '08 8C 80 80 80 00');

    // 11 stands for -6 in zigzag encoding
    doTestHexStringVarint_(
      jspb.BinaryReader.prototype.readSint32,
      -6, '08 8B 80 80 80 00');

    // uint64 and sint64 take no more than 10 bytes
    // 08 - field prefix (type = 0 means varint)
    doTestHexStringVarint_(
      jspb.BinaryReader.prototype.readUint64,
      12, '08 8C 80 80 80 80 80 80 80 80 00');

    // 11 stands for -6 in zigzag encoding
    doTestHexStringVarint_(
      jspb.BinaryReader.prototype.readSint64,
      -6, '08 8B 80 80 80 80 80 80 80 80 00');
  });

  /**
   * Tests reading 64-bit integers as split values.
   */
  it('handles split 64 fields', function() {
    var writer = new jspb.BinaryWriter();
    writer.writeInt64String(1, '4294967296');
    writer.writeSfixed64String(2, '4294967298');
    writer.writeInt64String(3, '3');  // 3 is the zig-zag encoding of -2.
    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    function rejoin(lowBits, highBits) {
      return highBits * 2 ** 32 + (lowBits >>> 0);
    }
    reader.nextField();
    expect(reader.getFieldNumber()).toEqual(1);
    expect(reader.readSplitVarint64(rejoin)).toEqual(0x100000000);

    reader.nextField();
    expect(reader.getFieldNumber()).toEqual(2);
    expect(reader.readSplitFixed64(rejoin)).toEqual(0x100000002);

    reader.nextField();
    expect(reader.getFieldNumber()).toEqual(3);
    expect(reader.readSplitZigzagVarint64(rejoin)).toEqual(-2);
  });

  /**
   * Tests 64-bit fields that are handled as strings.
   */
  it('testStringInt64Fields', function() {
    var writer = new jspb.BinaryWriter();

    var testSignedData = [
      '2730538252207801776',
      '-2688470994844604560',
      '3398529779486536359',
      '3568577411627971000',
      '272477188847484900',
      '-6649058714086158188',
      '-7695254765712060806',
      '-4525541438037104029',
      '-4993706538836508568',
      '4990160321893729138'
    ];
    var testUnsignedData = [
      '7822732630241694882',
      '6753602971916687352',
      '2399935075244442116',
      '8724292567325338867',
      '16948784802625696584',
      '4136275908516066934',
      '3575388346793700364',
      '5167142028379259461',
      '1557573948689737699',
      '17100725280812548567'
    ];

    for (var i = 0; i < testSignedData.length; i++) {
      writer.writeInt64String(2 * i + 1, testSignedData[i]);
      writer.writeUint64String(2 * i + 2, testUnsignedData[i]);
    }

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    for (var i = 0; i < testSignedData.length; i++) {
      reader.nextField();
      assertEquals(2 * i + 1, reader.getFieldNumber());
      assertEquals(testSignedData[i], reader.readInt64String());
      reader.nextField();
      assertEquals(2 * i + 2, reader.getFieldNumber());
      assertEquals(testUnsignedData[i], reader.readUint64String());
    }
  });


  /**
   * Tests fields that use zigzag encoding.
   */
  it('testZigzagFields', function() {
    doTestSignedField_(
        jspb.BinaryReader.prototype.readSint32,
        jspb.BinaryWriter.prototype.writeSint32,
        1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readSint64,
        jspb.BinaryWriter.prototype.writeSint64,
        1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readSintHash64,
        jspb.BinaryWriter.prototype.writeSintHash64, 1, -Math.pow(2, 63),
        Math.pow(2, 63) - 513, jspb.utils.numberToHash64);
  });


  /**
   * Tests fields that use fixed-length encoding.
   */
  it('testFixedFields', function() {
    doTestUnsignedField_(
        jspb.BinaryReader.prototype.readFixed32,
        jspb.BinaryWriter.prototype.writeFixed32,
        1, Math.pow(2, 32) - 1, Math.round);

    doTestUnsignedField_(
        jspb.BinaryReader.prototype.readFixed64,
        jspb.BinaryWriter.prototype.writeFixed64,
        1, Math.pow(2, 64) - 1025, Math.round);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readSfixed32,
        jspb.BinaryWriter.prototype.writeSfixed32,
        1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readSfixed64,
        jspb.BinaryWriter.prototype.writeSfixed64,
        1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
  });


  /**
   * Tests floating point fields.
   */
  it('testFloatFields', function() {
    doTestSignedField_(
        jspb.BinaryReader.prototype.readFloat,
        jspb.BinaryWriter.prototype.writeFloat,
        jspb.BinaryConstants.FLOAT32_MIN,
        -jspb.BinaryConstants.FLOAT32_MAX,
        jspb.BinaryConstants.FLOAT32_MAX,
        truncate);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readDouble,
        jspb.BinaryWriter.prototype.writeDouble,
        jspb.BinaryConstants.FLOAT64_EPS * 10,
        -jspb.BinaryConstants.FLOAT64_MIN,
        jspb.BinaryConstants.FLOAT64_MIN,
        function(x) { return x; });
  });


  /**
   * Tests length-delimited string fields.
   */
  it('testStringFields', function() {
    var s1 = 'The quick brown fox jumps over the lazy dog.';
    var s2 = '人人生而自由，在尊嚴和權利上一律平等。';

    var writer = new jspb.BinaryWriter();

    writer.writeString(1, s1);
    writer.writeString(2, s2);

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    assertEquals(s1, reader.readString());

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    assertEquals(s2, reader.readString());
  });


  /**
   * Tests length-delimited byte fields.
   */
  it('testByteFields', function() {
    var message = [];
    var lowerLimit = 1;
    var upperLimit = 256;
    var scale = 1.1;

    var writer = new jspb.BinaryWriter();

    for (var cursor = lowerLimit; cursor < upperLimit; cursor *= 1.1) {
      var len = Math.round(cursor);
      var bytes = [];
      for (var i = 0; i < len; i++) bytes.push(i % 256);

      writer.writeBytes(len, bytes);
    }

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    for (var cursor = lowerLimit; reader.nextField(); cursor *= 1.1) {
      var len = Math.round(cursor);
      if (len != reader.getFieldNumber()) throw 'fail!';

      var bytes = reader.readBytes();
      if (len != bytes.length) throw 'fail!';
      for (var i = 0; i < bytes.length; i++) {
        if (i % 256 != bytes[i]) throw 'fail!';
      }
    }
  });


  /**
   * Tests nested messages.
   */
  it('testNesting', function() {
    var writer = new jspb.BinaryWriter();
    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});

    writer.writeInt32(1, 100);

    // Add one message with 3 int fields.
    writer.writeMessage(2, dummyMessage, function() {
      writer.writeInt32(3, 300);
      writer.writeInt32(4, 400);
      writer.writeInt32(5, 500);
    });

    // Add one empty message.
    writer.writeMessage(6, dummyMessage, goog.nullFunction);

    writer.writeInt32(7, 700);

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    // Validate outermost message.

    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    assertEquals(100, reader.readInt32());

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    reader.readMessage(dummyMessage, function() {
      // Validate embedded message 1.
      reader.nextField();
      assertEquals(3, reader.getFieldNumber());
      assertEquals(300, reader.readInt32());

      reader.nextField();
      assertEquals(4, reader.getFieldNumber());
      assertEquals(400, reader.readInt32());

      reader.nextField();
      assertEquals(5, reader.getFieldNumber());
      assertEquals(500, reader.readInt32());

      assertEquals(false, reader.nextField());
    });

    reader.nextField();
    assertEquals(6, reader.getFieldNumber());
    reader.readMessage(dummyMessage, function() {
      // Validate embedded message 2.

      assertEquals(false, reader.nextField());
    });

    reader.nextField();
    assertEquals(7, reader.getFieldNumber());
    assertEquals(700, reader.readInt32());

    assertEquals(false, reader.nextField());
  });

  /**
   * Tests skipping fields of each type by interleaving them with sentinel
   * values and skipping everything that's not a sentinel.
   */
  it('testSkipField', function() {
    var writer = new jspb.BinaryWriter();

    var sentinel = 123456789;

    // Write varint fields of different sizes.
    writer.writeInt32(1, sentinel);
    writer.writeInt32(1, 1);
    writer.writeInt32(1, 1000);
    writer.writeInt32(1, 1000000);
    writer.writeInt32(1, 1000000000);

    // Write fixed 64-bit encoded fields.
    writer.writeInt32(2, sentinel);
    writer.writeDouble(2, 1);
    writer.writeFixed64(2, 1);
    writer.writeSfixed64(2, 1);

    // Write fixed 32-bit encoded fields.
    writer.writeInt32(3, sentinel);
    writer.writeFloat(3, 1);
    writer.writeFixed32(3, 1);
    writer.writeSfixed32(3, 1);

    // Write delimited fields.
    writer.writeInt32(4, sentinel);
    writer.writeBytes(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
    writer.writeString(4, 'The quick brown fox jumps over the lazy dog');

    // Write a group with a nested group inside.
    writer.writeInt32(5, sentinel);
    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
    writer.writeGroup(5, dummyMessage, function() {
      // Previously the skipGroup implementation was wrong, which only consume
      // the decoder by nextField. This case is for making the previous
      // implementation failed in skipGroup by an early end group tag.
      // The reason is 44 = 5 * 8 + 4, this will be translated in to a field
      // with number 5 and with type 4 (end group)
      writer.writeInt64(44, 44);
      // This will make previous implementation failed by invalid tag (7).
      writer.writeInt64(42, 47);
      writer.writeInt64(42, 42);
      // This is for making the previous implementation failed by an invalid
      // varint. The bytes have at least 9 consecutive minus byte, which will
      // fail in this.nextField for previous implementation.
      writer.writeBytes(43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]);
      writer.writeGroup(6, dummyMessage, function() {
        writer.writeInt64(84, 42);
        writer.writeInt64(84, 44);
        writer.writeBytes(
          43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]);
      });
    });

    // Write final sentinel.
    writer.writeInt32(6, sentinel);

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    function skip(field, count) {
      for (var i = 0; i < count; i++) {
        reader.nextField();
        if (field != reader.getFieldNumber()) throw 'fail!';
        reader.skipField();
      }
    }

    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    assertEquals(sentinel, reader.readInt32());
    skip(1, 4);

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    assertEquals(sentinel, reader.readInt32());
    skip(2, 3);

    reader.nextField();
    assertEquals(3, reader.getFieldNumber());
    assertEquals(sentinel, reader.readInt32());
    skip(3, 3);

    reader.nextField();
    assertEquals(4, reader.getFieldNumber());
    assertEquals(sentinel, reader.readInt32());
    skip(4, 2);

    reader.nextField();
    assertEquals(5, reader.getFieldNumber());
    assertEquals(sentinel, reader.readInt32());
    skip(5, 1);

    reader.nextField();
    assertEquals(6, reader.getFieldNumber());
    assertEquals(sentinel, reader.readInt32());
  });


  /**
   * Tests packed fields.
   */
  it('testPackedFields', function() {
    var writer = new jspb.BinaryWriter();

    var sentinel = 123456789;

    var unsignedData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    var signedData = [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10];
    var floatData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10];
    var doubleData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10];
    var boolData = [true, false, true, true, false, false, true, false];

    for (var i = 0; i < floatData.length; i++) {
      floatData[i] = truncate(floatData[i]);
    }

    writer.writeInt32(1, sentinel);

    writer.writePackedInt32(2, signedData);
    writer.writePackedInt64(2, signedData);
    writer.writePackedUint32(2, unsignedData);
    writer.writePackedUint64(2, unsignedData);
    writer.writePackedSint32(2, signedData);
    writer.writePackedSint64(2, signedData);
    writer.writePackedFixed32(2, unsignedData);
    writer.writePackedFixed64(2, unsignedData);
    writer.writePackedSfixed32(2, signedData);
    writer.writePackedSfixed64(2, signedData);
    writer.writePackedFloat(2, floatData);
    writer.writePackedDouble(2, doubleData);
    writer.writePackedBool(2, boolData);
    writer.writePackedEnum(2, unsignedData);

    writer.writeInt32(3, sentinel);

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    reader.nextField();
    assertEquals(sentinel, reader.readInt32());

    reader.nextField();
    assertElementsEquals(reader.readPackedInt32(), signedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedInt64(), signedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedUint32(), unsignedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedUint64(), unsignedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedSint32(), signedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedSint64(), signedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedFixed32(), unsignedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedFixed64(), unsignedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedSfixed32(), signedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedSfixed64(), signedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedFloat(), floatData);

    reader.nextField();
    assertElementsEquals(reader.readPackedDouble(), doubleData);

    reader.nextField();
    assertElementsEquals(reader.readPackedBool(), boolData);

    reader.nextField();
    assertElementsEquals(reader.readPackedEnum(), unsignedData);

    reader.nextField();
    assertEquals(sentinel, reader.readInt32());
  });


  /**
   * Byte blobs inside nested messages should always have their byte offset set
   * relative to the start of the outermost blob, not the start of their parent
   * blob.
   */
  it('testNestedBlobs', function() {
    // Create a proto consisting of two nested messages, with the inner one
    // containing a blob of bytes.

    var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED;
    var blob = [1, 2, 3, 4, 5];
    var writer = new jspb.BinaryWriter();
    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});

    writer.writeMessage(1, dummyMessage, function() {
      writer.writeMessage(1, dummyMessage, function() {
        writer.writeBytes(1, blob);
      });
    });

    // Peel off the outer two message layers. Each layer should have two bytes
    // of overhead, one for the field tag and one for the length of the inner
    // blob.

    var decoder1 = new jspb.BinaryDecoder(writer.getResultBuffer());
    assertEquals(fieldTag, decoder1.readUnsignedVarint32());
    assertEquals(blob.length + 4, decoder1.readUnsignedVarint32());

    var decoder2 = new jspb.BinaryDecoder(decoder1.readBytes(blob.length + 4));
    assertEquals(fieldTag, decoder2.readUnsignedVarint32());
    assertEquals(blob.length + 2, decoder2.readUnsignedVarint32());

    assertEquals(fieldTag, decoder2.readUnsignedVarint32());
    assertEquals(blob.length, decoder2.readUnsignedVarint32());
    var bytes = decoder2.readBytes(blob.length);

    assertElementsEquals(bytes, blob);
  });


  /**
   * Tests read callbacks.
   */
  it('testReadCallbacks', function() {
    var writer = new jspb.BinaryWriter();
    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});

    // Add an int, a submessage, and another int.
    writer.writeInt32(1, 100);

    writer.writeMessage(2, dummyMessage, function() {
      writer.writeInt32(3, 300);
      writer.writeInt32(4, 400);
      writer.writeInt32(5, 500);
    });

    writer.writeInt32(7, 700);

    // Create the reader and register a custom read callback.
    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    /**
     * @param {!jspb.BinaryReader} reader
     * @return {*}
     */
    function readCallback(reader) {
      reader.nextField();
      assertEquals(3, reader.getFieldNumber());
      assertEquals(300, reader.readInt32());

      reader.nextField();
      assertEquals(4, reader.getFieldNumber());
      assertEquals(400, reader.readInt32());

      reader.nextField();
      assertEquals(5, reader.getFieldNumber());
      assertEquals(500, reader.readInt32());

      assertEquals(false, reader.nextField());
    };

    reader.registerReadCallback('readCallback', readCallback);

    // Read the container message.
    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    assertEquals(100, reader.readInt32());

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    reader.readMessage(dummyMessage, function() {
      // Decode the embedded message using the registered callback.
      reader.runReadCallback('readCallback');
    });

    reader.nextField();
    assertEquals(7, reader.getFieldNumber());
    assertEquals(700, reader.readInt32());

    assertEquals(false, reader.nextField());
  });
});
