text: /**
   * Copyright 2017 Google Inc.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *   http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  var LONG_TYPE = 'type.googleapis.com/google.protobuf.Int64Value';
  var UNSIGNED_LONG_TYPE = 'type.googleapis.com/google.protobuf.UInt64Value';
  function mapValues(o, f) {
      var result = {};
      for (var key in o) {
          if (o.hasOwnProperty(key)) {
              result[key] = f(o[key]);
          }
      }
      return result;
  }
  var Serializer = /** @class */ (function () {
      function Serializer() {
      }
      // Takes data and encodes it in a JSON-friendly way, such that types such as
      // Date are preserved.
      Serializer.prototype.encode = function (data) {
          var _this = this;
          if (data === null || data === undefined) {
              return null;
          }
          if (data instanceof Number) {
              data = data.valueOf();
          }
          if (typeof data === 'number' && isFinite(data)) {
              // Any number in JS is safe to put directly in JSON and parse as a double
              // without any loss of precision.
              return data;
          }
          if (data === true || data === false) {
              return data;
          }
          if (toString.call(data) === '[object String]') {
              return data;
          }
          if (Array.isArray(data)) {
              return data.map(function (x) { return _this.encode(x); });
          }
          if (typeof data === 'function' || typeof data === 'object') {
              return mapValues(data, function (x) { return _this.encode(x); });
          }
          // If we got this far, the data is not encodable.
          throw new Error('Data cannot be encoded in JSON: ' + data);
      };
      // Takes data that's been encoded in a JSON-friendly form and returns a form
      // with richer datatypes, such as Dates, etc.
      Serializer.prototype.decode = function (json) {
          var _this = this;
          if (json === null) {
              return json;
          }
          if (json['@type']) {
              switch (json['@type']) {
                  case LONG_TYPE:
                  // Fall through and handle this the same as unsigned.
                  case UNSIGNED_LONG_TYPE: {
                      // Technically, this could work return a valid number for malformed
                      // data if there was a number followed by garbage. But it's just not
                      // worth all the extra code to detect that case.
                      var value = parseFloat(json.value);
                      if (isNaN(value)) {
                          throw new Error('Data cannot be decoded from JSON: ' + json);
                      }
                      return value;
                  }
                  default: {
                      throw new Error('Data cannot be decoded from JSON: ' + json);
                  }
              }
          }
          if (Array.isArray(json)) {
              return json.map(function (x) { return _this.decode(x); });
          }
          if (typeof json === 'function' || typeof json === 'object') {
              return mapValues(json, function (x) { return _this.decode(x); });
          }
          // Anything else is safe to return.
          return json;
      };
      return Serializer;
  }());
  export { Serializer };
  
  //# sourceMappingURL=serializer.js.map
  