Integrated internal changes from Google

This includes all internal changes from around May 20 to now.
diff --git a/js/binary/constants.js b/js/binary/constants.js
index 836216b..ef5fecd 100644
--- a/js/binary/constants.js
+++ b/js/binary/constants.js
@@ -141,8 +141,8 @@
 
 /**
  * A writer function serializes a message to a BinaryWriter.
- * @typedef {!function(!jspb.Message, !jspb.BinaryWriter):void |
- *           !function(!jspb.ConstBinaryMessage, !jspb.BinaryWriter):void}
+ * @typedef {function((!jspb.Message|!jspb.ConstBinaryMessage),
+ *                    !jspb.BinaryWriter):void}
  */
 jspb.WriterFunction;
 
diff --git a/js/binary/decoder_test.js b/js/binary/decoder_test.js
index d045e91..ac31264 100644
--- a/js/binary/decoder_test.js
+++ b/js/binary/decoder_test.js
@@ -147,9 +147,8 @@
 describe('binaryDecoderTest', function() {
   /**
    * Tests the decoder instance cache.
-   * @suppress {visibility}
    */
-  it('testInstanceCache', function() {
+  it('testInstanceCache', /** @suppress {visibility} */ function() {
     // Empty the instance caches.
     jspb.BinaryDecoder.instanceCache_ = [];
 
diff --git a/js/binary/reader_test.js b/js/binary/reader_test.js
index db674cf..9571138 100644
--- a/js/binary/reader_test.js
+++ b/js/binary/reader_test.js
@@ -52,9 +52,8 @@
 describe('binaryReaderTest', function() {
   /**
    * Tests the reader instance cache.
-   * @suppress {visibility}
    */
-  it('testInstanceCaches', function() {
+  it('testInstanceCaches', /** @suppress {visibility} */ function() {
     var writer = new jspb.BinaryWriter();
     var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
     writer.writeMessage(1, dummyMessage, goog.nullFunction);
@@ -131,9 +130,8 @@
 
   /**
    * Verifies that misuse of the reader class triggers assertions.
-   * @suppress {checkTypes|visibility}
    */
-  it('testReadErrors', function() {
+  it('testReadErrors', /** @suppress {checkTypes|visibility} */ function() {
     // Calling readMessage on a non-delimited field should trigger an
     // assertion.
     var reader = jspb.BinaryReader.alloc([8, 1]);
@@ -200,7 +198,7 @@
    * @private
    * @suppress {missingProperties}
    */
-  function doTestUnsignedField_(readField,
+  var doTestUnsignedField_ = function(readField,
       writeField, epsilon, upperLimit, filter) {
     assertNotNull(readField);
     assertNotNull(writeField);
@@ -252,7 +250,7 @@
    * @private
    * @suppress {missingProperties}
    */
-  function doTestSignedField_(readField,
+  var doTestSignedField_ = function(readField,
       writeField, epsilon, lowerLimit, upperLimit, filter) {
     var writer = new jspb.BinaryWriter();
 
@@ -321,12 +319,12 @@
    * Tests fields that use varint encoding.
    */
   it('testVarintFields', function() {
-    assertNotNull(jspb.BinaryReader.prototype.readUint32);
-    assertNotNull(jspb.BinaryReader.prototype.writeUint32);
-    assertNotNull(jspb.BinaryReader.prototype.readUint64);
-    assertNotNull(jspb.BinaryReader.prototype.writeUint64);
-    assertNotNull(jspb.BinaryReader.prototype.readBool);
-    assertNotNull(jspb.BinaryReader.prototype.writeBool);
+    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,
@@ -369,8 +367,7 @@
     var bytesCount = (hexString.length + 1) / 3;
     var bytes = new Uint8Array(bytesCount);
     for (var i = 0; i < bytesCount; i++) {
-      byte = parseInt(hexString.substring(i * 3, i * 3 + 2), 16);
-      bytes[i] = byte;
+      bytes[i] = parseInt(hexString.substring(i * 3, i * 3 + 2), 16);
     }
     var reader = jspb.BinaryReader.alloc(bytes);
     reader.nextField();
diff --git a/js/binary/writer.js b/js/binary/writer.js
index be4478e..3eb2f1b 100644
--- a/js/binary/writer.js
+++ b/js/binary/writer.js
@@ -717,11 +717,19 @@
 
 /**
  * Writes a message to the buffer.
- * @template MessageType
  * @param {number} field The field number.
  * @param {?MessageType} value The message to write.
- * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
- *     to write and the writer to write it with.
+ * @param {function(MessageTypeNonNull, !jspb.BinaryWriter)} writerCallback
+ *     Will be invoked with the value to write and the writer to write it with.
+ * @template MessageType
+ * Use go/closure-ttl to declare a non-nullable version of MessageType.  Replace
+ * the null in blah|null with none.  This is necessary because the compiler will
+ * infer MessageType to be nullable if the value parameter is nullable.
+ * @template MessageTypeNonNull :=
+ *     cond(isUnknown(MessageType), unknown(),
+ *       mapunion(MessageType, (X) =>
+ *         cond(eq(X, 'null'), none(), X)))
+ * =:
  */
 jspb.BinaryWriter.prototype.writeMessage = function(
     field, value, writerCallback) {
@@ -735,12 +743,20 @@
 /**
  * Writes a group message to the buffer.
  *
- * @template MessageType
  * @param {number} field The field number.
  * @param {?MessageType} value The message to write, wrapped with START_GROUP /
  *     END_GROUP tags. Will be a no-op if 'value' is null.
- * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
- *     to write and the writer to write it with.
+ * @param {function(MessageTypeNonNull, !jspb.BinaryWriter)} writerCallback
+ *     Will be invoked with the value to write and the writer to write it with.
+ * @template MessageType
+ * Use go/closure-ttl to declare a non-nullable version of MessageType.  Replace
+ * the null in blah|null with none.  This is necessary because the compiler will
+ * infer MessageType to be nullable if the value parameter is nullable.
+ * @template MessageTypeNonNull :=
+ *     cond(isUnknown(MessageType), unknown(),
+ *       mapunion(MessageType, (X) =>
+ *         cond(eq(X, 'null'), none(), X)))
+ * =:
  */
 jspb.BinaryWriter.prototype.writeGroup = function(
     field, value, writerCallback) {
@@ -1122,8 +1138,8 @@
  * @param {number} field The field number.
  * @param {?Array.<MessageType>} value The array of messages to
  *    write.
- * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
- *     to write and the writer to write it with.
+ * @param {function(MessageType, !jspb.BinaryWriter)} writerCallback
+ *     Will be invoked with the value to write and the writer to write it with.
  */
 jspb.BinaryWriter.prototype.writeRepeatedMessage = function(
     field, value, writerCallback) {
@@ -1142,8 +1158,8 @@
  * @param {number} field The field number.
  * @param {?Array.<MessageType>} value The array of messages to
  *    write.
- * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
- *     to write and the writer to write it with.
+ * @param {function(MessageType, !jspb.BinaryWriter)} writerCallback
+ *     Will be invoked with the value to write and the writer to write it with.
  */
 jspb.BinaryWriter.prototype.writeRepeatedGroup = function(
     field, value, writerCallback) {