Update to goog.modules (#260)

diff --git a/asserts.js b/asserts.js
index 5ac5850..9ade06b 100644
--- a/asserts.js
+++ b/asserts.js
@@ -9,7 +9,8 @@
  * invariants runtime.
  */
 
-goog.provide('jspb.asserts');
+goog.module('jspb.asserts');
+goog.module.declareLegacyNamespace();
 
 /**
  * Throws an exception with the given message and "Assertion failed" prefixed
@@ -20,7 +21,7 @@
  * @param {!Array<*>} givenArgs The substitution arguments for givenMessage.
  * @throws {Error} When the value is not a number.
  */
-jspb.asserts.doAssertFailure = function(defaultMessage, defaultArgs, givenMessage, givenArgs) {
+function doAssertFailure(defaultMessage, defaultArgs, givenMessage, givenArgs) {
   let message = 'Assertion failed';
   let args;
   if (givenMessage) {
@@ -46,13 +47,12 @@
  * @return {T} The value of the condition.
  * @throws {Error} When the condition evaluates to false.
  */
-
-jspb.asserts.assert = function(condition, opt_message, ...args) {
+function assert(condition, opt_message, ...args) {
   if (!condition) {
-    jspb.asserts.doAssertFailure('', null, opt_message, args);
+    doAssertFailure('', null, opt_message, args);
   }
   return condition;
-};
+}
 
 
 /**
@@ -63,14 +63,14 @@
  * @return {string} The value, guaranteed to be a string when asserts enabled.
  * @throws {Error} When the value is not a string.
  */
-jspb.asserts.assertString = function(value, opt_message, ...args) {
+function assertString(value, opt_message, ...args) {
   if (typeof value !== 'string') {
-    jspb.asserts.doAssertFailure(
+    doAssertFailure(
         'Expected string but got %s: %s.', [goog.typeOf(value), value],
         opt_message, args);
   }
   return /** @type {string} */ (value);
-};
+}
 
 
 /**
@@ -81,14 +81,14 @@
  * @return {!Array<?>} The value, guaranteed to be a non-null array.
  * @throws {Error} When the value is not an array.
  */
-jspb.asserts.assertArray = function(value, opt_message, ...args) {
+function assertArray(value, opt_message, ...args) {
   if (!Array.isArray(value)) {
-    jspb.asserts.doAssertFailure(
+    doAssertFailure(
         'Expected array but got %s: %s.', [goog.typeOf(value), value],
         opt_message, args);
   }
   return /** @type {!Array<?>} */ (value);
-};
+}
 
 /**
  * Triggers a failure. This function is useful in case when we want to add a
@@ -98,7 +98,7 @@
  *  switch(type) {
  *    case FOO: doSomething(); break;
  *    case BAR: doSomethingElse(); break;
- *    default: jspb.asserts.JspbFail('Unrecognized type: ' + type);
+ *    default: jspb.asserts.fail('Unrecognized type: ' + type);
  *      // We have only 2 types - "default:" section is unreachable code.
  *  }
  * </pre>
@@ -108,11 +108,11 @@
  * @return {void}
  * @throws {Error} Failure.
  */
-jspb.asserts.fail = function(opt_message, ...args) {
+function fail(opt_message, ...args) {
   throw new Error(
       'Failure' + (opt_message ? ': ' + opt_message : ''),
       args);
-};
+}
 
 /**
  * Checks if the value is an instance of the user-defined type.
@@ -130,15 +130,15 @@
  * @return {T}
  * @template T
  */
-jspb.asserts.assertInstanceof = function(value, type, opt_message, ...args) {
+function assertInstanceof(value, type, opt_message, ...args) {
   if (!(value instanceof type)) {
-    jspb.asserts.doAssertFailure(
+    doAssertFailure(
         'Expected instanceof %s but got %s.',
-        [jspb.asserts.getType(type), jspb.asserts.getType(value)],
+      [getType(type), getType(value)],
         opt_message, args);
   }
   return value;
-};
+}
 
 /**
  * Returns the type of a value. If a constructor is passed, and a suitable
@@ -147,7 +147,7 @@
  * @return {string} The best display name for the value, or 'unknown type name'.
  * @private
  */
-jspb.asserts.getType = function(value) {
+function getType(value) {
   if (value instanceof Function) {
     return value.displayName || value.name || 'unknown type name';
   } else if (value instanceof Object) {
@@ -157,3 +157,13 @@
     return value === null ? 'null' : typeof value;
   }
 }
+
+exports = {
+  doAssertFailure,
+  assert,
+  assertString,
+  assertArray,
+  fail,
+  assertInstanceof,
+  getType
+};
diff --git a/commonjs/rewrite_tests_for_commonjs.js b/commonjs/rewrite_tests_for_commonjs.js
index 8b13c28..9cd5579 100644
--- a/commonjs/rewrite_tests_for_commonjs.js
+++ b/commonjs/rewrite_tests_for_commonjs.js
@@ -63,12 +63,11 @@
 var pkg = null;
 
 // Header: goes in every file at the top.
-console.log("var global = Function('return this')();");
+console.log("var global = globalThis;");
 console.log("var googleProtobuf = require('google-protobuf');");
 console.log("var testdeps = require('testdeps_commonjs');");
 console.log("global.COMPILED = testdeps.COMPILED;");
 console.log("global.goog = testdeps.goog;");
-console.log("global.jspb = googleProtobuf.jspb;");
 console.log("");
 
 lineReader.on('line', function (line) {
diff --git a/debug.js b/debug.js
index 88abaeb..081912a 100644
--- a/debug.js
+++ b/debug.js
@@ -32,14 +32,15 @@
  * @fileoverview Utilities to debug JSPB based proto objects.
  */
 
-goog.provide('jspb.debug');
+goog.module('jspb.debug');
+goog.module.declareLegacyNamespace();
 
-goog.require('goog.array');
-goog.require('goog.object');
+const googArray = goog.require('goog.array');
+const googObject = goog.require('goog.object');
 
-goog.require('jspb.asserts');
-goog.require('jspb.Map');
-goog.require('jspb.Message');
+const asserts = goog.require('jspb.asserts');
+const Map = goog.require('jspb.Map');
+const Message = goog.require('jspb.Message');
 
 
 /**
@@ -49,22 +50,21 @@
  * work in obfuscated and or optimized code.
  * Use this in environments where {@see jspb.Message.prototype.toObject} is
  * not available for code size reasons.
- * @param {jspb.Message} message A jspb.Message.
+ * @param {Message} message A jspb.Message.
  * @return {Object}
- * @export
  */
-jspb.debug.dump = function(message) {
+function dump(message) {
   if (!goog.DEBUG) {
     return null;
   }
-  jspb.asserts.assertInstanceof(message, jspb.Message,
+  asserts.assertInstanceof(message, Message,
       'jspb.Message instance expected');
   /** @type {Object} */
   var object = message;
-  jspb.asserts.assert(object['getExtension'],
+  asserts.assert(object['getExtension'],
       'Only unobfuscated and unoptimized compilation modes supported.');
-  return /** @type {Object} */ (jspb.debug.dump_(message));
-};
+  return /** @type {Object} */ (dump_(message));
+}
 
 
 /**
@@ -75,7 +75,7 @@
  * @return {*}
  * @private
  */
-jspb.debug.dump_ = function(thing) {
+function dump_(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' ||
@@ -90,20 +90,20 @@
   }
 
   if (type == 'array') {
-    jspb.asserts.assertArray(thing);
-    return goog.array.map(thing, jspb.debug.dump_);
+    asserts.assertArray(thing);
+    return googArray.map(thing, dump_);
   }
 
-  if (message instanceof jspb.Map) {
+  if (message instanceof Map) {
     var mapObject = {};
     var entries = message.entries();
     for (var entry = entries.next(); !entry.done; entry = entries.next()) {
-      mapObject[entry.value[0]] = jspb.debug.dump_(entry.value[1]);
+      mapObject[entry.value[0]] = dump_(entry.value[1]);
     }
     return mapObject;
   }
 
-  jspb.asserts.assertInstanceof(message, jspb.Message,
+  asserts.assertInstanceof(message, Message,
       'Only messages expected: ' + thing);
   var ctor = message.constructor;
   var messageName = ctor.name || ctor.displayName;
@@ -117,7 +117,7 @@
       var has = 'has' + match[1];
       if (!thing[has] || thing[has]()) {
         var val = thing[name]();
-        object[jspb.debug.formatFieldName_(match[1])] = jspb.debug.dump_(val);
+        object[formatFieldName_(match[1])] = dump_(val);
       }
     }
   }
@@ -132,18 +132,18 @@
     if (/^\d+$/.test(id)) {
       var ext = ctor['extensions'][id];
       var extVal = thing.getExtension(ext);
-      var fieldName = goog.object.getKeys(ext.fieldName)[0];
+      var fieldName = googObject.getKeys(ext.fieldName)[0];
       if (extVal != null) {
         if (!extensionsObject) {
           extensionsObject = object['$extensions'] = {};
         }
-        extensionsObject[jspb.debug.formatFieldName_(fieldName)] =
-            jspb.debug.dump_(extVal);
+        extensionsObject[formatFieldName_(fieldName)] =
+          dump_(extVal);
       }
     }
   }
   return object;
-};
+}
 
 
 /**
@@ -153,9 +153,13 @@
  * @return {string}
  * @private
  */
-jspb.debug.formatFieldName_ = function(name) {
+function formatFieldName_(name) {
   // Name may be in TitleCase.
   return name.replace(/^[A-Z]/, function(c) {
     return c.toLowerCase();
   });
+}
+
+exports = {
+  dump
 };
diff --git a/extension_field_binary_info.js b/extension_field_binary_info.js
new file mode 100644
index 0000000..4f79100
--- /dev/null
+++ b/extension_field_binary_info.js
@@ -0,0 +1,72 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://protobuf.dev/
+//
+// 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 Definition of jspb.ExtensionFieldBinaryInfo.
+ */
+
+goog.module('jspb.ExtensionFieldBinaryInfo');
+goog.module.declareLegacyNamespace();
+
+const ExtensionFieldInfo = goog.require('jspb.ExtensionFieldInfo');
+goog.requireType('jspb.BinaryReader');
+goog.requireType('jspb.BinaryWriter');
+
+/**
+ * Stores binary-related information for a single extension field.
+ * @param {!ExtensionFieldInfo<T>} fieldInfo
+ * @param {function(this:jspb.BinaryReader,number,?,?)} binaryReaderFn
+ * @param {function(this:jspb.BinaryWriter,number,?)
+ *        |function(this:jspb.BinaryWriter,number,?,?,?,?,?)} binaryWriterFn
+ * @param {function(?,?)=} opt_binaryMessageSerializeFn
+ * @param {function(?,?)=} opt_binaryMessageDeserializeFn
+ * @param {boolean=} opt_isPacked
+ * @constructor
+ * @struct
+ * @template T
+ */
+const ExtensionFieldBinaryInfo = function (
+  fieldInfo, binaryReaderFn, binaryWriterFn, opt_binaryMessageSerializeFn,
+  opt_binaryMessageDeserializeFn, opt_isPacked) {
+  /** @const */
+  this.fieldInfo = fieldInfo;
+  /** @const */
+  this.binaryReaderFn = binaryReaderFn;
+  /** @const */
+  this.binaryWriterFn = binaryWriterFn;
+  /** @const */
+  this.binaryMessageSerializeFn = opt_binaryMessageSerializeFn;
+  /** @const */
+  this.binaryMessageDeserializeFn = opt_binaryMessageDeserializeFn;
+  /** @const */
+  this.isPacked = opt_isPacked;
+};
+
+exports = ExtensionFieldBinaryInfo;
diff --git a/extension_field_info.js b/extension_field_info.js
new file mode 100644
index 0000000..ff83177
--- /dev/null
+++ b/extension_field_info.js
@@ -0,0 +1,104 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://protobuf.dev/
+//
+// 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 Definition of jspb.ExtensionFieldInfo.
+ */
+
+goog.module('jspb.ExtensionFieldInfo');
+goog.module.declareLegacyNamespace();
+
+// We need to reference jspb.Message for type annotations, but we want to avoid
+// a circular dependency that would cause a runtime error.
+goog.forwardDeclare('jspb.Message');
+
+/**
+ * Stores information for a single extension field.
+ *
+ * For example, an extension field defined like so:
+ *
+ *     extend BaseMessage {
+ *       optional MyMessage my_field = 123;
+ *     }
+ *
+ * will result in an ExtensionFieldInfo object with these properties:
+ *
+ *     {
+ *       fieldIndex: 123,
+ *       fieldName: {my_field_renamed: 0},
+ *       ctor: proto.example.MyMessage,
+ *       toObjectFn: proto.example.MyMessage.toObject,
+ *       isRepeated: 0
+ *     }
+ *
+ * We include `toObjectFn` to allow the JSCompiler to perform dead-code removal
+ * on unused toObject() methods.
+ *
+ * If an extension field is primitive, ctor and toObjectFn will be null.
+ * isRepeated should be 0 or 1.
+ *
+ * binary{Reader,Writer}Fn and (if message type) binaryMessageSerializeFn are
+ * always provided. binaryReaderFn and binaryWriterFn are references to the
+ * appropriate methods on BinaryReader/BinaryWriter to read/write the value of
+ * this extension, and binaryMessageSerializeFn is a reference to the message
+ * class's .serializeBinary method, if available.
+ *
+ * @param {number} fieldNumber
+ * @param {Object} fieldName This has the extension field name as a property.
+ * @param {?function(new: jspb.Message, Array=)} ctor
+ * @param {?function((boolean|undefined),!jspb.Message):!Object} toObjectFn
+ * @param {number} isRepeated
+ * @constructor
+ * @struct
+ * @template T
+ */
+const ExtensionFieldInfo = function (
+  fieldNumber, fieldName, ctor, toObjectFn, isRepeated) {
+  /** @const */
+  this.fieldIndex = fieldNumber;
+  /** @const */
+  this.fieldName = fieldName;
+  /** @const */
+  this.ctor = ctor;
+  /** @const */
+  this.toObjectFn = toObjectFn;
+  /** @const */
+  this.isRepeated = isRepeated;
+};
+
+/**
+ * @return {boolean} Does this field represent a sub Message?
+ * @export
+ */
+ExtensionFieldInfo.prototype.isMessageType = function () {
+  return !!this.ctor;
+};
+
+exports = ExtensionFieldInfo;
diff --git a/gulpfile.js b/gulpfile.js
index 3703193..6140b1a 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -177,6 +177,8 @@
     '--js=internal_public.js',
     '--js=map.js',
     '--js=message.js',
+    '--js=extension_field_info.js',
+    '--js=extension_field_binary_info.js',
     '--js=bytestring.js',
     '--js=unsafe_bytestring.js',
     '--js=binary/**.js',
@@ -228,7 +230,7 @@
 
 function closure_make_deps(cb) {
   exec(
-    './node_modules/.bin/closure-make-deps --closure-path=. --file=node_modules/google-closure-library/closure/goog/deps.js bytestring.js internal_bytes.js internal_options.js internal_public.js binary/arith.js binary/bytesource.js binary/binary_constants.js binary/decoder.js binary/decoder_alias.js binary/encoder.js binary/encoder_alias.js binary/errors.js binary/internal_buffer.js binary/reader.js binary/reader_alias.js binary/test_utils.js binary/utf8.js binary/utils.js binary/writer.js binary/writer_alias.js asserts.js debug.js map.js message.js node_loader.js test_bootstrap.js unsafe_bytestring.js > deps.js',
+    './node_modules/.bin/closure-make-deps --closure-path=. --file=node_modules/google-closure-library/closure/goog/deps.js bytestring.js internal_bytes.js internal_options.js internal_public.js binary/arith.js binary/bytesource.js binary/binary_constants.js binary/decoder.js binary/decoder_alias.js binary/encoder.js binary/encoder_alias.js binary/errors.js binary/internal_buffer.js binary/reader.js binary/reader_alias.js binary/test_utils.js binary/utf8.js binary/utils.js binary/writer.js binary/writer_alias.js asserts.js debug.js map.js message.js extension_field_info.js extension_field_binary_info.js node_loader.js test_bootstrap.js unsafe_bytestring.js > deps.js',
     make_exec_logging_callback(cb));
 }
 
diff --git a/map.js b/map.js
index e917941..e46087c 100644
--- a/map.js
+++ b/map.js
@@ -32,10 +32,44 @@
 /**
  * @fileoverview
  */
-goog.provide('jspb.Map');
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://protobuf.dev/
+//
+// 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
+ */
+goog.module('jspb.Map');
+goog.module.declareLegacyNamespace();
 
 
-goog.require('jspb.asserts');
+const asserts = goog.require('jspb.asserts');
 
 goog.requireType('jspb.BinaryReader');
 goog.requireType('jspb.BinaryWriter');
@@ -60,15 +94,14 @@
  *
  * @constructor
  * @struct
- * @export
  */
-jspb.Map = function(arr, opt_valueCtor) {
+const Map = function (arr, opt_valueCtor) {
   /** @const @private */
   this.arr_ = arr;
   /** @const @private */
   this.valueCtor_ = opt_valueCtor;
 
-  /** @type {!Object<string, !jspb.Map.Entry_<K,V>>} @private */
+  /** @type {!Object<string, !Entry_<K,V>>} @private */
   this.map_ = {};
 
   /**
@@ -85,15 +118,38 @@
 
 
 /**
+ * @param {K} key The entry's key.
+ * @param {V=} opt_value The entry's value wrapper.
+ * @constructor
+ * @struct
+ * @template K, V
+ * @private
+ */
+const Entry_ = function (key, opt_value) {
+  /** @const {K} */
+  this.key = key;
+
+  // The JSPB-serializable value.  For primitive types this will be of type V.
+  // For message types it will be an array.
+  /** @type {V} */
+  this.value = opt_value;
+
+  // Only used for submessage values.
+  /** @type {V} */
+  this.valueWrapper = undefined;
+};
+
+
+/**
  * Load initial content from underlying array.
  * @private
  */
-jspb.Map.prototype.loadFromArray_ = function() {
+Map.prototype.loadFromArray_ = function () {
   for (var i = 0; i < this.arr_.length; i++) {
     var record = this.arr_[i];
     var key = record[0];
     var value = record[1];
-    this.map_[key.toString()] = new jspb.Map.Entry_(key, value);
+    this.map_[key.toString()] = new Entry_(key, value);
   }
   this.arrClean = true;
 };
@@ -104,7 +160,7 @@
  * @return {!Array<!Array<!Object>>}
  * @export
  */
-jspb.Map.prototype.toArray = function() {
+Map.prototype.toArray = function () {
   if (this.arrClean) {
     if (this.valueCtor_) {
       // We need to recursively sync maps in submessages to their arrays.
@@ -149,7 +205,7 @@
  * @return {!Array<!Array<!Object>>}
  * @export
  */
-jspb.Map.prototype.toObject = function(includeInstance, valueToObject) {
+Map.prototype.toObject = function (includeInstance, valueToObject) {
   var rawArray = this.toArray();
   var entries = [];
   for (var i = 0; i < rawArray.length; i++) {
@@ -157,7 +213,7 @@
     this.wrapEntry_(entry);
     var valueWrapper = /** @type {V|undefined} */ (entry.valueWrapper);
     if (valueWrapper) {
-      jspb.asserts.assert(valueToObject);
+      asserts.assert(valueToObject);
       entries.push([entry.key, valueToObject(includeInstance, valueWrapper)]);
     } else {
       entries.push([entry.key, entry.value]);
@@ -178,11 +234,11 @@
  *    The constructor for type V.
  * @param {function(!Object):V} valueFromObject
  *    The fromObject function for type V.
- * @return {!jspb.Map<K, V>}
+ * @return {!Map<K, V>}
  * @export
  */
-jspb.Map.fromObject = function(entries, valueCtor, valueFromObject) {
-  var result = new jspb.Map([], valueCtor);
+Map.fromObject = function (entries, valueCtor, valueFromObject) {
+  var result = new Map([], valueCtor);
   for (var i = 0; i < entries.length; i++) {
     var key = entries[i][0];
     var value = valueFromObject(entries[i][1]);
@@ -200,7 +256,7 @@
  * @constructor @struct
  * @private
  */
-jspb.Map.ArrayIteratorIterable_ = function(arr) {
+const ArrayIteratorIterable_ = function (arr) {
   /** @type {number} @private */
   this.idx_ = 0;
 
@@ -210,7 +266,7 @@
 
 
 /** @override @final */
-jspb.Map.ArrayIteratorIterable_.prototype.next = function() {
+ArrayIteratorIterable_.prototype.next = function () {
   if (this.idx_ < this.arr_.length) {
     return {done: false, value: this.arr_[this.idx_++]};
   } else {
@@ -220,7 +276,7 @@
 
 if (typeof(Symbol) != 'undefined') {
   /** @override */
-  jspb.Map.ArrayIteratorIterable_.prototype[Symbol.iterator] = function() {
+  ArrayIteratorIterable_.prototype[Symbol.iterator] = function () {
     return this;
   };
 }
@@ -231,7 +287,7 @@
  * @return {number}
  * @export
  */
-jspb.Map.prototype.getLength = function() {
+Map.prototype.getLength = function () {
   return this.stringKeys_().length;
 };
 
@@ -240,7 +296,7 @@
  * Clears the map.
  * @export
  */
-jspb.Map.prototype.clear = function() {
+Map.prototype.clear = function () {
   this.map_ = {};
   this.arrClean = false;
 };
@@ -250,12 +306,12 @@
  * Deletes a particular key from the map.
  * N.B.: differs in name from ES6 Map's `delete` because IE8 does not support
  * reserved words as property names.
- * @this {jspb.Map}
+ * @this {Map}
  * @param {K} key
  * @return {boolean} Whether any entry with this key was deleted.
  * @export
  */
-jspb.Map.prototype.del = function(key) {
+Map.prototype.del = function (key) {
   var keyValue = key.toString();
   var hadKey = this.map_.hasOwnProperty(keyValue);
   delete this.map_[keyValue];
@@ -274,7 +330,7 @@
  * @return {!Array<!Array<K|V>>}
  * @export
  */
-jspb.Map.prototype.getEntryList = function() {
+Map.prototype.getEntryList = function () {
   var entries = [];
   var strKeys = this.stringKeys_();
   strKeys.sort();
@@ -292,7 +348,7 @@
  * @return {!IteratorIterable<!Array<K|V>>} The iterator-iterable.
  * @export
  */
-jspb.Map.prototype.entries = function() {
+Map.prototype.entries = function () {
   var entries = [];
   var strKeys = this.stringKeys_();
   strKeys.sort();
@@ -300,7 +356,7 @@
     var entry = this.map_[strKeys[i]];
     entries.push([entry.key, this.wrapEntry_(entry)]);
   }
-  return new jspb.Map.ArrayIteratorIterable_(entries);
+  return new ArrayIteratorIterable_(entries);
 };
 
 
@@ -309,7 +365,7 @@
  * @return {!IteratorIterable<K>} The iterator-iterable.
  * @export
  */
-jspb.Map.prototype.keys = function() {
+Map.prototype.keys = function () {
   var keys = [];
   var strKeys = this.stringKeys_();
   strKeys.sort();
@@ -317,7 +373,7 @@
     var entry = this.map_[strKeys[i]];
     keys.push(entry.key);
   }
-  return new jspb.Map.ArrayIteratorIterable_(keys);
+  return new ArrayIteratorIterable_(keys);
 };
 
 
@@ -326,7 +382,7 @@
  * @return {!IteratorIterable<V>} The iterator-iterable.
  * @export
  */
-jspb.Map.prototype.values = function() {
+Map.prototype.values = function () {
   var values = [];
   var strKeys = this.stringKeys_();
   strKeys.sort();
@@ -334,18 +390,18 @@
     var entry = this.map_[strKeys[i]];
     values.push(this.wrapEntry_(entry));
   }
-  return new jspb.Map.ArrayIteratorIterable_(values);
+  return new ArrayIteratorIterable_(values);
 };
 
 
 /**
  * Iterates over entries in the map, calling a function on each.
  * @template T
- * @param {function(this:T, V, K, ?jspb.Map<K, V>)} cb
+ * @param {function(this:T, V, K, ?Map<K, V>)} cb
  * @param {T=} opt_thisArg
  * @export
  */
-jspb.Map.prototype.forEach = function(cb, opt_thisArg) {
+Map.prototype.forEach = function (cb, opt_thisArg) {
   var strKeys = this.stringKeys_();
   strKeys.sort();
   for (var i = 0; i < strKeys.length; i++) {
@@ -359,11 +415,11 @@
  * Sets a key in the map to the given value.
  * @param {K} key The key
  * @param {V} value The value
- * @return {!jspb.Map<K,V>}
+ * @return {!Map<K,V>}
  * @export
  */
-jspb.Map.prototype.set = function(key, value) {
-  var entry = new jspb.Map.Entry_(key);
+Map.prototype.set = function (key, value) {
+  var entry = new Entry_(key);
   if (this.valueCtor_) {
     entry.valueWrapper = value;
     // .toArray() on a message returns a reference to the underlying array
@@ -381,11 +437,11 @@
 /**
  * Helper: lazily construct a wrapper around an entry, if needed, and return the
  * user-visible type.
- * @param {!jspb.Map.Entry_<K,V>} entry
+ * @param {!Entry_<K,V>} entry
  * @return {V}
  * @private
  */
-jspb.Map.prototype.wrapEntry_ = function(entry) {
+Map.prototype.wrapEntry_ = function (entry) {
   if (this.valueCtor_) {
     if (!entry.valueWrapper) {
       entry.valueWrapper = new this.valueCtor_(entry.value);
@@ -403,7 +459,7 @@
  * @return {V|undefined} The value, or `undefined` if key not present
  * @export
  */
-jspb.Map.prototype.get = function(key) {
+Map.prototype.get = function (key) {
   var keyValue = key.toString();
   var entry = this.map_[keyValue];
   if (entry) {
@@ -420,7 +476,7 @@
  * @return {boolean} `true` if the key is present
  * @export
  */
-jspb.Map.prototype.has = function(key) {
+Map.prototype.has = function (key) {
   var keyValue = key.toString();
   return (keyValue in this.map_);
 };
@@ -431,7 +487,7 @@
  * 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 {!Map} map
  * @param {!jspb.BinaryReader} reader
  * @param {function(this:jspb.BinaryReader):K} keyReaderFn
  *     The method on BinaryReader that reads type K from the stream.
@@ -457,7 +513,7 @@
  * @export
  *
  */
-jspb.Map.deserializeBinary = function(map, reader, keyReaderFn, valueReaderFn,
+Map.deserializeBinary = function (map, reader, keyReaderFn, valueReaderFn,
                                       opt_valueReaderCallback, opt_defaultKey,
                                       opt_defaultValue) {
   var key = opt_defaultKey;
@@ -475,7 +531,7 @@
     } else if (field == 2) {
       // Value.
       if (map.valueCtor_) {
-        jspb.asserts.assert(opt_valueReaderCallback);
+        asserts.assert(opt_valueReaderCallback);
         if (!value) {
           // Old generator still doesn't provide default value message.
           // Need this for backward compatibility.
@@ -490,8 +546,8 @@
     }
   }
 
-  jspb.asserts.assert(key != undefined);
-  jspb.asserts.assert(value != undefined);
+  asserts.assert(key != undefined);
+  asserts.assert(value != undefined);
   map.set(key, value);
 };
 
@@ -502,7 +558,7 @@
  * @return {!Array<string>}
  * @private
  */
-jspb.Map.prototype.stringKeys_ = function() {
+Map.prototype.stringKeys_ = function () {
   var m = this.map_;
   var ret = [];
   for (var p in m) {
@@ -513,26 +569,4 @@
   return ret;
 };
 
-
-
-/**
- * @param {K} key The entry's key.
- * @param {V=} opt_value The entry's value wrapper.
- * @constructor
- * @struct
- * @template K, V
- * @private
- */
-jspb.Map.Entry_ = function(key, opt_value) {
-  /** @const {K} */
-  this.key = key;
-
-  // The JSPB-serializable value.  For primitive types this will be of type V.
-  // For message types it will be an array.
-  /** @type {V} */
-  this.value = opt_value;
-
-  // Only used for submessage values.
-  /** @type {V} */
-  this.valueWrapper = undefined;
-};
+exports = Map;
diff --git a/message.js b/message.js
index 430cb52..066389e 100644
--- a/message.js
+++ b/message.js
@@ -35,111 +35,17 @@
  * @author [email protected] (Mark Rawling)
  */
 
-goog.provide('jspb.ExtensionFieldBinaryInfo');
-goog.provide('jspb.ExtensionFieldInfo');
-goog.provide('jspb.Message');
+goog.module('jspb.Message');
+goog.module.declareLegacyNamespace();
 
-goog.require('goog.array');
-goog.require('goog.crypt.base64');
+const googArray = goog.require('goog.array');
+const googCryptBase64 = goog.require('goog.crypt.base64');
 
-goog.require('jspb.asserts');
-goog.require('jspb.binary.reader');
-goog.require('jspb.Map');
-
-
-/**
- * Stores information for a single extension field.
- *
- * For example, an extension field defined like so:
- *
- *     extend BaseMessage {
- *       optional MyMessage my_field = 123;
- *     }
- *
- * will result in an ExtensionFieldInfo object with these properties:
- *
- *     {
- *       fieldIndex: 123,
- *       fieldName: {my_field_renamed: 0},
- *       ctor: proto.example.MyMessage,
- *       toObjectFn: proto.example.MyMessage.toObject,
- *       isRepeated: 0
- *     }
- *
- * We include `toObjectFn` to allow the JSCompiler to perform dead-code removal
- * on unused toObject() methods.
- *
- * If an extension field is primitive, ctor and toObjectFn will be null.
- * isRepeated should be 0 or 1.
- *
- * binary{Reader,Writer}Fn and (if message type) binaryMessageSerializeFn are
- * always provided. binaryReaderFn and binaryWriterFn are references to the
- * appropriate methods on BinaryReader/BinaryWriter to read/write the value of
- * this extension, and binaryMessageSerializeFn is a reference to the message
- * class's .serializeBinary method, if available.
- *
- * @param {number} fieldNumber
- * @param {Object} fieldName This has the extension field name as a property.
- * @param {?function(new: jspb.Message, Array=)} ctor
- * @param {?function((boolean|undefined),!jspb.Message):!Object} toObjectFn
- * @param {number} isRepeated
- * @constructor
- * @struct
- * @template T
- * @export
- */
-jspb.ExtensionFieldInfo = function(
-    fieldNumber, fieldName, ctor, toObjectFn, isRepeated) {
-  /** @const */
-  this.fieldIndex = fieldNumber;
-  /** @const */
-  this.fieldName = fieldName;
-  /** @const */
-  this.ctor = ctor;
-  /** @const */
-  this.toObjectFn = toObjectFn;
-  /** @const */
-  this.isRepeated = isRepeated;
-};
-
-/**
- * Stores binary-related information for a single extension field.
- * @param {!jspb.ExtensionFieldInfo<T>} fieldInfo
- * @param {function(this:jspb.BinaryReader,number,?,?)} binaryReaderFn
- * @param {function(this:jspb.BinaryWriter,number,?)
- *        |function(this:jspb.BinaryWriter,number,?,?,?,?,?)} binaryWriterFn
- * @param {function(?,?)=} opt_binaryMessageSerializeFn
- * @param {function(?,?)=} opt_binaryMessageDeserializeFn
- * @param {boolean=} opt_isPacked
- * @constructor
- * @struct
- * @template T
- * @export
- */
-jspb.ExtensionFieldBinaryInfo = function(
-    fieldInfo, binaryReaderFn, binaryWriterFn, opt_binaryMessageSerializeFn,
-    opt_binaryMessageDeserializeFn, opt_isPacked) {
-  /** @const */
-  this.fieldInfo = fieldInfo;
-  /** @const */
-  this.binaryReaderFn = binaryReaderFn;
-  /** @const */
-  this.binaryWriterFn = binaryWriterFn;
-  /** @const */
-  this.binaryMessageSerializeFn = opt_binaryMessageSerializeFn;
-  /** @const */
-  this.binaryMessageDeserializeFn = opt_binaryMessageDeserializeFn;
-  /** @const */
-  this.isPacked = opt_isPacked;
-};
-
-/**
- * @return {boolean} Does this field represent a sub Message?
- * @export
- */
-jspb.ExtensionFieldInfo.prototype.isMessageType = function() {
-  return !!this.ctor;
-};
+const asserts = goog.require('jspb.asserts');
+const { BinaryReader } = goog.require('jspb.binary.reader');
+const Map = goog.require('jspb.Map');
+const ExtensionFieldInfo = goog.require('jspb.ExtensionFieldInfo');
+const ExtensionFieldBinaryInfo = goog.require('jspb.ExtensionFieldBinaryInfo');
 
 
 /**
@@ -156,14 +62,13 @@
  * or use a lambda that knows the type:
  *     someFunction(()=>instanceOfKnownProto.serializeBinary());
  * or, if you don't care about code size, just suppress the
- *     WARNING - Property serializeBinary never defined on jspb.Message
+ *     WARNING - Property serializeBinary never defined on Message
  * and call it the intuitive way.
  *
  * @constructor
  * @struct
- * @export
  */
-jspb.Message = function() {};
+const Message = function () { };
 
 
 /**
@@ -175,8 +80,8 @@
  *     in an application.
  * @export
  */
-jspb.Message.GENERATE_TO_OBJECT =
-    goog.define('jspb.Message.GENERATE_TO_OBJECT', true);
+Message.GENERATE_TO_OBJECT =
+  goog.define('Message.GENERATE_TO_OBJECT', true);
 
 
 /**
@@ -189,8 +94,8 @@
  *     By default this is enabled for test code only.
  * @export
  */
-jspb.Message.GENERATE_FROM_OBJECT = goog.define(
-    'jspb.Message.GENERATE_FROM_OBJECT', !goog.DISALLOW_TEST_ONLY_CODE);
+Message.GENERATE_FROM_OBJECT = goog.define(
+  'Message.GENERATE_FROM_OBJECT', !goog.DISALLOW_TEST_ONLY_CODE);
 
 
 /**
@@ -198,8 +103,8 @@
  *     this off if you do not use toString in your project and want to trim it
  *     from the compiled JS.
  */
-jspb.Message.GENERATE_TO_STRING =
-    goog.define('jspb.Message.GENERATE_TO_STRING', true);
+Message.GENERATE_TO_STRING =
+  goog.define('Message.GENERATE_TO_STRING', true);
 
 
 /**
@@ -207,8 +112,8 @@
  *     local (e.g. not from another iframe) and thus safely classified with
  *     instanceof Array.
  */
-jspb.Message.ASSUME_LOCAL_ARRAYS =
-    goog.define('jspb.Message.ASSUME_LOCAL_ARRAYS', false);
+Message.ASSUME_LOCAL_ARRAYS =
+  goog.define('Message.ASSUME_LOCAL_ARRAYS', false);
 
 
 // TODO(jakubvrana): Turn this off by default.
@@ -219,8 +124,8 @@
  *     backwards compatible. Projects are advised to turn this flag always off.
  * @private
  */
-jspb.Message.SERIALIZE_EMPTY_TRAILING_FIELDS =
-    goog.define('jspb.Message.SERIALIZE_EMPTY_TRAILING_FIELDS', true);
+Message.SERIALIZE_EMPTY_TRAILING_FIELDS =
+  goog.define('Message.SERIALIZE_EMPTY_TRAILING_FIELDS', true);
 
 
 /**
@@ -228,7 +133,7 @@
  * @type {boolean}
  * @private
  */
-jspb.Message.SUPPORTS_UINT8ARRAY_ = (typeof Uint8Array == 'function');
+Message.SUPPORTS_UINT8ARRAY_ = (typeof Uint8Array == 'function');
 
 
 /**
@@ -236,7 +141,7 @@
  * @type {!Array}
  * @private
  */
-jspb.Message.prototype.array;
+Message.prototype.array;
 
 
 /**
@@ -246,7 +151,7 @@
  * @type {Object}
  * @private
  */
-jspb.Message.prototype.wrappers_;
+Message.prototype.wrappers_;
 
 
 /**
@@ -255,7 +160,7 @@
  * @type {Object}
  * @private
  */
-jspb.Message.prototype.extensionObject_;
+Message.prototype.extensionObject_;
 
 
 /**
@@ -264,7 +169,7 @@
  * @type {number}
  * @private
  */
-jspb.Message.prototype.pivot_;
+Message.prototype.pivot_;
 
 
 /**
@@ -273,7 +178,7 @@
  *     has no id.
  * @private
  */
-jspb.Message.prototype.messageId_;
+Message.prototype.messageId_;
 
 
 /**
@@ -282,13 +187,13 @@
  * and for booleans stored as numbers (0 or 1).
  * @private {!Object<number,boolean>|undefined}
  */
-jspb.Message.prototype.convertedPrimitiveFields_;
+Message.prototype.convertedPrimitiveFields_;
 
 /**
  * Repeated fields numbers.
  * @protected {?Array<number>|undefined}
  */
-jspb.Message.prototype.repeatedFields;
+Message.prototype.repeatedFields;
 
 
 
@@ -298,7 +203,7 @@
  *     has no id.
  * @export
  */
-jspb.Message.prototype.getJsPbMessageId = function() {
+Message.prototype.getJsPbMessageId = function () {
   return this.messageId_;
 };
 
@@ -310,41 +215,41 @@
  * @type {number}
  * @private
  */
-jspb.Message.prototype.arrayIndexOffset_;
+Message.prototype.arrayIndexOffset_;
 
 
 /**
  * Returns the index into msg.array at which the proto field with tag number
  * fieldNumber will be located.
- * @param {!jspb.Message} msg Message for which we're calculating an index.
+ * @param {!Message} msg Message for which we're calculating an index.
  * @param {number} fieldNumber The field number.
  * @return {number} The index.
  * @private
  */
-jspb.Message.getIndex_ = function(msg, fieldNumber) {
+Message.getIndex_ = function (msg, fieldNumber) {
   return fieldNumber + msg.arrayIndexOffset_;
 };
 
 // This is only here to ensure we are not back sliding on ES6 requirements for
 // protos in g3.
-jspb.Message.hiddenES6Property_ = class {};
+Message.hiddenES6Property_ = class { };
 
 
 /**
  * Returns the tag number based on the index in msg.array.
- * @param {!jspb.Message} msg Message for which we're calculating an index.
+ * @param {!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) {
+Message.getFieldNumber_ = function (msg, index) {
   return index - msg.arrayIndexOffset_;
 };
 
 
 /**
  * Initializes a JsPb Message.
- * @param {!jspb.Message} msg The JsPb proto to modify.
+ * @param {!Message} msg The JsPb proto to modify.
  * @param {Array|undefined} data An initial data array.
  * @param {string|number} messageId For response messages, the message id or ''
  *     if no message id is specified. For non-response messages, 0.
@@ -357,7 +262,7 @@
  *     each of the message's oneof unions.
  * @export
  */
-jspb.Message.initialize = function(
+Message.initialize = function (
     msg, data, messageId, suggestedPivot, repeatedFields, opt_oneofFields) {
   msg.wrappers_ = null;
   if (!data) {
@@ -369,10 +274,10 @@
   // which would otherwise go unused.
   msg.arrayIndexOffset_ = messageId === 0 ? -1 : 0;
   msg.array = data;
-  jspb.Message.initPivotAndExtensionObject_(msg, suggestedPivot);
+  Message.initPivotAndExtensionObject_(msg, suggestedPivot);
   msg.convertedPrimitiveFields_ = {};
 
-  if (!jspb.Message.SERIALIZE_EMPTY_TRAILING_FIELDS) {
+  if (!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 serialization,
     // consider switching to a set.
@@ -383,13 +288,13 @@
     for (var i = 0; i < repeatedFields.length; i++) {
       var fieldNumber = repeatedFields[i];
       if (fieldNumber < msg.pivot_) {
-        var index = jspb.Message.getIndex_(msg, fieldNumber);
+        var index = Message.getIndex_(msg, fieldNumber);
         msg.array[index] =
-            msg.array[index] || jspb.Message.EMPTY_LIST_SENTINEL_;
+          msg.array[index] || Message.EMPTY_LIST_SENTINEL_;
       } else {
-        jspb.Message.maybeInitEmptyExtensionObject_(msg);
+        Message.maybeInitEmptyExtensionObject_(msg);
         msg.extensionObject_[fieldNumber] = msg.extensionObject_[fieldNumber] ||
-            jspb.Message.EMPTY_LIST_SENTINEL_;
+          Message.EMPTY_LIST_SENTINEL_;
       }
     }
   }
@@ -398,7 +303,7 @@
     // Compute the oneof case for each union. This ensures only one value is
     // set in the union.
     for (var i = 0; i < opt_oneofFields.length; i++) {
-      jspb.Message.computeOneofCase(msg, opt_oneofFields[i]);
+      Message.computeOneofCase(msg, opt_oneofFields[i]);
     }
   }
 };
@@ -412,7 +317,7 @@
  * present.
  * @private @const {!Object}
  */
-jspb.Message.EMPTY_LIST_SENTINEL_ =
+Message.EMPTY_LIST_SENTINEL_ =
     goog.DEBUG && Object.freeze ? Object.freeze([]) : [];
 
 
@@ -422,8 +327,8 @@
  * @return {boolean} True if the provided object is an array.
  * @private
  */
-jspb.Message.isArray_ = function(o) {
-  return jspb.Message.ASSUME_LOCAL_ARRAYS ? o instanceof Array :
+Message.isArray_ = function (o) {
+  return Message.ASSUME_LOCAL_ARRAYS ? o instanceof Array :
                                             Array.isArray(o);
 };
 
@@ -433,7 +338,7 @@
  * @return {boolean} True if the provided object is an extension object.
  * @private
  */
-jspb.Message.isExtensionObject_ = function(o) {
+Message.isExtensionObject_ = function (o) {
   // Normal fields are never objects, so we can be sure that if we find an
   // object here, then it's the extension object. However, we must ensure that
   // the object is not an array, since arrays are valid field values (bytes
@@ -441,8 +346,8 @@
   // NOTE(lukestebbing): We avoid looking at .length to avoid a JIT bug
   // in Safari on iOS 8. See the description of CL/86511464 for details.
   return (
-      o !== null && typeof o == 'object' && !jspb.Message.isArray_(o) &&
-      !(jspb.Message.SUPPORTS_UINT8ARRAY_ && o instanceof Uint8Array));
+    o !== null && typeof o == 'object' && !Message.isArray_(o) &&
+    !(Message.SUPPORTS_UINT8ARRAY_ && o instanceof Uint8Array));
 };
 
 
@@ -452,11 +357,11 @@
  * decides the pivot of the message based on suggestedPivot without
  * materializing the extension object.
  *
- * @param {!jspb.Message} msg The JsPb proto to modify.
+ * @param {!Message} msg The JsPb proto to modify.
  * @param {number} suggestedPivot See description for initialize().
  * @private
  */
-jspb.Message.initPivotAndExtensionObject_ = function(msg, suggestedPivot) {
+Message.initPivotAndExtensionObject_ = function (msg, suggestedPivot) {
   // There are 3 variants that need to be dealt with which are the
   // combination of whether there exists an extension object (EO) and
   // whether there is a suggested pivot (SP).
@@ -470,8 +375,8 @@
   if (msgLength) {
     lastIndex = msgLength - 1;
     var obj = msg.array[lastIndex];
-    if (jspb.Message.isExtensionObject_(obj)) {
-      msg.pivot_ = jspb.Message.getFieldNumber_(msg, lastIndex);
+    if (Message.isExtensionObject_(obj)) {
+      msg.pivot_ = Message.getFieldNumber_(msg, lastIndex);
       msg.extensionObject_ = obj;
       return;
     }
@@ -481,7 +386,7 @@
     // If a extension object is not present, set the pivot value as being
     // after the last value in the array to avoid overwriting values, etc.
     msg.pivot_ = Math.max(
-        suggestedPivot, jspb.Message.getFieldNumber_(msg, lastIndex + 1));
+      suggestedPivot, Message.getFieldNumber_(msg, lastIndex + 1));
     // Avoid changing the shape of the proto with an empty extension object by
     // deferring the materialization of the extension object until the first
     // time a field set into it (may be due to getting a repeated proto field
@@ -497,11 +402,11 @@
 
 /**
  * Creates an empty extensionObject_ if non exists.
- * @param {!jspb.Message} msg The JsPb proto to modify.
+ * @param {!Message} msg The JsPb proto to modify.
  * @private
  */
-jspb.Message.maybeInitEmptyExtensionObject_ = function(msg) {
-  var pivotIndex = jspb.Message.getIndex_(msg, msg.pivot_);
+Message.maybeInitEmptyExtensionObject_ = function (msg) {
+  var pivotIndex = Message.getIndex_(msg, msg.pivot_);
   if (!msg.array[pivotIndex]) {
     msg.extensionObject_ = msg.array[pivotIndex] = {};
   }
@@ -522,8 +427,8 @@
  * @template T
  * @export
  */
-jspb.Message.toObjectList = function(field, toObjectFn, opt_includeInstance) {
-  // Not using goog.array.map in the generated code to keep it small.
+Message.toObjectList = function (field, toObjectFn, opt_includeInstance) {
+// Not using googArray.map in the generated code to keep it small.
   // And not using it here to avoid a function call.
   var result = [];
   for (var i = 0; i < field.length; i++) {
@@ -535,17 +440,17 @@
 
 /**
  * Adds a proto's extension data to a Soy rendering object.
- * @param {!jspb.Message} proto The proto whose extensions to convert.
+ * @param {!Message} proto The proto whose extensions to convert.
  * @param {!Object} obj The Soy object to add converted extension data to.
  * @param {!Object} extensions The proto class' registered extensions.
- * @param {function(this:?, jspb.ExtensionFieldInfo) : *} getExtensionFn
+ * @param {function(this:?, ExtensionFieldInfo) : *} getExtensionFn
  *     The proto class' getExtension function. Passed for effective dead code
  *     removal.
  * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
  *     for transitional soy proto support: http://goto/soy-param-migration
  * @export
  */
-jspb.Message.toObjectExtension = function(
+Message.toObjectExtension = function (
     proto, obj, extensions, getExtensionFn, opt_includeInstance) {
   for (var fieldNumber in extensions) {
     var fieldInfo = extensions[fieldNumber];
@@ -560,12 +465,12 @@
         obj[name] = value;
       } else {
         if (fieldInfo.isRepeated) {
-          obj[name] = jspb.Message.toObjectList(
-              /** @type {!Array<!jspb.Message>} */ (value),
+          obj[name] = Message.toObjectList(
+              /** @type {!Array<!Message>} */(value),
               fieldInfo.toObjectFn, opt_includeInstance);
         } else {
           obj[name] = fieldInfo.toObjectFn(
-              opt_includeInstance, /** @type {!jspb.Message} */ (value));
+            opt_includeInstance, /** @type {!Message} */(value));
         }
       }
     }
@@ -575,15 +480,15 @@
 
 /**
  * Writes a proto's extension data to a binary-format output stream.
- * @param {!jspb.Message} proto The proto whose extensions to convert.
+ * @param {!Message} proto The proto whose extensions to convert.
  * @param {*} writer The binary-format writer to write to.
  * @param {!Object} extensions The proto class' registered extensions.
- * @param {function(this:jspb.Message,!jspb.ExtensionFieldInfo) : *}
+ * @param {function(this:Message,!ExtensionFieldInfo) : *}
  *     getExtensionFn The proto class' getExtension function. Passed for
  *     effective dead code removal.
  * @export
  */
-jspb.Message.serializeBinaryExtensions = function(
+Message.serializeBinaryExtensions = function (
     proto, writer, extensions, getExtensionFn) {
   for (var fieldNumber in extensions) {
     var binaryFieldInfo = extensions[fieldNumber];
@@ -628,15 +533,15 @@
 /**
  * Reads an extension field from the given reader and, if a valid extension,
  * sets the extension value.
- * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Message} msg A jspb proto.
  * @param {!jspb.BinaryReader} reader
  * @param {!Object} extensions The extensions object.
- * @param {function(this:jspb.Message,!jspb.ExtensionFieldInfo)} getExtensionFn
- * @param {function(this:jspb.Message,!jspb.ExtensionFieldInfo, ?)}
+ * @param {function(this:Message,!ExtensionFieldInfo)} getExtensionFn
+ * @param {function(this:Message,!ExtensionFieldInfo, ?)}
  *     setExtensionFn
  * @export
  */
-jspb.Message.readBinaryExtension = function(
+Message.readBinaryExtension = function (
     msg, reader, extensions, getExtensionFn, setExtensionFn) {
   var binaryFieldInfo = extensions[reader.getFieldNumber()];
   if (!binaryFieldInfo) {
@@ -682,17 +587,17 @@
 
 /**
  * Gets the value of a non-extension field.
- * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Message} msg A jspb proto.
  * @param {number} fieldNumber The field number.
  * @return {string|number|boolean|Uint8Array|Array|null|undefined}
  * The field's value.
  * @export
  */
-jspb.Message.getField = function(msg, fieldNumber) {
+Message.getField = function (msg, fieldNumber) {
   if (fieldNumber < msg.pivot_) {
-    var index = jspb.Message.getIndex_(msg, fieldNumber);
+    var index = Message.getIndex_(msg, fieldNumber);
     var val = msg.array[index];
-    if (val === jspb.Message.EMPTY_LIST_SENTINEL_) {
+    if (val === Message.EMPTY_LIST_SENTINEL_) {
       return msg.array[index] = [];
     }
     return val;
@@ -701,7 +606,7 @@
       return undefined;
     }
     var val = msg.extensionObject_[fieldNumber];
-    if (val === jspb.Message.EMPTY_LIST_SENTINEL_) {
+    if (val === Message.EMPTY_LIST_SENTINEL_) {
       return msg.extensionObject_[fieldNumber] = [];
     }
     return val;
@@ -711,26 +616,26 @@
 
 /**
  * Gets the value of a non-extension repeated field.
- * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Message} msg A jspb proto.
  * @param {number} fieldNumber The field number.
  * @return {!Array}
  * The field's value.
  * @export
  */
-jspb.Message.getRepeatedField = function(msg, fieldNumber) {
-  return /** @type {!Array} */ (jspb.Message.getField(msg, fieldNumber));
+Message.getRepeatedField = function (msg, fieldNumber) {
+  return /** @type {!Array} */ (Message.getField(msg, fieldNumber));
 };
 
 
 /**
  * Gets the value of an optional float or double field.
- * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Message} msg A jspb proto.
  * @param {number} fieldNumber The field number.
  * @return {?number|undefined} The field's value.
  * @export
  */
-jspb.Message.getOptionalFloatingPointField = function(msg, fieldNumber) {
-  var value = jspb.Message.getField(msg, fieldNumber);
+Message.getOptionalFloatingPointField = function (msg, fieldNumber) {
+  var value = Message.getField(msg, fieldNumber);
   // Converts "NaN", "Infinity" and "-Infinity" to their corresponding numbers.
   return value == null ? value : +value;
 };
@@ -738,13 +643,13 @@
 
 /**
  * Gets the value of an optional boolean field.
- * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Message} msg A jspb proto.
  * @param {number} fieldNumber The field number.
  * @return {?boolean|undefined} The field's value.
  * @export
  */
-jspb.Message.getBooleanField = function(msg, fieldNumber) {
-  var value = jspb.Message.getField(msg, fieldNumber);
+Message.getBooleanField = function (msg, fieldNumber) {
+  var value = Message.getField(msg, fieldNumber);
   // TODO(b/122673075): always return null when the value is null-ish.
   return value == null ? (value) : !!value;
 };
@@ -752,13 +657,13 @@
 
 /**
  * Gets the value of a repeated float or double field.
- * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Message} msg A jspb proto.
  * @param {number} fieldNumber The field number.
  * @return {!Array<number>} The field's value.
  * @export
  */
-jspb.Message.getRepeatedFloatingPointField = function(msg, fieldNumber) {
-  var values = jspb.Message.getRepeatedField(msg, fieldNumber);
+Message.getRepeatedFloatingPointField = function (msg, fieldNumber) {
+  var values = Message.getRepeatedField(msg, fieldNumber);
   if (!msg.convertedPrimitiveFields_) {
     msg.convertedPrimitiveFields_ = {};
   }
@@ -775,13 +680,13 @@
 
 /**
  * Gets the value of a repeated boolean field.
- * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Message} msg A jspb proto.
  * @param {number} fieldNumber The field number.
  * @return {!Array<boolean>} The field's value.
  * @export
  */
-jspb.Message.getRepeatedBooleanField = function(msg, fieldNumber) {
-  var values = jspb.Message.getRepeatedField(msg, fieldNumber);
+Message.getRepeatedBooleanField = function (msg, fieldNumber) {
+  var values = Message.getRepeatedField(msg, fieldNumber);
   if (!msg.convertedPrimitiveFields_) {
     msg.convertedPrimitiveFields_ = {};
   }
@@ -802,14 +707,14 @@
  * @return {?string} The field's coerced value.
  * @export
  */
-jspb.Message.bytesAsB64 = function(value) {
+Message.bytesAsB64 = function (value) {
   if (value == null || typeof value === 'string') {
     return value;
   }
-  if (jspb.Message.SUPPORTS_UINT8ARRAY_ && value instanceof Uint8Array) {
-    return goog.crypt.base64.encodeByteArray(value);
+  if (Message.SUPPORTS_UINT8ARRAY_ && value instanceof Uint8Array) {
+    return googCryptBase64.encodeByteArray(value);
   }
-  jspb.asserts.fail('Cannot coerce to b64 string: ' + goog.typeOf(value));
+  asserts.fail('Cannot coerce to b64 string: ' + goog.typeOf(value));
   return null;
 };
 
@@ -822,14 +727,14 @@
  * @return {?Uint8Array} The field's coerced value.
  * @export
  */
-jspb.Message.bytesAsU8 = function(value) {
+Message.bytesAsU8 = function (value) {
   if (value == null || value instanceof Uint8Array) {
     return value;
   }
   if (typeof value === 'string') {
-    return goog.crypt.base64.decodeStringToUint8Array(value);
+    return googCryptBase64.decodeStringToUint8Array(value);
   }
-  jspb.asserts.fail('Cannot coerce to Uint8Array: ' + goog.typeOf(value));
+  asserts.fail('Cannot coerce to Uint8Array: ' + goog.typeOf(value));
   return null;
 };
 
@@ -841,12 +746,12 @@
  * @return {!Array<string?>} The field's coerced value.
  * @export
  */
-jspb.Message.bytesListAsB64 = function(value) {
-  jspb.Message.assertConsistentTypes_(value);
+Message.bytesListAsB64 = function (value) {
+  Message.assertConsistentTypes_(value);
   if (!value.length || typeof value[0] === 'string') {
     return /** @type {!Array<string>} */ (value);
   }
-  return goog.array.map(value, jspb.Message.bytesAsB64);
+  return googArray.map(value, Message.bytesAsB64);
 };
 
 
@@ -859,12 +764,12 @@
  * @return {!Array<Uint8Array?>} The field's coerced value.
  * @export
  */
-jspb.Message.bytesListAsU8 = function(value) {
-  jspb.Message.assertConsistentTypes_(value);
+Message.bytesListAsU8 = function (value) {
+  Message.assertConsistentTypes_(value);
   if (!value.length || value[0] instanceof Uint8Array) {
     return /** @type {!Array<!Uint8Array>} */ (value);
   }
-  return goog.array.map(value, jspb.Message.bytesAsU8);
+  return googArray.map(value, Message.bytesAsU8);
 };
 
 
@@ -873,12 +778,12 @@
  * @param {Array?} array The array to test.
  * @private
  */
-jspb.Message.assertConsistentTypes_ = function(array) {
+Message.assertConsistentTypes_ = function (array) {
   if (goog.DEBUG && array && array.length > 1) {
     var expected = goog.typeOf(array[0]);
-    goog.array.forEach(array, function(e) {
+    googArray.forEach(array, function (e) {
       if (goog.typeOf(e) != expected) {
-        jspb.asserts.fail(
+        asserts.fail(
             'Inconsistent type in JSPB repeated field array. ' +
             'Got ' + goog.typeOf(e) + ' expected ' + expected);
       }
@@ -892,14 +797,14 @@
  * primitives) semantics. Returns `defaultValue` if the field is not otherwise
  * set.
  * @template T
- * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Message} msg A jspb proto.
  * @param {number} fieldNumber The field number.
  * @param {T} defaultValue The default value.
  * @return {T} The field's value.
  * @export
  */
-jspb.Message.getFieldWithDefault = function(msg, fieldNumber, defaultValue) {
-  var value = jspb.Message.getField(msg, fieldNumber);
+Message.getFieldWithDefault = function (msg, fieldNumber, defaultValue) {
+  var value = Message.getField(msg, fieldNumber);
   if (value == null) {
     return defaultValue;
   } else {
@@ -912,15 +817,15 @@
  * Gets the value of a boolean field, with proto3 (non-nullable primitives)
  * semantics. Returns `defaultValue` if the field is not otherwise set.
  * @template T
- * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Message} msg A jspb proto.
  * @param {number} fieldNumber The field number.
  * @param {boolean} defaultValue The default value.
  * @return {boolean} The field's value.
  * @export
  */
-jspb.Message.getBooleanFieldWithDefault = function(
+Message.getBooleanFieldWithDefault = function (
     msg, fieldNumber, defaultValue) {
-  var value = jspb.Message.getBooleanField(msg, fieldNumber);
+  var value = Message.getBooleanField(msg, fieldNumber);
   if (value == null) {
     return defaultValue;
   } else {
@@ -934,15 +839,15 @@
  * primitives) semantics. Returns `defaultValue` if the field is not otherwise
  * set.
  * @template T
- * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Message} msg A jspb proto.
  * @param {number} fieldNumber The field number.
  * @param {number} defaultValue The default value.
  * @return {number} The field's value.
  * @export
  */
-jspb.Message.getFloatingPointFieldWithDefault = function(
+Message.getFloatingPointFieldWithDefault = function (
     msg, fieldNumber, defaultValue) {
-  var value = jspb.Message.getOptionalFloatingPointField(msg, fieldNumber);
+  var value = Message.getOptionalFloatingPointField(msg, fieldNumber);
   if (value == null) {
     return defaultValue;
   } else {
@@ -954,13 +859,13 @@
 /**
  * Alias for getFieldWithDefault used by older generated code.
  * @template T
- * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Message} msg A jspb proto.
  * @param {number} fieldNumber The field number.
  * @param {T} defaultValue The default value.
  * @return {T} The field's value.
  * @export
  */
-jspb.Message.getFieldProto3 = jspb.Message.getFieldWithDefault;
+Message.getFieldProto3 = Message.getFieldWithDefault;
 
 
 /**
@@ -972,14 +877,14 @@
  * construction time, and the map may be constructed here).
  *
  * @template K, V
- * @param {!jspb.Message} msg
+ * @param {!Message} msg
  * @param {number} fieldNumber
  * @param {boolean|undefined} noLazyCreate
  * @param {?=} opt_valueCtor
- * @return {!jspb.Map<K, V>|undefined}
+ * @return {!Map<K, V>|undefined}
  * @export
  */
-jspb.Message.getMapField = function(
+Message.getMapField = function (
     msg, fieldNumber, noLazyCreate, opt_valueCtor) {
   if (!msg.wrappers_) {
     msg.wrappers_ = {};
@@ -988,16 +893,16 @@
   if (fieldNumber in msg.wrappers_) {
     return msg.wrappers_[fieldNumber];
   }
-  var arr = jspb.Message.getField(msg, fieldNumber);
+  var arr = Message.getField(msg, fieldNumber);
   // Wrap the underlying elements array with a Map.
   if (!arr) {
     if (noLazyCreate) {
       return undefined;
     }
     arr = [];
-    jspb.Message.setField(msg, fieldNumber, arr);
+    Message.setField(msg, fieldNumber, arr);
   }
-  return msg.wrappers_[fieldNumber] = new jspb.Map(
+  return msg.wrappers_[fieldNumber] = new Map(
              /** @type {!Array<!Array<!Object>>} */ (arr), opt_valueCtor);
 };
 
@@ -1011,13 +916,13 @@
  * @template T
  * @export
  */
-jspb.Message.setField = function(msg, fieldNumber, value) {
+Message.setField = function (msg, fieldNumber, value) {
   // TODO(b/35241823): replace this with a bounded generic when available
-  jspb.asserts.assertInstanceof(msg, jspb.Message);
+  asserts.assertInstanceof(msg, Message);
   if (fieldNumber < msg.pivot_) {
-    msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = value;
+    msg.array[Message.getIndex_(msg, fieldNumber)] = value;
   } else {
-    jspb.Message.maybeInitEmptyExtensionObject_(msg);
+    Message.maybeInitEmptyExtensionObject_(msg);
     msg.extensionObject_[fieldNumber] = value;
   }
   return msg;
@@ -1033,8 +938,8 @@
  * @template T
  * @export
  */
-jspb.Message.setProto3IntField = function(msg, fieldNumber, value) {
-  return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, 0);
+Message.setProto3IntField = function (msg, fieldNumber, value) {
+  return Message.setFieldIgnoringDefault_(msg, fieldNumber, value, 0);
 };
 
 
@@ -1047,8 +952,8 @@
  * @template T
  * @export
  */
-jspb.Message.setProto3FloatField = function(msg, fieldNumber, value) {
-  return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, 0.0);
+Message.setProto3FloatField = function (msg, fieldNumber, value) {
+  return Message.setFieldIgnoringDefault_(msg, fieldNumber, value, 0.0);
 };
 
 
@@ -1061,8 +966,8 @@
  * @template T
  * @export
  */
-jspb.Message.setProto3BooleanField = function(msg, fieldNumber, value) {
-  return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, false);
+Message.setProto3BooleanField = function (msg, fieldNumber, value) {
+  return Message.setFieldIgnoringDefault_(msg, fieldNumber, value, false);
 };
 
 
@@ -1075,8 +980,8 @@
  * @template T
  * @export
  */
-jspb.Message.setProto3StringField = function(msg, fieldNumber, value) {
-  return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, '');
+Message.setProto3StringField = function (msg, fieldNumber, value) {
+  return Message.setFieldIgnoringDefault_(msg, fieldNumber, value, '');
 };
 
 
@@ -1089,8 +994,8 @@
  * @template T
  * @export
  */
-jspb.Message.setProto3BytesField = function(msg, fieldNumber, value) {
-  return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, '');
+Message.setProto3BytesField = function (msg, fieldNumber, value) {
+  return Message.setFieldIgnoringDefault_(msg, fieldNumber, value, '');
 };
 
 
@@ -1103,8 +1008,8 @@
  * @template T
  * @export
  */
-jspb.Message.setProto3EnumField = function(msg, fieldNumber, value) {
-  return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, 0);
+Message.setProto3EnumField = function (msg, fieldNumber, value) {
+  return Message.setFieldIgnoringDefault_(msg, fieldNumber, value, 0);
 };
 
 
@@ -1118,8 +1023,8 @@
  * @template T
  * @export
  */
-jspb.Message.setProto3StringIntField = function(msg, fieldNumber, value) {
-  return jspb.Message.setFieldIgnoringDefault_(msg, fieldNumber, value, '0');
+Message.setProto3StringIntField = function (msg, fieldNumber, value) {
+  return Message.setFieldIgnoringDefault_(msg, fieldNumber, value, '0');
 };
 
 /**
@@ -1134,16 +1039,16 @@
  * @template T
  * @private
  */
-jspb.Message.setFieldIgnoringDefault_ = function(
+Message.setFieldIgnoringDefault_ = function (
     msg, fieldNumber, value, defaultValue) {
   // TODO(b/35241823): replace this with a bounded generic when available
-  jspb.asserts.assertInstanceof(msg, jspb.Message);
+  asserts.assertInstanceof(msg, Message);
   if (value !== defaultValue) {
-    jspb.Message.setField(msg, fieldNumber, value);
+    Message.setField(msg, fieldNumber, value);
   } else if (fieldNumber < msg.pivot_) {
-    msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = null;
+    msg.array[Message.getIndex_(msg, fieldNumber)] = null;
   } else {
-    jspb.Message.maybeInitEmptyExtensionObject_(msg);
+    Message.maybeInitEmptyExtensionObject_(msg);
     delete msg.extensionObject_[fieldNumber];
   }
   return msg;
@@ -1160,10 +1065,10 @@
  * @template T
  * @export
  */
-jspb.Message.addToRepeatedField = function(msg, fieldNumber, value, opt_index) {
+Message.addToRepeatedField = function (msg, fieldNumber, value, opt_index) {
   // TODO(b/35241823): replace this with a bounded generic when available
-  jspb.asserts.assertInstanceof(msg, jspb.Message);
-  var arr = jspb.Message.getRepeatedField(msg, fieldNumber);
+  asserts.assertInstanceof(msg, Message);
+  var arr = Message.getRepeatedField(msg, fieldNumber);
   if (opt_index != undefined) {
     arr.splice(opt_index, 0, value);
   } else {
@@ -1184,17 +1089,17 @@
  * @template T
  * @export
  */
-jspb.Message.setOneofField = function(msg, fieldNumber, oneof, value) {
+Message.setOneofField = function (msg, fieldNumber, oneof, value) {
   // TODO(b/35241823): replace this with a bounded generic when available
-  jspb.asserts.assertInstanceof(msg, jspb.Message);
-  var currentCase = jspb.Message.computeOneofCase(msg, oneof);
+  asserts.assertInstanceof(msg, Message);
+  var currentCase = Message.computeOneofCase(msg, oneof);
   if (currentCase && currentCase !== fieldNumber && value !== undefined) {
     if (msg.wrappers_ && currentCase in msg.wrappers_) {
       msg.wrappers_[currentCase] = undefined;
     }
-    jspb.Message.setField(msg, currentCase, undefined);
+    Message.setField(msg, currentCase, undefined);
   }
-  return jspb.Message.setField(msg, fieldNumber, value);
+  return Message.setField(msg, fieldNumber, value);
 };
 
 
@@ -1210,30 +1115,30 @@
  * with the greatest field number (directly corresponding to the greatest
  * array index).
  *
- * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Message} msg A jspb proto.
  * @param {!Array<number>} oneof The field numbers belonging to the union.
  * @return {number} The field number currently set in the union, or 0 if none.
  * @export
  */
-jspb.Message.computeOneofCase = function(msg, oneof) {
+Message.computeOneofCase = function (msg, oneof) {
   var oneofField;
   var oneofValue;
 
   for (var i = 0; i < oneof.length; i++) {
     var fieldNumber = oneof[i];
-    var value = jspb.Message.getField(msg, fieldNumber);
+    var value = Message.getField(msg, fieldNumber);
     if (value != null) {
       oneofField = fieldNumber;
       oneofValue = value;
-      jspb.Message.setField(msg, fieldNumber, undefined);
+      Message.setField(msg, fieldNumber, undefined);
     }
   }
 
   if (oneofField) {
-    // NB: We know the value is unique, so we can call jspb.Message.setField
+    // NB: We know the value is unique, so we can call Message.setField
     // directly instead of jpsb.Message.setOneofField. Also, setOneofField
     // calls this function.
-    jspb.Message.setField(msg, oneofField, oneofValue);
+    Message.setField(msg, oneofField, oneofValue);
     return oneofField;
   }
 
@@ -1243,61 +1148,61 @@
 
 /**
  * Gets and wraps a proto field on access.
- * @param {!jspb.Message} msg A jspb proto.
- * @param {function(new:jspb.Message, Array)} ctor Constructor for the field.
+ * @param {!Message} msg A jspb proto.
+ * @param {function(new:Message, Array)} ctor Constructor for the field.
  * @param {number} fieldNumber The field number.
  * @param {number=} opt_required True (1) if this is a required field.
- * @return {jspb.Message} The field as a jspb proto.
+ * @return {Message} The field as a jspb proto.
  * @export
  */
-jspb.Message.getWrapperField = function(msg, ctor, fieldNumber, opt_required) {
+Message.getWrapperField = function (msg, ctor, fieldNumber, opt_required) {
   // TODO(mwr): Consider copying data and/or arrays.
   if (!msg.wrappers_) {
     msg.wrappers_ = {};
   }
   if (!msg.wrappers_[fieldNumber]) {
-    var data = /** @type {Array} */ (jspb.Message.getField(msg, fieldNumber));
+    var data = /** @type {Array} */ (Message.getField(msg, fieldNumber));
     if (opt_required || data) {
       // TODO(mwr): Remove existence test for always valid default protos.
       msg.wrappers_[fieldNumber] = new ctor(data);
     }
   }
-  return /** @type {jspb.Message} */ (msg.wrappers_[fieldNumber]);
+  return /** @type {Message} */ (msg.wrappers_[fieldNumber]);
 };
 
 
 /**
  * Gets and wraps a repeated proto field on access.
- * @param {!jspb.Message} msg A jspb proto.
- * @param {function(new:jspb.Message, Array)} ctor Constructor for the field.
+ * @param {!Message} msg A jspb proto.
+ * @param {function(new:Message, Array)} ctor Constructor for the field.
  * @param {number} fieldNumber The field number.
- * @return {!Array<!jspb.Message>} The repeated field as an array of protos.
+ * @return {!Array<!Message>} The repeated field as an array of protos.
  * @export
  */
-jspb.Message.getRepeatedWrapperField = function(msg, ctor, fieldNumber) {
-  jspb.Message.wrapRepeatedField_(msg, ctor, fieldNumber);
+Message.getRepeatedWrapperField = function (msg, ctor, fieldNumber) {
+  Message.wrapRepeatedField_(msg, ctor, fieldNumber);
   var val = msg.wrappers_[fieldNumber];
-  if (val == jspb.Message.EMPTY_LIST_SENTINEL_) {
+  if (val == Message.EMPTY_LIST_SENTINEL_) {
     val = msg.wrappers_[fieldNumber] = [];
   }
-  return /** @type {!Array<!jspb.Message>} */ (val);
+  return /** @type {!Array<!Message>} */ (val);
 };
 
 
 /**
  * Wraps underlying array into proto message representation if it wasn't done
  * before.
- * @param {!jspb.Message} msg A jspb proto.
- * @param {function(new:jspb.Message, ?Array)} ctor Constructor for the field.
+ * @param {!Message} msg A jspb proto.
+ * @param {function(new:Message, ?Array)} ctor Constructor for the field.
  * @param {number} fieldNumber The field number.
  * @private
  */
-jspb.Message.wrapRepeatedField_ = function(msg, ctor, fieldNumber) {
+Message.wrapRepeatedField_ = function (msg, ctor, fieldNumber) {
   if (!msg.wrappers_) {
     msg.wrappers_ = {};
   }
   if (!msg.wrappers_[fieldNumber]) {
-    var data = jspb.Message.getRepeatedField(msg, fieldNumber);
+    var data = Message.getRepeatedField(msg, fieldNumber);
     for (var wrappers = [], i = 0; i < data.length; i++) {
       wrappers[i] = new ctor(data[i]);
     }
@@ -1310,21 +1215,21 @@
  * Sets a proto field and syncs it to the backing array.
  * @param {T} msg A jspb proto.
  * @param {number} fieldNumber The field number.
- * @param {?jspb.Message|?jspb.Map|undefined} value A new value for this proto
+ * @param {?Message|?Map|undefined} value A new value for this proto
  * field.
  * @return {T} the msg
  * @template T
  * @export
  */
-jspb.Message.setWrapperField = function(msg, fieldNumber, value) {
+Message.setWrapperField = function (msg, fieldNumber, value) {
   // TODO(b/35241823): replace this with a bounded generic when available
-  jspb.asserts.assertInstanceof(msg, jspb.Message);
+  asserts.assertInstanceof(msg, Message);
   if (!msg.wrappers_) {
     msg.wrappers_ = {};
   }
   var data = value ? value.toArray() : value;
   msg.wrappers_[fieldNumber] = value;
-  return jspb.Message.setField(msg, fieldNumber, data);
+  return Message.setField(msg, fieldNumber, data);
 };
 
 
@@ -1334,20 +1239,20 @@
  * @param {T} msg A jspb proto.
  * @param {number} fieldNumber The field number.
  * @param {!Array<number>} oneof The fields belonging to the union.
- * @param {jspb.Message|undefined} value A new value for this proto field.
+ * @param {Message|undefined} value A new value for this proto field.
  * @return {T} the msg
  * @template T
  * @export
  */
-jspb.Message.setOneofWrapperField = function(msg, fieldNumber, oneof, value) {
+Message.setOneofWrapperField = function (msg, fieldNumber, oneof, value) {
   // TODO(b/35241823): replace this with a bounded generic when available
-  jspb.asserts.assertInstanceof(msg, jspb.Message);
+  asserts.assertInstanceof(msg, Message);
   if (!msg.wrappers_) {
     msg.wrappers_ = {};
   }
   var data = value ? value.toArray() : value;
   msg.wrappers_[fieldNumber] = value;
-  return jspb.Message.setOneofField(msg, fieldNumber, oneof, data);
+  return Message.setOneofField(msg, fieldNumber, oneof, data);
 };
 
 
@@ -1355,14 +1260,14 @@
  * Sets a repeated proto field and syncs it to the backing array.
  * @param {T} msg A jspb proto.
  * @param {number} fieldNumber The field number.
- * @param {Array<!jspb.Message>|undefined} value An array of protos.
+ * @param {Array<!Message>|undefined} value An array of protos.
  * @return {T} the msg
  * @template T
  * @export
  */
-jspb.Message.setRepeatedWrapperField = function(msg, fieldNumber, value) {
+Message.setRepeatedWrapperField = function (msg, fieldNumber, value) {
   // TODO(b/35241823): replace this with a bounded generic when available
-  jspb.asserts.assertInstanceof(msg, jspb.Message);
+  asserts.assertInstanceof(msg, Message);
   if (!msg.wrappers_) {
     msg.wrappers_ = {};
   }
@@ -1371,13 +1276,13 @@
     data[i] = value[i].toArray();
   }
   msg.wrappers_[fieldNumber] = value;
-  return jspb.Message.setField(msg, fieldNumber, data);
+  return Message.setField(msg, fieldNumber, data);
 };
 
 
 /**
  * Add a message to a repeated proto field.
- * @param {!jspb.Message} msg A jspb proto.
+ * @param {!Message} msg A jspb proto.
  * @param {number} fieldNumber The field number.
  * @param {T_CHILD|undefined} value Proto that will be added to the
  *     repeated field.
@@ -1397,15 +1302,15 @@
  * =:
  * @export
  */
-jspb.Message.addToRepeatedWrapperField = function(
+Message.addToRepeatedWrapperField = function (
     msg, fieldNumber, value, ctor, index) {
-  jspb.Message.wrapRepeatedField_(msg, ctor, fieldNumber);
+  Message.wrapRepeatedField_(msg, ctor, fieldNumber);
   var wrapperArray = msg.wrappers_[fieldNumber];
   if (!wrapperArray) {
     wrapperArray = msg.wrappers_[fieldNumber] = [];
   }
   var insertedValue = value ? value : new ctor();
-  var array = jspb.Message.getRepeatedField(msg, fieldNumber);
+  var array = Message.getRepeatedField(msg, fieldNumber);
   if (index != undefined) {
     wrapperArray.splice(index, 0, insertedValue);
     array.splice(index, 0, insertedValue.toArray());
@@ -1435,14 +1340,14 @@
  * @template T
  * @export
  */
-jspb.Message.toMap = function(
+Message.toMap = function (
     field, mapKeyGetterFn, opt_toObjectFn, opt_includeInstance) {
   var result = {};
   for (var i = 0; i < field.length; i++) {
     result[mapKeyGetterFn.call(field[i])] = opt_toObjectFn ?
         opt_toObjectFn.call(
             field[i], opt_includeInstance,
-            /** @type {!jspb.Message} */ (field[i])) :
+            /** @type {!Message} */(field[i])) :
         field[i];
   }
   return result;
@@ -1453,7 +1358,7 @@
  * Syncs all map fields' contents back to their underlying arrays.
  * @private
  */
-jspb.Message.prototype.syncMapFields_ = function() {
+Message.prototype.syncMapFields_ = function () {
   // This iterates over submessage, map, and repeated fields, which is intended.
   // Submessages can contain maps which also need to be synced.
   //
@@ -1488,14 +1393,14 @@
  * @return {!Array} The proto represented as an array.
  * @export
  */
-jspb.Message.prototype.toArray = function() {
+Message.prototype.toArray = function () {
   this.syncMapFields_();
   return this.array;
 };
 
 
 
-if (jspb.Message.GENERATE_TO_STRING) {
+if (Message.GENERATE_TO_STRING) {
   /**
    * Creates a string representation of the internal data array of this proto.
    * <p>NOTE: This string is *not* suitable for use in server requests.
@@ -1503,7 +1408,7 @@
    * @override
    * @export
    */
-  jspb.Message.prototype.toString = function() {
+  Message.prototype.toString = function () {
     this.syncMapFields_();
     return this.array.toString();
   };
@@ -1511,12 +1416,12 @@
 
 /**
  * Gets the value of the extension field from the extended object.
- * @param {jspb.ExtensionFieldInfo<T>} fieldInfo Specifies the field to get.
+ * @param {ExtensionFieldInfo<T>} fieldInfo Specifies the field to get.
  * @return {T} The value of the field.
  * @template T
  * @export
  */
-jspb.Message.prototype.getExtension = function(fieldInfo) {
+Message.prototype.getExtension = function (fieldInfo) {
   if (!this.extensionObject_) {
     return undefined;
   }
@@ -1527,7 +1432,7 @@
   if (fieldInfo.isRepeated) {
     if (fieldInfo.isMessageType()) {
       if (!this.wrappers_[fieldNumber]) {
-        this.wrappers_[fieldNumber] = goog.array.map(
+        this.wrappers_[fieldNumber] = googArray.map(
             this.extensionObject_[fieldNumber] || [], function(arr) {
               return new fieldInfo.ctor(arr);
             });
@@ -1553,29 +1458,29 @@
 
 /**
  * Sets the value of the extension field in the extended object.
- * @param {jspb.ExtensionFieldInfo} fieldInfo Specifies the field to set.
- * @param {jspb.Message|string|Uint8Array|number|boolean|Array?} value The value
+ * @param {ExtensionFieldInfo} fieldInfo Specifies the field to set.
+ * @param {Message|string|Uint8Array|number|boolean|Array?} value The value
  *     to set.
  * @return {THIS} For chaining
  * @this {THIS}
  * @template THIS
  * @export
  */
-jspb.Message.prototype.setExtension = function(fieldInfo, value) {
+Message.prototype.setExtension = function (fieldInfo, value) {
   // Cast self, since the inferred THIS is unknown inside the function body.
   // https://github.com/google/closure-compiler/issues/1411#issuecomment-232442220
-  var self = /** @type {!jspb.Message} */ (this);
+  var self = /** @type {!Message} */ (this);
   if (!self.wrappers_) {
     self.wrappers_ = {};
   }
-  jspb.Message.maybeInitEmptyExtensionObject_(self);
+  Message.maybeInitEmptyExtensionObject_(self);
   var fieldNumber = fieldInfo.fieldIndex;
   if (fieldInfo.isRepeated) {
     value = value || [];
     if (fieldInfo.isMessageType()) {
       self.wrappers_[fieldNumber] = value;
-      self.extensionObject_[fieldNumber] = goog.array.map(
-          /** @type {!Array<!jspb.Message>} */ (value), function(msg) {
+      self.extensionObject_[fieldNumber] = googArray.map(
+          /** @type {!Array<!Message>} */(value), function (msg) {
             return msg.toArray();
           });
     } else {
@@ -1585,7 +1490,7 @@
     if (fieldInfo.isMessageType()) {
       self.wrappers_[fieldNumber] = value;
       self.extensionObject_[fieldNumber] =
-          value ? /** @type {!jspb.Message} */ (value).toArray() : value;
+        value ? /** @type {!Message} */ (value).toArray() : value;
     } else {
       self.extensionObject_[fieldNumber] = value;
     }
@@ -1606,9 +1511,9 @@
  * the same if the only difference between them is due to trailing
  * null/undefined values.
  *
- * @param {!jspb.Message} m1 The first message object.
- * @param {!jspb.Message} m2 The second message object.
- * @return {!jspb.Message} The difference returned as a proto message.
+ * @param {!Message} m1 The first message object.
+ * @param {!Message} m2 The second message object.
+ * @return {!Message} The difference returned as a proto message.
  *     Note that the returned message may be missing required fields. This is
  *     currently tolerated in Js, but would cause an error if you tried to
  *     send such a proto to the server. You can access the raw difference
@@ -1616,7 +1521,7 @@
  * @throws {Error} If the messages are responses with different types.
  * @export
  */
-jspb.Message.difference = function(m1, m2) {
+Message.difference = function (m1, m2) {
   if (!(m1 instanceof m2.constructor)) {
     throw new Error('Messages have different types.');
   }
@@ -1630,7 +1535,7 @@
     start = 1;
   }
   for (var i = start; i < length; i++) {
-    if (!jspb.Message.compareFields(arr1[i], arr2[i])) {
+    if (!Message.compareFields(arr1[i], arr2[i])) {
       res[i] = arr2[i];
     }
   }
@@ -1640,16 +1545,16 @@
 
 /**
  * Tests whether two messages are equal.
- * @param {jspb.Message|undefined} m1 The first message object.
- * @param {jspb.Message|undefined} m2 The second message object.
+ * @param {Message|undefined} m1 The first message object.
+ * @param {Message|undefined} m2 The second message object.
  * @return {boolean} true if both messages are null/undefined, or if both are
  *     of the same type and have the same field values.
  * @export
  */
-jspb.Message.equals = function(m1, m2) {
+Message.equals = function (m1, m2) {
   return m1 == m2 ||
       (!!(m1 && m2) && (m1 instanceof m2.constructor) &&
-       jspb.Message.compareFields(m1.toArray(), m2.toArray()));
+      Message.compareFields(m1.toArray(), m2.toArray()));
 };
 
 
@@ -1661,7 +1566,7 @@
  *     equal.
  * @export
  */
-jspb.Message.compareExtensions = function(extension1, extension2) {
+Message.compareExtensions = function (extension1, extension2) {
   extension1 = extension1 || {};
   extension2 = extension2 || {};
 
@@ -1673,7 +1578,7 @@
     keys[name] = 0;
   }
   for (name in keys) {
-    if (!jspb.Message.compareFields(extension1[name], extension2[name])) {
+    if (!Message.compareFields(extension1[name], extension2[name])) {
       return false;
     }
   }
@@ -1688,7 +1593,7 @@
  * @return {boolean} true if the fields are null/undefined, or otherwise equal.
  * @export
  */
-jspb.Message.compareFields = function(field1, field2) {
+Message.compareFields = function (field1, field2) {
   // If the fields are trivially equal, they're equal.
   if (field1 == field2) return true;
 
@@ -1710,7 +1615,7 @@
   if (field1.constructor != field2.constructor) return false;
 
   // If both are Uint8Arrays, compare them element-by-element.
-  if (jspb.Message.SUPPORTS_UINT8ARRAY_ && field1.constructor === Uint8Array) {
+  if (Message.SUPPORTS_UINT8ARRAY_ && field1.constructor === Uint8Array) {
     var bytes1 = /** @type {!Uint8Array} */ (field1);
     var bytes2 = /** @type {!Uint8Array} */ (field2);
     if (bytes1.length != bytes2.length) return false;
@@ -1734,20 +1639,20 @@
       var val2 = typedField2[i];
 
       if (val1 && (val1.constructor == Object)) {
-        jspb.asserts.assert(extension1 === undefined);
-        jspb.asserts.assert(i === typedField1.length - 1);
+        asserts.assert(extension1 === undefined);
+        asserts.assert(i === typedField1.length - 1);
         extension1 = val1;
         val1 = undefined;
       }
 
       if (val2 && (val2.constructor == Object)) {
-        jspb.asserts.assert(extension2 === undefined);
-        jspb.asserts.assert(i === typedField2.length - 1);
+        asserts.assert(extension2 === undefined);
+        asserts.assert(i === typedField2.length - 1);
         extension2 = val2;
         val2 = undefined;
       }
 
-      if (!jspb.Message.compareFields(val1, val2)) {
+      if (!Message.compareFields(val1, val2)) {
         return false;
       }
     }
@@ -1755,7 +1660,7 @@
     if (extension1 || extension2) {
       extension1 = extension1 || {};
       extension2 = extension2 || {};
-      return jspb.Message.compareExtensions(extension1, extension2);
+      return Message.compareExtensions(extension1, extension2);
     }
 
     return true;
@@ -1764,7 +1669,7 @@
   // If they're both plain Objects (i.e. extensions), compare them as
   // extensions.
   if (field1.constructor === Object) {
-    return jspb.Message.compareExtensions(field1, field2);
+    return Message.compareExtensions(field1, field2);
   }
 
   throw new Error('Invalid type in JSPB array');
@@ -1778,8 +1683,8 @@
  * @template THIS
  * @export
  */
-jspb.Message.prototype.cloneMessage = function() {
-  return jspb.Message.cloneMessage(/** @type {!jspb.Message} */ (this));
+Message.prototype.cloneMessage = function () {
+  return Message.cloneMessage(/** @type {!Message} */(this));
 };
 
 /**
@@ -1791,32 +1696,32 @@
  * @template THIS
  * @export
  */
-jspb.Message.prototype.clone = function() {
-  return jspb.Message.cloneMessage(/** @type {!jspb.Message} */ (this));
+Message.prototype.clone = function () {
+  return Message.cloneMessage(/** @type {!Message} */(this));
 };
 
 /**
  * Static clone function. NOTE: A type-safe method called "cloneMessage"
  * exists
  * on each generated JsPb class. Do not call this function directly.
- * @param {!jspb.Message} msg A message to clone.
- * @return {!jspb.Message} A deep clone of the given message.
+ * @param {!Message} msg A message to clone.
+ * @return {!Message} A deep clone of the given message.
  * @export
  */
-jspb.Message.clone = function(msg) {
+Message.clone = function (msg) {
   // Although we could include the wrappers, we leave them out here.
-  return jspb.Message.cloneMessage(msg);
+  return Message.cloneMessage(msg);
 };
 
 
 /**
- * @param {!jspb.Message} msg A message to clone.
- * @return {!jspb.Message} A deep clone of the given message.
+ * @param {!Message} msg A message to clone.
+ * @return {!Message} A deep clone of the given message.
  * @protected
  */
-jspb.Message.cloneMessage = function(msg) {
+Message.cloneMessage = function (msg) {
   // Although we could include the wrappers, we leave them out here.
-  return new msg.constructor(jspb.Message.clone_(msg.toArray()));
+  return new msg.constructor(Message.clone_(msg.toArray()));
 };
 
 
@@ -1832,14 +1737,14 @@
  * @template MESSAGE
  * @export
  */
-jspb.Message.copyInto = function(fromMessage, toMessage) {
-  jspb.asserts.assertInstanceof(fromMessage, jspb.Message);
-  jspb.asserts.assertInstanceof(toMessage, jspb.Message);
-  jspb.asserts.assert(
+Message.copyInto = function (fromMessage, toMessage) {
+  asserts.assertInstanceof(fromMessage, Message);
+  asserts.assertInstanceof(toMessage, Message);
+  asserts.assert(
       fromMessage.constructor == toMessage.constructor,
       'Copy source and target message should have the same type.');
 
-  var copyOfFrom = jspb.Message.clone(fromMessage);
+  var copyOfFrom = Message.clone(fromMessage);
 
   var to = toMessage.toArray();
   var from = copyOfFrom.toArray();
@@ -1864,7 +1769,7 @@
  * @return {!Object} A clone of the input object.
  * @private
  */
-jspb.Message.clone_ = function(obj) {
+Message.clone_ = function (obj) {
   var o;
   if (Array.isArray(obj)) {
     // Allocate array of correct size.
@@ -1876,13 +1781,13 @@
         // NOTE:redundant null check existing for NTI compatibility.
         // see b/70515949
         clonedArray[i] = (typeof o == 'object') ?
-            jspb.Message.clone_(/** @type {!Object} */(jspb.asserts.assert(o))) :
+          Message.clone_(/** @type {!Object} */(asserts.assert(o))) :
             o;
       }
     }
     return clonedArray;
   }
-  if (jspb.Message.SUPPORTS_UINT8ARRAY_ && obj instanceof Uint8Array) {
+  if (Message.SUPPORTS_UINT8ARRAY_ && obj instanceof Uint8Array) {
     return new Uint8Array(obj);
   }
   var clone = {};
@@ -1892,7 +1797,7 @@
       // NOTE:redundant null check existing for NTI compatibility.
       // see b/70515949
       clone[key] = (typeof o == 'object') ?
-          jspb.Message.clone_(/** @type {!Object} */(jspb.asserts.assert(o))) :
+        Message.clone_(/** @type {!Object} */(asserts.assert(o))) :
           o;
     }
   }
@@ -1906,7 +1811,7 @@
  * @param {Function} constructor The message constructor.
  * @export
  */
-jspb.Message.registerMessageType = function(id, constructor) {
+Message.registerMessageType = function (id, constructor) {
   // This is needed so we can later access messageId directly on the
   // constructor, otherwise it is not available due to 'property collapsing' by
   // the compiler.
@@ -1924,11 +1829,12 @@
  * 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, ExtensionFieldInfo>}
  */
-jspb.Message.messageSetExtensions = {};
+Message.messageSetExtensions = {};
 
 /**
- * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}
+ * @type {!Object<number, ExtensionFieldBinaryInfo>}
  */
-jspb.Message.messageSetExtensionsBinary = {};
+Message.messageSetExtensionsBinary = {};
+exports = Message;