// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

(function() {
  var internal = mojo.internal;

  var kErrorUnsigned = "Passing negative value to unsigned";
  var kErrorArray = "Passing non Array for array type";
  var kErrorString = "Passing non String for string type";
  var kErrorMap = "Passing non Map for map type";

  // Memory -------------------------------------------------------------------

  var kAlignment = 8;

  function align(size) {
    return size + (kAlignment - (size % kAlignment)) % kAlignment;
  }

  function isAligned(offset) {
    return offset >= 0 && (offset % kAlignment) === 0;
  }

  // Constants ----------------------------------------------------------------

  var kArrayHeaderSize = 8;
  var kStructHeaderSize = 8;
  var kMessageV0HeaderSize = 24;
  var kMessageV1HeaderSize = 32;
  var kMessageV2HeaderSize = 48;
  var kMapStructPayloadSize = 16;

  var kStructHeaderNumBytesOffset = 0;
  var kStructHeaderVersionOffset = 4;

  var kEncodedInvalidHandleValue = 0xFFFFFFFF;

  // Decoder ------------------------------------------------------------------

  function Decoder(buffer, handles, associatedEndpointHandles, base) {
    this.buffer = buffer;
    this.handles = handles;
    this.associatedEndpointHandles = associatedEndpointHandles;
    this.base = base;
    this.next = base;
  }

  Decoder.prototype.align = function() {
    this.next = align(this.next);
  };

  Decoder.prototype.skip = function(offset) {
    this.next += offset;
  };

  Decoder.prototype.readInt8 = function() {
    var result = this.buffer.getInt8(this.next);
    this.next += 1;
    return result;
  };

  Decoder.prototype.readUint8 = function() {
    var result = this.buffer.getUint8(this.next);
    this.next += 1;
    return result;
  };

  Decoder.prototype.readInt16 = function() {
    var result = this.buffer.getInt16(this.next);
    this.next += 2;
    return result;
  };

  Decoder.prototype.readUint16 = function() {
    var result = this.buffer.getUint16(this.next);
    this.next += 2;
    return result;
  };

  Decoder.prototype.readInt32 = function() {
    var result = this.buffer.getInt32(this.next);
    this.next += 4;
    return result;
  };

  Decoder.prototype.readUint32 = function() {
    var result = this.buffer.getUint32(this.next);
    this.next += 4;
    return result;
  };

  Decoder.prototype.readInt64 = function() {
    var result = this.buffer.getInt64(this.next);
    this.next += 8;
    return result;
  };

  Decoder.prototype.readUint64 = function() {
    var result = this.buffer.getUint64(this.next);
    this.next += 8;
    return result;
  };

  Decoder.prototype.readFloat = function() {
    var result = this.buffer.getFloat32(this.next);
    this.next += 4;
    return result;
  };

  Decoder.prototype.readDouble = function() {
    var result = this.buffer.getFloat64(this.next);
    this.next += 8;
    return result;
  };

  Decoder.prototype.decodePointer = function() {
    // TODO(abarth): To correctly decode a pointer, we need to know the real
    // base address of the array buffer.
    var offsetPointer = this.next;
    var offset = this.readUint64();
    if (!offset)
      return 0;
    return offsetPointer + offset;
  };

  Decoder.prototype.decodeAndCreateDecoder = function(pointer) {
    return new Decoder(this.buffer, this.handles,
        this.associatedEndpointHandles, pointer);
  };

  Decoder.prototype.decodeHandle = function() {
    return this.handles[this.readUint32()] || null;
  };

  Decoder.prototype.decodeAssociatedEndpointHandle = function() {
    return this.associatedEndpointHandles[this.readUint32()] || null;
  };

  Decoder.prototype.decodeString = function() {
    var numberOfBytes = this.readUint32();
    var numberOfElements = this.readUint32();
    var base = this.next;
    this.next += numberOfElements;
    return internal.decodeUtf8String(
        new Uint8Array(this.buffer.arrayBuffer, base, numberOfElements));
  };

  Decoder.prototype.decodeArray = function(cls) {
    var numberOfBytes = this.readUint32();
    var numberOfElements = this.readUint32();
    var val = new Array(numberOfElements);
    if (cls === PackedBool) {
      var byte;
      for (var i = 0; i < numberOfElements; ++i) {
        if (i % 8 === 0)
          byte = this.readUint8();
        val[i] = (byte & (1 << i % 8)) ? true : false;
      }
    } else {
      for (var i = 0; i < numberOfElements; ++i) {
        val[i] = cls.decode(this);
      }
    }
    return val;
  };

  Decoder.prototype.decodeStruct = function(cls) {
    return cls.decode(this);
  };

  Decoder.prototype.decodeStructPointer = function(cls) {
    var pointer = this.decodePointer();
    if (!pointer) {
      return null;
    }
    return cls.decode(this.decodeAndCreateDecoder(pointer));
  };

  Decoder.prototype.decodeArrayPointer = function(cls) {
    var pointer = this.decodePointer();
    if (!pointer) {
      return null;
    }
    return this.decodeAndCreateDecoder(pointer).decodeArray(cls);
  };

  Decoder.prototype.decodeStringPointer = function() {
    var pointer = this.decodePointer();
    if (!pointer) {
      return null;
    }
    return this.decodeAndCreateDecoder(pointer).decodeString();
  };

  Decoder.prototype.decodeMap = function(keyClass, valueClass) {
    this.skip(4); // numberOfBytes
    this.skip(4); // version
    var keys = this.decodeArrayPointer(keyClass);
    var values = this.decodeArrayPointer(valueClass);
    var val = new Map();
    for (var i = 0; i < keys.length; i++)
      val.set(keys[i], values[i]);
    return val;
  };

  Decoder.prototype.decodeMapPointer = function(keyClass, valueClass) {
    var pointer = this.decodePointer();
    if (!pointer) {
      return null;
    }
    var decoder = this.decodeAndCreateDecoder(pointer);
    return decoder.decodeMap(keyClass, valueClass);
  };

  // Encoder ------------------------------------------------------------------

  function Encoder(buffer, handles, associatedEndpointHandles, base) {
    this.buffer = buffer;
    this.handles = handles;
    this.associatedEndpointHandles = associatedEndpointHandles;
    this.base = base;
    this.next = base;
  }

  Encoder.prototype.align = function() {
    this.next = align(this.next);
  };

  Encoder.prototype.skip = function(offset) {
    this.next += offset;
  };

  Encoder.prototype.writeInt8 = function(val) {
    this.buffer.setInt8(this.next, val);
    this.next += 1;
  };

  Encoder.prototype.writeUint8 = function(val) {
    if (val < 0) {
      throw new Error(kErrorUnsigned);
    }
    this.buffer.setUint8(this.next, val);
    this.next += 1;
  };

  Encoder.prototype.writeInt16 = function(val) {
    this.buffer.setInt16(this.next, val);
    this.next += 2;
  };

  Encoder.prototype.writeUint16 = function(val) {
    if (val < 0) {
      throw new Error(kErrorUnsigned);
    }
    this.buffer.setUint16(this.next, val);
    this.next += 2;
  };

  Encoder.prototype.writeInt32 = function(val) {
    this.buffer.setInt32(this.next, val);
    this.next += 4;
  };

  Encoder.prototype.writeUint32 = function(val) {
    if (val < 0) {
      throw new Error(kErrorUnsigned);
    }
    this.buffer.setUint32(this.next, val);
    this.next += 4;
  };

  Encoder.prototype.writeInt64 = function(val) {
    this.buffer.setInt64(this.next, val);
    this.next += 8;
  };

  Encoder.prototype.writeUint64 = function(val) {
    if (val < 0) {
      throw new Error(kErrorUnsigned);
    }
    this.buffer.setUint64(this.next, val);
    this.next += 8;
  };

  Encoder.prototype.writeFloat = function(val) {
    this.buffer.setFloat32(this.next, val);
    this.next += 4;
  };

  Encoder.prototype.writeDouble = function(val) {
    this.buffer.setFloat64(this.next, val);
    this.next += 8;
  };

  Encoder.prototype.encodePointer = function(pointer) {
    if (!pointer)
      return this.writeUint64(0);
    // TODO(abarth): To correctly encode a pointer, we need to know the real
    // base address of the array buffer.
    var offset = pointer - this.next;
    this.writeUint64(offset);
  };

  Encoder.prototype.createAndEncodeEncoder = function(size) {
    var pointer = this.buffer.alloc(align(size));
    this.encodePointer(pointer);
    return new Encoder(this.buffer, this.handles,
        this.associatedEndpointHandles, pointer);
  };

  Encoder.prototype.encodeHandle = function(handle) {
    if (handle) {
      this.handles.push(handle);
      this.writeUint32(this.handles.length - 1);
    } else {
      this.writeUint32(kEncodedInvalidHandleValue);
    }
  };

  Encoder.prototype.encodeAssociatedEndpointHandle = function(endpointHandle) {
    if (endpointHandle) {
      this.associatedEndpointHandles.push(endpointHandle);
      this.writeUint32(this.associatedEndpointHandles.length - 1);
    } else {
      this.writeUint32(kEncodedInvalidHandleValue);
    }
  };

  Encoder.prototype.encodeString = function(val) {
    var base = this.next + kArrayHeaderSize;
    var numberOfElements = internal.encodeUtf8String(
        val, new Uint8Array(this.buffer.arrayBuffer, base));
    var numberOfBytes = kArrayHeaderSize + numberOfElements;
    this.writeUint32(numberOfBytes);
    this.writeUint32(numberOfElements);
    this.next += numberOfElements;
  };

  Encoder.prototype.encodeArray =
      function(cls, val, numberOfElements, encodedSize) {
    if (numberOfElements === undefined)
      numberOfElements = val.length;
    if (encodedSize === undefined)
      encodedSize = kArrayHeaderSize + cls.encodedSize * numberOfElements;

    this.writeUint32(encodedSize);
    this.writeUint32(numberOfElements);

    if (cls === PackedBool) {
      var byte = 0;
      for (i = 0; i < numberOfElements; ++i) {
        if (val[i])
          byte |= (1 << i % 8);
        if (i % 8 === 7 || i == numberOfElements - 1) {
          Uint8.encode(this, byte);
          byte = 0;
        }
      }
    } else {
      for (var i = 0; i < numberOfElements; ++i)
        cls.encode(this, val[i]);
    }
  };

  Encoder.prototype.encodeStruct = function(cls, val) {
    return cls.encode(this, val);
  };

  Encoder.prototype.encodeStructPointer = function(cls, val) {
    if (val == null) {
      // Also handles undefined, since undefined == null.
      this.encodePointer(val);
      return;
    }
    var encoder = this.createAndEncodeEncoder(cls.encodedSize);
    cls.encode(encoder, val);
  };

  Encoder.prototype.encodeArrayPointer = function(cls, val) {
    if (val == null) {
      // Also handles undefined, since undefined == null.
      this.encodePointer(val);
      return;
    }

    var numberOfElements = val.length;
    if (!Number.isSafeInteger(numberOfElements) || numberOfElements < 0)
      throw new Error(kErrorArray);

    var encodedSize = kArrayHeaderSize + ((cls === PackedBool) ?
        Math.ceil(numberOfElements / 8) : cls.encodedSize * numberOfElements);
    var encoder = this.createAndEncodeEncoder(encodedSize);
    encoder.encodeArray(cls, val, numberOfElements, encodedSize);
  };

  Encoder.prototype.encodeStringPointer = function(val) {
    if (val == null) {
      // Also handles undefined, since undefined == null.
      this.encodePointer(val);
      return;
    }
    // Only accepts string primivites, not String Objects like new String("foo")
    if (typeof(val) !== "string") {
      throw new Error(kErrorString);
    }
    var encodedSize = kArrayHeaderSize + internal.utf8Length(val);
    var encoder = this.createAndEncodeEncoder(encodedSize);
    encoder.encodeString(val);
  };

  Encoder.prototype.encodeMap = function(keyClass, valueClass, val) {
    var keys = new Array(val.size);
    var values = new Array(val.size);
    var i = 0;
    val.forEach(function(value, key) {
      values[i] = value;
      keys[i++] = key;
    });
    this.writeUint32(kStructHeaderSize + kMapStructPayloadSize);
    this.writeUint32(0);  // version
    this.encodeArrayPointer(keyClass, keys);
    this.encodeArrayPointer(valueClass, values);
  }

  Encoder.prototype.encodeMapPointer = function(keyClass, valueClass, val) {
    if (val == null) {
      // Also handles undefined, since undefined == null.
      this.encodePointer(val);
      return;
    }
    if (!(val instanceof Map)) {
      throw new Error(kErrorMap);
    }
    var encodedSize = kStructHeaderSize + kMapStructPayloadSize;
    var encoder = this.createAndEncodeEncoder(encodedSize);
    encoder.encodeMap(keyClass, valueClass, val);
  };

  // Message ------------------------------------------------------------------

  var kMessageInterfaceIdOffset = kStructHeaderSize;
  var kMessageNameOffset = kMessageInterfaceIdOffset + 4;
  var kMessageFlagsOffset = kMessageNameOffset + 4;
  var kMessageRequestIDOffset = kMessageFlagsOffset + 8;
  var kMessagePayloadInterfaceIdsPointerOffset = kMessageV2HeaderSize - 8;

  var kMessageExpectsResponse = 1 << 0;
  var kMessageIsResponse      = 1 << 1;

  function Message(buffer, handles, associatedEndpointHandles) {
    if (associatedEndpointHandles === undefined) {
      associatedEndpointHandles = [];
    }

    this.buffer = buffer;
    this.handles = handles;
    this.associatedEndpointHandles = associatedEndpointHandles;
  }

  Message.prototype.getHeaderNumBytes = function() {
    return this.buffer.getUint32(kStructHeaderNumBytesOffset);
  };

  Message.prototype.getHeaderVersion = function() {
    return this.buffer.getUint32(kStructHeaderVersionOffset);
  };

  Message.prototype.getName = function() {
    return this.buffer.getUint32(kMessageNameOffset);
  };

  Message.prototype.getFlags = function() {
    return this.buffer.getUint32(kMessageFlagsOffset);
  };

  Message.prototype.getInterfaceId = function() {
    return this.buffer.getUint32(kMessageInterfaceIdOffset);
  };

  Message.prototype.getPayloadInterfaceIds = function() {
    if (this.getHeaderVersion() < 2) {
      return null;
    }

    var decoder = new Decoder(this.buffer, this.handles,
        this.associatedEndpointHandles,
        kMessagePayloadInterfaceIdsPointerOffset);
    var payloadInterfaceIds = decoder.decodeArrayPointer(Uint32);
    return payloadInterfaceIds;
  };

  Message.prototype.isResponse = function() {
    return (this.getFlags() & kMessageIsResponse) != 0;
  };

  Message.prototype.expectsResponse = function() {
    return (this.getFlags() & kMessageExpectsResponse) != 0;
  };

  Message.prototype.setRequestID = function(requestID) {
    // TODO(darin): Verify that space was reserved for this field!
    this.buffer.setUint64(kMessageRequestIDOffset, requestID);
  };

  Message.prototype.setInterfaceId = function(interfaceId) {
    this.buffer.setUint32(kMessageInterfaceIdOffset, interfaceId);
  };

  Message.prototype.setPayloadInterfaceIds_ = function(payloadInterfaceIds) {
    if (this.getHeaderVersion() < 2) {
      throw new Error(
          "Version of message does not support payload interface ids");
    }

    var decoder = new Decoder(this.buffer, this.handles,
        this.associatedEndpointHandles,
        kMessagePayloadInterfaceIdsPointerOffset);
    var payloadInterfaceIdsOffset = decoder.decodePointer();
    var encoder = new Encoder(this.buffer, this.handles,
        this.associatedEndpointHandles,
        payloadInterfaceIdsOffset);
    encoder.encodeArray(Uint32, payloadInterfaceIds);
  };

  Message.prototype.serializeAssociatedEndpointHandles = function(
      associatedGroupController) {
    if (this.associatedEndpointHandles.length > 0) {
      if (this.getHeaderVersion() < 2) {
        throw new Error(
            "Version of message does not support associated endpoint handles");
      }

      var data = [];
      for (var i = 0; i < this.associatedEndpointHandles.length; i++) {
        var handle = this.associatedEndpointHandles[i];
        data.push(associatedGroupController.associateInterface(handle));
      }
      this.associatedEndpointHandles = [];
      this.setPayloadInterfaceIds_(data);
    }
  };

  Message.prototype.deserializeAssociatedEndpointHandles = function(
      associatedGroupController) {
    if (this.getHeaderVersion() < 2) {
      return true;
    }

    this.associatedEndpointHandles = [];
    var ids = this.getPayloadInterfaceIds();

    var result = true;
    for (var i = 0; i < ids.length; i++) {
      var handle = associatedGroupController.createLocalEndpointHandle(ids[i]);
      if (internal.isValidInterfaceId(ids[i]) && !handle.isValid()) {
        // |ids[i]| itself is valid but handle creation failed. In that case,
        // mark deserialization as failed but continue to deserialize the
        // rest of handles.
        result = false;
      }
      this.associatedEndpointHandles.push(handle);
      ids[i] = internal.kInvalidInterfaceId;
    }

    this.setPayloadInterfaceIds_(ids);
    return result;
  };


  // MessageV0Builder ---------------------------------------------------------

  function MessageV0Builder(messageName, payloadSize) {
    // Currently, we don't compute the payload size correctly ahead of time.
    // Instead, we resize the buffer at the end.
    var numberOfBytes = kMessageV0HeaderSize + payloadSize;
    this.buffer = new internal.Buffer(numberOfBytes);
    this.handles = [];
    var encoder = this.createEncoder(kMessageV0HeaderSize);
    encoder.writeUint32(kMessageV0HeaderSize);
    encoder.writeUint32(0);  // version.
    encoder.writeUint32(0);  // interface ID.
    encoder.writeUint32(messageName);
    encoder.writeUint32(0);  // flags.
    encoder.writeUint32(0);  // padding.
  }

  MessageV0Builder.prototype.createEncoder = function(size) {
    var pointer = this.buffer.alloc(size);
    return new Encoder(this.buffer, this.handles, [], pointer);
  };

  MessageV0Builder.prototype.encodeStruct = function(cls, val) {
    cls.encode(this.createEncoder(cls.encodedSize), val);
  };

  MessageV0Builder.prototype.finish = function() {
    // TODO(abarth): Rather than resizing the buffer at the end, we could
    // compute the size we need ahead of time, like we do in C++.
    this.buffer.trim();
    var message = new Message(this.buffer, this.handles);
    this.buffer = null;
    this.handles = null;
    this.encoder = null;
    return message;
  };

  // MessageV1Builder -----------------------------------------------

  function MessageV1Builder(messageName, payloadSize, flags,
                                       requestID) {
    // Currently, we don't compute the payload size correctly ahead of time.
    // Instead, we resize the buffer at the end.
    var numberOfBytes = kMessageV1HeaderSize + payloadSize;
    this.buffer = new internal.Buffer(numberOfBytes);
    this.handles = [];
    var encoder = this.createEncoder(kMessageV1HeaderSize);
    encoder.writeUint32(kMessageV1HeaderSize);
    encoder.writeUint32(1);  // version.
    encoder.writeUint32(0);  // interface ID.
    encoder.writeUint32(messageName);
    encoder.writeUint32(flags);
    encoder.writeUint32(0);  // padding.
    encoder.writeUint64(requestID);
  }

  MessageV1Builder.prototype =
      Object.create(MessageV0Builder.prototype);

  MessageV1Builder.prototype.constructor =
      MessageV1Builder;

  // MessageV2 -----------------------------------------------

  function MessageV2Builder(messageName, payloadSize, flags, requestID) {
    // Currently, we don't compute the payload size correctly ahead of time.
    // Instead, we resize the buffer at the end.
    var numberOfBytes = kMessageV2HeaderSize + payloadSize;
    this.buffer = new internal.Buffer(numberOfBytes);
    this.handles = [];

    this.payload = null;
    this.associatedEndpointHandles = [];

    this.encoder = this.createEncoder(kMessageV2HeaderSize);
    this.encoder.writeUint32(kMessageV2HeaderSize);
    this.encoder.writeUint32(2);  // version.
    // Gets set to an appropriate interfaceId for the endpoint by the Router.
    this.encoder.writeUint32(0);  // interface ID.
    this.encoder.writeUint32(messageName);
    this.encoder.writeUint32(flags);
    this.encoder.writeUint32(0);  // padding.
    this.encoder.writeUint64(requestID);
  }

  MessageV2Builder.prototype.createEncoder = function(size) {
    var pointer = this.buffer.alloc(size);
    return new Encoder(this.buffer, this.handles,
        this.associatedEndpointHandles, pointer);
  };

  MessageV2Builder.prototype.setPayload = function(cls, val) {
    this.payload = {cls: cls, val: val};
  };

  MessageV2Builder.prototype.finish = function() {
    if (!this.payload) {
      throw new Error("Payload needs to be set before calling finish");
    }

    this.encoder.encodeStructPointer(this.payload.cls, this.payload.val);
    this.encoder.encodeArrayPointer(Uint32,
        new Array(this.associatedEndpointHandles.length));

    this.buffer.trim();
    var message = new Message(this.buffer, this.handles,
        this.associatedEndpointHandles);
    this.buffer = null;
    this.handles = null;
    this.encoder = null;
    this.payload = null;
    this.associatedEndpointHandles = null;

    return message;
  };

  // MessageReader ------------------------------------------------------------

  function MessageReader(message) {
    this.decoder = new Decoder(message.buffer, message.handles,
        message.associatedEndpointHandles, 0);
    var messageHeaderSize = this.decoder.readUint32();
    this.payloadSize = message.buffer.byteLength - messageHeaderSize;
    var version = this.decoder.readUint32();
    var interface_id = this.decoder.readUint32();
    this.messageName = this.decoder.readUint32();
    this.flags = this.decoder.readUint32();
    // Skip the padding.
    this.decoder.skip(4);
    if (version >= 1)
      this.requestID = this.decoder.readUint64();
    this.decoder.skip(messageHeaderSize - this.decoder.next);
  }

  MessageReader.prototype.decodeStruct = function(cls) {
    return cls.decode(this.decoder);
  };

  // Built-in types -----------------------------------------------------------

  // This type is only used with ArrayOf(PackedBool).
  function PackedBool() {
  }

  function Int8() {
  }

  Int8.encodedSize = 1;

  Int8.decode = function(decoder) {
    return decoder.readInt8();
  };

  Int8.encode = function(encoder, val) {
    encoder.writeInt8(val);
  };

  Uint8.encode = function(encoder, val) {
    encoder.writeUint8(val);
  };

  function Uint8() {
  }

  Uint8.encodedSize = 1;

  Uint8.decode = function(decoder) {
    return decoder.readUint8();
  };

  Uint8.encode = function(encoder, val) {
    encoder.writeUint8(val);
  };

  function Int16() {
  }

  Int16.encodedSize = 2;

  Int16.decode = function(decoder) {
    return decoder.readInt16();
  };

  Int16.encode = function(encoder, val) {
    encoder.writeInt16(val);
  };

  function Uint16() {
  }

  Uint16.encodedSize = 2;

  Uint16.decode = function(decoder) {
    return decoder.readUint16();
  };

  Uint16.encode = function(encoder, val) {
    encoder.writeUint16(val);
  };

  function Int32() {
  }

  Int32.encodedSize = 4;

  Int32.decode = function(decoder) {
    return decoder.readInt32();
  };

  Int32.encode = function(encoder, val) {
    encoder.writeInt32(val);
  };

  function Uint32() {
  }

  Uint32.encodedSize = 4;

  Uint32.decode = function(decoder) {
    return decoder.readUint32();
  };

  Uint32.encode = function(encoder, val) {
    encoder.writeUint32(val);
  };

  function Int64() {
  }

  Int64.encodedSize = 8;

  Int64.decode = function(decoder) {
    return decoder.readInt64();
  };

  Int64.encode = function(encoder, val) {
    encoder.writeInt64(val);
  };

  function Uint64() {
  }

  Uint64.encodedSize = 8;

  Uint64.decode = function(decoder) {
    return decoder.readUint64();
  };

  Uint64.encode = function(encoder, val) {
    encoder.writeUint64(val);
  };

  function String() {
  };

  String.encodedSize = 8;

  String.decode = function(decoder) {
    return decoder.decodeStringPointer();
  };

  String.encode = function(encoder, val) {
    encoder.encodeStringPointer(val);
  };

  function NullableString() {
  }

  NullableString.encodedSize = String.encodedSize;

  NullableString.decode = String.decode;

  NullableString.encode = String.encode;

  function Float() {
  }

  Float.encodedSize = 4;

  Float.decode = function(decoder) {
    return decoder.readFloat();
  };

  Float.encode = function(encoder, val) {
    encoder.writeFloat(val);
  };

  function Double() {
  }

  Double.encodedSize = 8;

  Double.decode = function(decoder) {
    return decoder.readDouble();
  };

  Double.encode = function(encoder, val) {
    encoder.writeDouble(val);
  };

  function Enum(cls) {
    this.cls = cls;
  }

  Enum.prototype.encodedSize = 4;

  Enum.prototype.decode = function(decoder) {
    return decoder.readInt32();
  };

  Enum.prototype.encode = function(encoder, val) {
    encoder.writeInt32(val);
  };

  function PointerTo(cls) {
    this.cls = cls;
  }

  PointerTo.prototype.encodedSize = 8;

  PointerTo.prototype.decode = function(decoder) {
    var pointer = decoder.decodePointer();
    if (!pointer) {
      return null;
    }
    return this.cls.decode(decoder.decodeAndCreateDecoder(pointer));
  };

  PointerTo.prototype.encode = function(encoder, val) {
    if (!val) {
      encoder.encodePointer(val);
      return;
    }
    var objectEncoder = encoder.createAndEncodeEncoder(this.cls.encodedSize);
    this.cls.encode(objectEncoder, val);
  };

  function NullablePointerTo(cls) {
    PointerTo.call(this, cls);
  }

  NullablePointerTo.prototype = Object.create(PointerTo.prototype);

  function ArrayOf(cls, length) {
    this.cls = cls;
    this.length = length || 0;
  }

  ArrayOf.prototype.encodedSize = 8;

  ArrayOf.prototype.dimensions = function() {
    return [this.length].concat(
      (this.cls instanceof ArrayOf) ? this.cls.dimensions() : []);
  }

  ArrayOf.prototype.decode = function(decoder) {
    return decoder.decodeArrayPointer(this.cls);
  };

  ArrayOf.prototype.encode = function(encoder, val) {
    encoder.encodeArrayPointer(this.cls, val);
  };

  function NullableArrayOf(cls) {
    ArrayOf.call(this, cls);
  }

  NullableArrayOf.prototype = Object.create(ArrayOf.prototype);

  function Handle() {
  }

  Handle.encodedSize = 4;

  Handle.decode = function(decoder) {
    return decoder.decodeHandle();
  };

  Handle.encode = function(encoder, val) {
    encoder.encodeHandle(val);
  };

  function NullableHandle() {
  }

  NullableHandle.encodedSize = Handle.encodedSize;

  NullableHandle.decode = Handle.decode;

  NullableHandle.encode = Handle.encode;

  function Interface(cls) {
    this.cls = cls;
  }

  Interface.prototype.encodedSize = 8;

  Interface.prototype.decode = function(decoder) {
    var interfacePtrInfo = new mojo.InterfacePtrInfo(
        decoder.decodeHandle(), decoder.readUint32());
    var interfacePtr = new this.cls();
    interfacePtr.ptr.bind(interfacePtrInfo);
    return interfacePtr;
  };

  Interface.prototype.encode = function(encoder, val) {
    var interfacePtrInfo =
        val ? val.ptr.passInterface() : new mojo.InterfacePtrInfo(null, 0);
    encoder.encodeHandle(interfacePtrInfo.handle);
    encoder.writeUint32(interfacePtrInfo.version);
  };

  function NullableInterface(cls) {
    Interface.call(this, cls);
  }

  NullableInterface.prototype = Object.create(Interface.prototype);

  function AssociatedInterfacePtrInfo() {
  }

  AssociatedInterfacePtrInfo.prototype.encodedSize = 8;

  AssociatedInterfacePtrInfo.decode = function(decoder) {
    return new mojo.AssociatedInterfacePtrInfo(
      decoder.decodeAssociatedEndpointHandle(), decoder.readUint32());
  };

  AssociatedInterfacePtrInfo.encode = function(encoder, val) {
    var associatedinterfacePtrInfo =
        val ? val : new mojo.AssociatedInterfacePtrInfo(null, 0);
    encoder.encodeAssociatedEndpointHandle(
        associatedinterfacePtrInfo.interfaceEndpointHandle);
    encoder.writeUint32(associatedinterfacePtrInfo.version);
  };

  function NullableAssociatedInterfacePtrInfo() {
  }

  NullableAssociatedInterfacePtrInfo.encodedSize =
      AssociatedInterfacePtrInfo.encodedSize;

  NullableAssociatedInterfacePtrInfo.decode =
      AssociatedInterfacePtrInfo.decode;

  NullableAssociatedInterfacePtrInfo.encode =
      AssociatedInterfacePtrInfo.encode;

  function InterfaceRequest() {
  }

  InterfaceRequest.encodedSize = 4;

  InterfaceRequest.decode = function(decoder) {
    return new mojo.InterfaceRequest(decoder.decodeHandle());
  };

  InterfaceRequest.encode = function(encoder, val) {
    encoder.encodeHandle(val ? val.handle : null);
  };

  function NullableInterfaceRequest() {
  }

  NullableInterfaceRequest.encodedSize = InterfaceRequest.encodedSize;

  NullableInterfaceRequest.decode = InterfaceRequest.decode;

  NullableInterfaceRequest.encode = InterfaceRequest.encode;

  function AssociatedInterfaceRequest() {
  }

  AssociatedInterfaceRequest.decode = function(decoder) {
    var handle = decoder.decodeAssociatedEndpointHandle();
    return new mojo.AssociatedInterfaceRequest(handle);
  };

  AssociatedInterfaceRequest.encode = function(encoder, val) {
    encoder.encodeAssociatedEndpointHandle(
        val ? val.interfaceEndpointHandle : null);
  };

  AssociatedInterfaceRequest.encodedSize = 4;

  function NullableAssociatedInterfaceRequest() {
  }

  NullableAssociatedInterfaceRequest.encodedSize =
      AssociatedInterfaceRequest.encodedSize;

  NullableAssociatedInterfaceRequest.decode =
      AssociatedInterfaceRequest.decode;

  NullableAssociatedInterfaceRequest.encode =
      AssociatedInterfaceRequest.encode;

  function MapOf(keyClass, valueClass) {
    this.keyClass = keyClass;
    this.valueClass = valueClass;
  }

  MapOf.prototype.encodedSize = 8;

  MapOf.prototype.decode = function(decoder) {
    return decoder.decodeMapPointer(this.keyClass, this.valueClass);
  };

  MapOf.prototype.encode = function(encoder, val) {
    encoder.encodeMapPointer(this.keyClass, this.valueClass, val);
  };

  function NullableMapOf(keyClass, valueClass) {
    MapOf.call(this, keyClass, valueClass);
  }

  NullableMapOf.prototype = Object.create(MapOf.prototype);

  internal.align = align;
  internal.isAligned = isAligned;
  internal.Message = Message;
  internal.MessageV0Builder = MessageV0Builder;
  internal.MessageV1Builder = MessageV1Builder;
  internal.MessageV2Builder = MessageV2Builder;
  internal.MessageReader = MessageReader;
  internal.kArrayHeaderSize = kArrayHeaderSize;
  internal.kMapStructPayloadSize = kMapStructPayloadSize;
  internal.kStructHeaderSize = kStructHeaderSize;
  internal.kEncodedInvalidHandleValue = kEncodedInvalidHandleValue;
  internal.kMessageV0HeaderSize = kMessageV0HeaderSize;
  internal.kMessageV1HeaderSize = kMessageV1HeaderSize;
  internal.kMessageV2HeaderSize = kMessageV2HeaderSize;
  internal.kMessagePayloadInterfaceIdsPointerOffset =
      kMessagePayloadInterfaceIdsPointerOffset;
  internal.kMessageExpectsResponse = kMessageExpectsResponse;
  internal.kMessageIsResponse = kMessageIsResponse;
  internal.Int8 = Int8;
  internal.Uint8 = Uint8;
  internal.Int16 = Int16;
  internal.Uint16 = Uint16;
  internal.Int32 = Int32;
  internal.Uint32 = Uint32;
  internal.Int64 = Int64;
  internal.Uint64 = Uint64;
  internal.Float = Float;
  internal.Double = Double;
  internal.String = String;
  internal.Enum = Enum;
  internal.NullableString = NullableString;
  internal.PointerTo = PointerTo;
  internal.NullablePointerTo = NullablePointerTo;
  internal.ArrayOf = ArrayOf;
  internal.NullableArrayOf = NullableArrayOf;
  internal.PackedBool = PackedBool;
  internal.Handle = Handle;
  internal.NullableHandle = NullableHandle;
  internal.Interface = Interface;
  internal.NullableInterface = NullableInterface;
  internal.InterfaceRequest = InterfaceRequest;
  internal.NullableInterfaceRequest = NullableInterfaceRequest;
  internal.AssociatedInterfacePtrInfo = AssociatedInterfacePtrInfo;
  internal.NullableAssociatedInterfacePtrInfo =
      NullableAssociatedInterfacePtrInfo;
  internal.AssociatedInterfaceRequest = AssociatedInterfaceRequest;
  internal.NullableAssociatedInterfaceRequest =
      NullableAssociatedInterfaceRequest;
  internal.MapOf = MapOf;
  internal.NullableMapOf = NullableMapOf;
})();
