// chrome/common/importer/profile_import.mojom.js is auto generated by mojom_bindings_generator.py, do not edit

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

'use strict';

(function() {
  var mojomId = 'chrome/common/importer/profile_import.mojom';
  if (mojo.internal.isMojomLoaded(mojomId)) {
    console.warn('The following mojom is loaded multiple times: ' + mojomId);
    return;
  }
  mojo.internal.markMojomLoaded(mojomId);
  var bindings = mojo;
  var associatedBindings = mojo;
  var codec = mojo.internal;
  var validator = mojo.internal;

  var exports = mojo.internal.exposeNamespace('chrome.mojom');
  var string16$ =
      mojo.internal.exposeNamespace('mojoBase.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'mojo/public/mojom/base/string16.mojom', '../../../mojo/public/mojom/base/string16.mojom.js');
  }
  var sandbox$ =
      mojo.internal.exposeNamespace('sandbox.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'sandbox/policy/mojom/sandbox.mojom', '../../../sandbox/policy/mojom/sandbox.mojom.js');
  }
  var url$ =
      mojo.internal.exposeNamespace('url.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'url/mojom/url.mojom', '../../../url/mojom/url.mojom.js');
  }


  var ImportItem = {};

  ImportItem.isKnownEnumValue = function(value) {
    return false;
  };

  ImportItem.toKnownEnumValue = function(value) {
    return value;
  };

  ImportItem.validate = function(enumValue) {
    const isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };

  function ImportedBookmarkEntry(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ImportedBookmarkEntry.prototype.initDefaults_ = function() {
  };
  ImportedBookmarkEntry.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ImportedBookmarkEntry.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ImportedBookmarkEntry.encodedSize = codec.kStructHeaderSize + 0;

  ImportedBookmarkEntry.decode = function(decoder) {
    var packed;
    var val = new ImportedBookmarkEntry();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  ImportedBookmarkEntry.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ImportedBookmarkEntry.encodedSize);
    encoder.writeUint32(0);
  };
  function ImporterAutofillFormDataEntry(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ImporterAutofillFormDataEntry.prototype.initDefaults_ = function() {
  };
  ImporterAutofillFormDataEntry.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ImporterAutofillFormDataEntry.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ImporterAutofillFormDataEntry.encodedSize = codec.kStructHeaderSize + 0;

  ImporterAutofillFormDataEntry.decode = function(decoder) {
    var packed;
    var val = new ImporterAutofillFormDataEntry();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  ImporterAutofillFormDataEntry.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ImporterAutofillFormDataEntry.encodedSize);
    encoder.writeUint32(0);
  };
  function SearchEngineInfo(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  SearchEngineInfo.prototype.initDefaults_ = function() {
  };
  SearchEngineInfo.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  SearchEngineInfo.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  SearchEngineInfo.encodedSize = codec.kStructHeaderSize + 0;

  SearchEngineInfo.decode = function(decoder) {
    var packed;
    var val = new SearchEngineInfo();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  SearchEngineInfo.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(SearchEngineInfo.encodedSize);
    encoder.writeUint32(0);
  };
  function ImporterURLRow(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ImporterURLRow.prototype.initDefaults_ = function() {
  };
  ImporterURLRow.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ImporterURLRow.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ImporterURLRow.encodedSize = codec.kStructHeaderSize + 0;

  ImporterURLRow.decode = function(decoder) {
    var packed;
    var val = new ImporterURLRow();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  ImporterURLRow.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ImporterURLRow.encodedSize);
    encoder.writeUint32(0);
  };
  function SourceProfile(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  SourceProfile.prototype.initDefaults_ = function() {
  };
  SourceProfile.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  SourceProfile.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  SourceProfile.encodedSize = codec.kStructHeaderSize + 0;

  SourceProfile.decode = function(decoder) {
    var packed;
    var val = new SourceProfile();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  SourceProfile.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(SourceProfile.encodedSize);
    encoder.writeUint32(0);
  };
  function FaviconUsageDataList(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  FaviconUsageDataList.prototype.initDefaults_ = function() {
  };
  FaviconUsageDataList.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  FaviconUsageDataList.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  FaviconUsageDataList.encodedSize = codec.kStructHeaderSize + 0;

  FaviconUsageDataList.decode = function(decoder) {
    var packed;
    var val = new FaviconUsageDataList();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  FaviconUsageDataList.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(FaviconUsageDataList.encodedSize);
    encoder.writeUint32(0);
  };
  function ImporterIE7PasswordInfo(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ImporterIE7PasswordInfo.prototype.initDefaults_ = function() {
  };
  ImporterIE7PasswordInfo.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ImporterIE7PasswordInfo.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ImporterIE7PasswordInfo.encodedSize = codec.kStructHeaderSize + 0;

  ImporterIE7PasswordInfo.decode = function(decoder) {
    var packed;
    var val = new ImporterIE7PasswordInfo();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  ImporterIE7PasswordInfo.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ImporterIE7PasswordInfo.encodedSize);
    encoder.writeUint32(0);
  };
  function ImportedPasswordForm(values) {
    this.initDefaults_();
    this.initFields_(values);
  }

  ImportedPasswordForm.Scheme = {};
  ImportedPasswordForm.Scheme.kHtml = 0;
  ImportedPasswordForm.Scheme.kBasic = 1;
  ImportedPasswordForm.Scheme.MIN_VALUE = 0;
  ImportedPasswordForm.Scheme.MAX_VALUE = 1;

  ImportedPasswordForm.Scheme.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
      return true;
    }
    return false;
  };

  ImportedPasswordForm.Scheme.toKnownEnumValue = function(value) {
    return value;
  };

  ImportedPasswordForm.Scheme.validate = function(enumValue) {
    const isExtensible = false;
    if (isExtensible || this.isKnownEnumValue(enumValue))
      return validator.validationError.NONE;

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };

  ImportedPasswordForm.prototype.initDefaults_ = function() {
    this.scheme = 0;
    this.blockedByUser = false;
    this.signonRealm = null;
    this.url = null;
    this.action = null;
    this.usernameElement = null;
    this.usernameValue = null;
    this.passwordElement = null;
    this.passwordValue = null;
  };
  ImportedPasswordForm.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ImportedPasswordForm.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 72}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ImportedPasswordForm.scheme
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, ImportedPasswordForm.Scheme);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ImportedPasswordForm.signonRealm
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate ImportedPasswordForm.url
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 16, url$.Url, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ImportedPasswordForm.action
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 24, url$.Url, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ImportedPasswordForm.usernameElement
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 32, string16$.String16, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ImportedPasswordForm.usernameValue
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 40, string16$.String16, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ImportedPasswordForm.passwordElement
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 48, string16$.String16, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ImportedPasswordForm.passwordValue
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 56, string16$.String16, false);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  ImportedPasswordForm.encodedSize = codec.kStructHeaderSize + 64;

  ImportedPasswordForm.decode = function(decoder) {
    var packed;
    var val = new ImportedPasswordForm();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.scheme =
        decoder.decodeStruct(new codec.Enum(ImportedPasswordForm.Scheme));
    packed = decoder.readUint8();
    val.blockedByUser = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.signonRealm =
        decoder.decodeStruct(codec.String);
    val.url =
        decoder.decodeStructPointer(url$.Url);
    val.action =
        decoder.decodeStructPointer(url$.Url);
    val.usernameElement =
        decoder.decodeStructPointer(string16$.String16);
    val.usernameValue =
        decoder.decodeStructPointer(string16$.String16);
    val.passwordElement =
        decoder.decodeStructPointer(string16$.String16);
    val.passwordValue =
        decoder.decodeStructPointer(string16$.String16);
    return val;
  };

  ImportedPasswordForm.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ImportedPasswordForm.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.scheme);
    packed = 0;
    packed |= (val.blockedByUser & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStruct(codec.String, val.signonRealm);
    encoder.encodeStructPointer(url$.Url, val.url);
    encoder.encodeStructPointer(url$.Url, val.action);
    encoder.encodeStructPointer(string16$.String16, val.usernameElement);
    encoder.encodeStructPointer(string16$.String16, val.usernameValue);
    encoder.encodeStructPointer(string16$.String16, val.passwordElement);
    encoder.encodeStructPointer(string16$.String16, val.passwordValue);
  };
  function ProfileImportObserver_OnImportStart_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnImportStart_Params.prototype.initDefaults_ = function() {
  };
  ProfileImportObserver_OnImportStart_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnImportStart_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnImportStart_Params.encodedSize = codec.kStructHeaderSize + 0;

  ProfileImportObserver_OnImportStart_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnImportStart_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  ProfileImportObserver_OnImportStart_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnImportStart_Params.encodedSize);
    encoder.writeUint32(0);
  };
  function ProfileImportObserver_OnImportFinished_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnImportFinished_Params.prototype.initDefaults_ = function() {
    this.succeeded = false;
    this.errorMsg = null;
  };
  ProfileImportObserver_OnImportFinished_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnImportFinished_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;



    // validate ProfileImportObserver_OnImportFinished_Params.errorMsg
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false)
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnImportFinished_Params.encodedSize = codec.kStructHeaderSize + 16;

  ProfileImportObserver_OnImportFinished_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnImportFinished_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    packed = decoder.readUint8();
    val.succeeded = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.errorMsg =
        decoder.decodeStruct(codec.String);
    return val;
  };

  ProfileImportObserver_OnImportFinished_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnImportFinished_Params.encodedSize);
    encoder.writeUint32(0);
    packed = 0;
    packed |= (val.succeeded & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStruct(codec.String, val.errorMsg);
  };
  function ProfileImportObserver_OnImportItemStart_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnImportItemStart_Params.prototype.initDefaults_ = function() {
    this.item = 0;
  };
  ProfileImportObserver_OnImportItemStart_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnImportItemStart_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ProfileImportObserver_OnImportItemStart_Params.item
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, ImportItem);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnImportItemStart_Params.encodedSize = codec.kStructHeaderSize + 8;

  ProfileImportObserver_OnImportItemStart_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnImportItemStart_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.item =
        decoder.decodeStruct(new codec.Enum(ImportItem));
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  ProfileImportObserver_OnImportItemStart_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnImportItemStart_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.item);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function ProfileImportObserver_OnImportItemFinished_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnImportItemFinished_Params.prototype.initDefaults_ = function() {
    this.item = 0;
  };
  ProfileImportObserver_OnImportItemFinished_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnImportItemFinished_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ProfileImportObserver_OnImportItemFinished_Params.item
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, ImportItem);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnImportItemFinished_Params.encodedSize = codec.kStructHeaderSize + 8;

  ProfileImportObserver_OnImportItemFinished_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnImportItemFinished_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.item =
        decoder.decodeStruct(new codec.Enum(ImportItem));
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  ProfileImportObserver_OnImportItemFinished_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnImportItemFinished_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.item);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function ProfileImportObserver_OnHistoryImportStart_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnHistoryImportStart_Params.prototype.initDefaults_ = function() {
    this.totalHistoryRowsCount = 0;
  };
  ProfileImportObserver_OnHistoryImportStart_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnHistoryImportStart_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnHistoryImportStart_Params.encodedSize = codec.kStructHeaderSize + 8;

  ProfileImportObserver_OnHistoryImportStart_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnHistoryImportStart_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.totalHistoryRowsCount =
        decoder.decodeStruct(codec.Uint32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  ProfileImportObserver_OnHistoryImportStart_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnHistoryImportStart_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Uint32, val.totalHistoryRowsCount);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function ProfileImportObserver_OnHistoryImportGroup_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnHistoryImportGroup_Params.prototype.initDefaults_ = function() {
    this.historyRowsGroup = null;
    this.visitSource = 0;
  };
  ProfileImportObserver_OnHistoryImportGroup_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnHistoryImportGroup_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ProfileImportObserver_OnHistoryImportGroup_Params.historyRowsGroup
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(ImporterURLRow), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnHistoryImportGroup_Params.encodedSize = codec.kStructHeaderSize + 16;

  ProfileImportObserver_OnHistoryImportGroup_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnHistoryImportGroup_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.historyRowsGroup =
        decoder.decodeArrayPointer(new codec.PointerTo(ImporterURLRow));
    val.visitSource =
        decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  ProfileImportObserver_OnHistoryImportGroup_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnHistoryImportGroup_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeArrayPointer(new codec.PointerTo(ImporterURLRow), val.historyRowsGroup);
    encoder.encodeStruct(codec.Int32, val.visitSource);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function ProfileImportObserver_OnHomePageImportReady_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnHomePageImportReady_Params.prototype.initDefaults_ = function() {
    this.homePage = null;
  };
  ProfileImportObserver_OnHomePageImportReady_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnHomePageImportReady_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ProfileImportObserver_OnHomePageImportReady_Params.homePage
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, url$.Url, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnHomePageImportReady_Params.encodedSize = codec.kStructHeaderSize + 8;

  ProfileImportObserver_OnHomePageImportReady_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnHomePageImportReady_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.homePage =
        decoder.decodeStructPointer(url$.Url);
    return val;
  };

  ProfileImportObserver_OnHomePageImportReady_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnHomePageImportReady_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(url$.Url, val.homePage);
  };
  function ProfileImportObserver_OnBookmarksImportStart_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnBookmarksImportStart_Params.prototype.initDefaults_ = function() {
    this.firstFolderName = null;
    this.totalBookmarksCount = 0;
  };
  ProfileImportObserver_OnBookmarksImportStart_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnBookmarksImportStart_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ProfileImportObserver_OnBookmarksImportStart_Params.firstFolderName
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, string16$.String16, false);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnBookmarksImportStart_Params.encodedSize = codec.kStructHeaderSize + 16;

  ProfileImportObserver_OnBookmarksImportStart_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnBookmarksImportStart_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.firstFolderName =
        decoder.decodeStructPointer(string16$.String16);
    val.totalBookmarksCount =
        decoder.decodeStruct(codec.Uint32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  ProfileImportObserver_OnBookmarksImportStart_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnBookmarksImportStart_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(string16$.String16, val.firstFolderName);
    encoder.encodeStruct(codec.Uint32, val.totalBookmarksCount);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function ProfileImportObserver_OnBookmarksImportGroup_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnBookmarksImportGroup_Params.prototype.initDefaults_ = function() {
    this.bookmarksGroup = null;
  };
  ProfileImportObserver_OnBookmarksImportGroup_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnBookmarksImportGroup_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ProfileImportObserver_OnBookmarksImportGroup_Params.bookmarksGroup
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(ImportedBookmarkEntry), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnBookmarksImportGroup_Params.encodedSize = codec.kStructHeaderSize + 8;

  ProfileImportObserver_OnBookmarksImportGroup_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnBookmarksImportGroup_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.bookmarksGroup =
        decoder.decodeArrayPointer(new codec.PointerTo(ImportedBookmarkEntry));
    return val;
  };

  ProfileImportObserver_OnBookmarksImportGroup_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnBookmarksImportGroup_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeArrayPointer(new codec.PointerTo(ImportedBookmarkEntry), val.bookmarksGroup);
  };
  function ProfileImportObserver_OnFaviconsImportStart_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnFaviconsImportStart_Params.prototype.initDefaults_ = function() {
    this.totalFaviconsCount = 0;
  };
  ProfileImportObserver_OnFaviconsImportStart_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnFaviconsImportStart_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnFaviconsImportStart_Params.encodedSize = codec.kStructHeaderSize + 8;

  ProfileImportObserver_OnFaviconsImportStart_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnFaviconsImportStart_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.totalFaviconsCount =
        decoder.decodeStruct(codec.Uint32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  ProfileImportObserver_OnFaviconsImportStart_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnFaviconsImportStart_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Uint32, val.totalFaviconsCount);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function ProfileImportObserver_OnFaviconsImportGroup_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnFaviconsImportGroup_Params.prototype.initDefaults_ = function() {
    this.faviconsGroup = null;
  };
  ProfileImportObserver_OnFaviconsImportGroup_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnFaviconsImportGroup_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ProfileImportObserver_OnFaviconsImportGroup_Params.faviconsGroup
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, FaviconUsageDataList, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnFaviconsImportGroup_Params.encodedSize = codec.kStructHeaderSize + 8;

  ProfileImportObserver_OnFaviconsImportGroup_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnFaviconsImportGroup_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.faviconsGroup =
        decoder.decodeStructPointer(FaviconUsageDataList);
    return val;
  };

  ProfileImportObserver_OnFaviconsImportGroup_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnFaviconsImportGroup_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(FaviconUsageDataList, val.faviconsGroup);
  };
  function ProfileImportObserver_OnPasswordFormImportReady_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnPasswordFormImportReady_Params.prototype.initDefaults_ = function() {
    this.form = null;
  };
  ProfileImportObserver_OnPasswordFormImportReady_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnPasswordFormImportReady_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ProfileImportObserver_OnPasswordFormImportReady_Params.form
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, ImportedPasswordForm, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnPasswordFormImportReady_Params.encodedSize = codec.kStructHeaderSize + 8;

  ProfileImportObserver_OnPasswordFormImportReady_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnPasswordFormImportReady_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.form =
        decoder.decodeStructPointer(ImportedPasswordForm);
    return val;
  };

  ProfileImportObserver_OnPasswordFormImportReady_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnPasswordFormImportReady_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(ImportedPasswordForm, val.form);
  };
  function ProfileImportObserver_OnKeywordsImportReady_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnKeywordsImportReady_Params.prototype.initDefaults_ = function() {
    this.searchEngines = null;
    this.uniqueOnHostAndPath = false;
  };
  ProfileImportObserver_OnKeywordsImportReady_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnKeywordsImportReady_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 24}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ProfileImportObserver_OnKeywordsImportReady_Params.searchEngines
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(SearchEngineInfo), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnKeywordsImportReady_Params.encodedSize = codec.kStructHeaderSize + 16;

  ProfileImportObserver_OnKeywordsImportReady_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnKeywordsImportReady_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.searchEngines =
        decoder.decodeArrayPointer(new codec.PointerTo(SearchEngineInfo));
    packed = decoder.readUint8();
    val.uniqueOnHostAndPath = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  ProfileImportObserver_OnKeywordsImportReady_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnKeywordsImportReady_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeArrayPointer(new codec.PointerTo(SearchEngineInfo), val.searchEngines);
    packed = 0;
    packed |= (val.uniqueOnHostAndPath & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function ProfileImportObserver_OnAutofillFormDataImportStart_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnAutofillFormDataImportStart_Params.prototype.initDefaults_ = function() {
    this.totalAutofillFormDataEntryCount = 0;
  };
  ProfileImportObserver_OnAutofillFormDataImportStart_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnAutofillFormDataImportStart_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnAutofillFormDataImportStart_Params.encodedSize = codec.kStructHeaderSize + 8;

  ProfileImportObserver_OnAutofillFormDataImportStart_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnAutofillFormDataImportStart_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.totalAutofillFormDataEntryCount =
        decoder.decodeStruct(codec.Uint32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  ProfileImportObserver_OnAutofillFormDataImportStart_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnAutofillFormDataImportStart_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Uint32, val.totalAutofillFormDataEntryCount);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function ProfileImportObserver_OnAutofillFormDataImportGroup_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImportObserver_OnAutofillFormDataImportGroup_Params.prototype.initDefaults_ = function() {
    this.autofillFormDataEntryGroup = null;
  };
  ProfileImportObserver_OnAutofillFormDataImportGroup_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImportObserver_OnAutofillFormDataImportGroup_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ProfileImportObserver_OnAutofillFormDataImportGroup_Params.autofillFormDataEntryGroup
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(ImporterAutofillFormDataEntry), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ProfileImportObserver_OnAutofillFormDataImportGroup_Params.encodedSize = codec.kStructHeaderSize + 8;

  ProfileImportObserver_OnAutofillFormDataImportGroup_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImportObserver_OnAutofillFormDataImportGroup_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.autofillFormDataEntryGroup =
        decoder.decodeArrayPointer(new codec.PointerTo(ImporterAutofillFormDataEntry));
    return val;
  };

  ProfileImportObserver_OnAutofillFormDataImportGroup_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImportObserver_OnAutofillFormDataImportGroup_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeArrayPointer(new codec.PointerTo(ImporterAutofillFormDataEntry), val.autofillFormDataEntryGroup);
  };
  function ProfileImport_StartImport_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImport_StartImport_Params.prototype.initDefaults_ = function() {
    this.sourceProfile = null;
    this.items = 0;
    this.localizedStrings = null;
    this.observer = new ProfileImportObserverPtr();
  };
  ProfileImport_StartImport_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImport_StartImport_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 40}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ProfileImport_StartImport_Params.sourceProfile
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, SourceProfile, false);
    if (err !== validator.validationError.NONE)
        return err;



    // validate ProfileImport_StartImport_Params.localizedStrings
    err = messageValidator.validateMapPointer(offset + codec.kStructHeaderSize + 16, false, codec.Uint32, codec.String, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ProfileImport_StartImport_Params.observer
    err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 24, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ProfileImport_StartImport_Params.encodedSize = codec.kStructHeaderSize + 32;

  ProfileImport_StartImport_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImport_StartImport_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.sourceProfile =
        decoder.decodeStructPointer(SourceProfile);
    val.items =
        decoder.decodeStruct(codec.Uint16);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.localizedStrings =
        decoder.decodeMapPointer(codec.Uint32, codec.String);
    val.observer =
        decoder.decodeStruct(new codec.Interface(ProfileImportObserverPtr));
    return val;
  };

  ProfileImport_StartImport_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImport_StartImport_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(SourceProfile, val.sourceProfile);
    encoder.encodeStruct(codec.Uint16, val.items);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeMapPointer(codec.Uint32, codec.String, val.localizedStrings);
    encoder.encodeStruct(new codec.Interface(ProfileImportObserverPtr), val.observer);
  };
  function ProfileImport_CancelImport_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImport_CancelImport_Params.prototype.initDefaults_ = function() {
  };
  ProfileImport_CancelImport_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImport_CancelImport_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 8}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ProfileImport_CancelImport_Params.encodedSize = codec.kStructHeaderSize + 0;

  ProfileImport_CancelImport_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImport_CancelImport_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    return val;
  };

  ProfileImport_CancelImport_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImport_CancelImport_Params.encodedSize);
    encoder.writeUint32(0);
  };
  function ProfileImport_ReportImportItemFinished_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  ProfileImport_ReportImportItemFinished_Params.prototype.initDefaults_ = function() {
    this.item = 0;
  };
  ProfileImport_ReportImportItemFinished_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ProfileImport_ReportImportItemFinished_Params.validate = function(messageValidator, offset) {
    var err;
    err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize);
    if (err !== validator.validationError.NONE)
        return err;

    var kVersionSizes = [
      {version: 0, numBytes: 16}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ProfileImport_ReportImportItemFinished_Params.item
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, ImportItem);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ProfileImport_ReportImportItemFinished_Params.encodedSize = codec.kStructHeaderSize + 8;

  ProfileImport_ReportImportItemFinished_Params.decode = function(decoder) {
    var packed;
    var val = new ProfileImport_ReportImportItemFinished_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.item =
        decoder.decodeStruct(new codec.Enum(ImportItem));
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  ProfileImport_ReportImportItemFinished_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ProfileImport_ReportImportItemFinished_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.item);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  var kProfileImportObserver_OnImportStart_Name = 0;
  var kProfileImportObserver_OnImportFinished_Name = 1;
  var kProfileImportObserver_OnImportItemStart_Name = 2;
  var kProfileImportObserver_OnImportItemFinished_Name = 3;
  var kProfileImportObserver_OnHistoryImportStart_Name = 4;
  var kProfileImportObserver_OnHistoryImportGroup_Name = 5;
  var kProfileImportObserver_OnHomePageImportReady_Name = 6;
  var kProfileImportObserver_OnBookmarksImportStart_Name = 7;
  var kProfileImportObserver_OnBookmarksImportGroup_Name = 8;
  var kProfileImportObserver_OnFaviconsImportStart_Name = 9;
  var kProfileImportObserver_OnFaviconsImportGroup_Name = 10;
  var kProfileImportObserver_OnPasswordFormImportReady_Name = 11;
  var kProfileImportObserver_OnKeywordsImportReady_Name = 12;
  var kProfileImportObserver_OnAutofillFormDataImportStart_Name = 13;
  var kProfileImportObserver_OnAutofillFormDataImportGroup_Name = 14;

  function ProfileImportObserverPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(ProfileImportObserver,
                                                   handleOrPtrInfo);
  }

  function ProfileImportObserverAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        ProfileImportObserver, associatedInterfacePtrInfo);
  }

  ProfileImportObserverAssociatedPtr.prototype =
      Object.create(ProfileImportObserverPtr.prototype);
  ProfileImportObserverAssociatedPtr.prototype.constructor =
      ProfileImportObserverAssociatedPtr;

  function ProfileImportObserverProxy(receiver) {
    this.receiver_ = receiver;
  }
  ProfileImportObserverPtr.prototype.onImportStart = function() {
    return ProfileImportObserverProxy.prototype.onImportStart
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onImportStart = function() {
    var params_ = new ProfileImportObserver_OnImportStart_Params();
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnImportStart_Name,
        codec.align(ProfileImportObserver_OnImportStart_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnImportStart_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onImportFinished = function() {
    return ProfileImportObserverProxy.prototype.onImportFinished
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onImportFinished = function(succeeded, errorMsg) {
    var params_ = new ProfileImportObserver_OnImportFinished_Params();
    params_.succeeded = succeeded;
    params_.errorMsg = errorMsg;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnImportFinished_Name,
        codec.align(ProfileImportObserver_OnImportFinished_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnImportFinished_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onImportItemStart = function() {
    return ProfileImportObserverProxy.prototype.onImportItemStart
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onImportItemStart = function(item) {
    var params_ = new ProfileImportObserver_OnImportItemStart_Params();
    params_.item = item;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnImportItemStart_Name,
        codec.align(ProfileImportObserver_OnImportItemStart_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnImportItemStart_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onImportItemFinished = function() {
    return ProfileImportObserverProxy.prototype.onImportItemFinished
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onImportItemFinished = function(item) {
    var params_ = new ProfileImportObserver_OnImportItemFinished_Params();
    params_.item = item;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnImportItemFinished_Name,
        codec.align(ProfileImportObserver_OnImportItemFinished_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnImportItemFinished_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onHistoryImportStart = function() {
    return ProfileImportObserverProxy.prototype.onHistoryImportStart
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onHistoryImportStart = function(totalHistoryRowsCount) {
    var params_ = new ProfileImportObserver_OnHistoryImportStart_Params();
    params_.totalHistoryRowsCount = totalHistoryRowsCount;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnHistoryImportStart_Name,
        codec.align(ProfileImportObserver_OnHistoryImportStart_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnHistoryImportStart_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onHistoryImportGroup = function() {
    return ProfileImportObserverProxy.prototype.onHistoryImportGroup
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onHistoryImportGroup = function(historyRowsGroup, visitSource) {
    var params_ = new ProfileImportObserver_OnHistoryImportGroup_Params();
    params_.historyRowsGroup = historyRowsGroup;
    params_.visitSource = visitSource;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnHistoryImportGroup_Name,
        codec.align(ProfileImportObserver_OnHistoryImportGroup_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnHistoryImportGroup_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onHomePageImportReady = function() {
    return ProfileImportObserverProxy.prototype.onHomePageImportReady
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onHomePageImportReady = function(homePage) {
    var params_ = new ProfileImportObserver_OnHomePageImportReady_Params();
    params_.homePage = homePage;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnHomePageImportReady_Name,
        codec.align(ProfileImportObserver_OnHomePageImportReady_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnHomePageImportReady_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onBookmarksImportStart = function() {
    return ProfileImportObserverProxy.prototype.onBookmarksImportStart
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onBookmarksImportStart = function(firstFolderName, totalBookmarksCount) {
    var params_ = new ProfileImportObserver_OnBookmarksImportStart_Params();
    params_.firstFolderName = firstFolderName;
    params_.totalBookmarksCount = totalBookmarksCount;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnBookmarksImportStart_Name,
        codec.align(ProfileImportObserver_OnBookmarksImportStart_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnBookmarksImportStart_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onBookmarksImportGroup = function() {
    return ProfileImportObserverProxy.prototype.onBookmarksImportGroup
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onBookmarksImportGroup = function(bookmarksGroup) {
    var params_ = new ProfileImportObserver_OnBookmarksImportGroup_Params();
    params_.bookmarksGroup = bookmarksGroup;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnBookmarksImportGroup_Name,
        codec.align(ProfileImportObserver_OnBookmarksImportGroup_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnBookmarksImportGroup_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onFaviconsImportStart = function() {
    return ProfileImportObserverProxy.prototype.onFaviconsImportStart
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onFaviconsImportStart = function(totalFaviconsCount) {
    var params_ = new ProfileImportObserver_OnFaviconsImportStart_Params();
    params_.totalFaviconsCount = totalFaviconsCount;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnFaviconsImportStart_Name,
        codec.align(ProfileImportObserver_OnFaviconsImportStart_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnFaviconsImportStart_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onFaviconsImportGroup = function() {
    return ProfileImportObserverProxy.prototype.onFaviconsImportGroup
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onFaviconsImportGroup = function(faviconsGroup) {
    var params_ = new ProfileImportObserver_OnFaviconsImportGroup_Params();
    params_.faviconsGroup = faviconsGroup;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnFaviconsImportGroup_Name,
        codec.align(ProfileImportObserver_OnFaviconsImportGroup_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnFaviconsImportGroup_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onPasswordFormImportReady = function() {
    return ProfileImportObserverProxy.prototype.onPasswordFormImportReady
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onPasswordFormImportReady = function(form) {
    var params_ = new ProfileImportObserver_OnPasswordFormImportReady_Params();
    params_.form = form;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnPasswordFormImportReady_Name,
        codec.align(ProfileImportObserver_OnPasswordFormImportReady_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnPasswordFormImportReady_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onKeywordsImportReady = function() {
    return ProfileImportObserverProxy.prototype.onKeywordsImportReady
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onKeywordsImportReady = function(searchEngines, uniqueOnHostAndPath) {
    var params_ = new ProfileImportObserver_OnKeywordsImportReady_Params();
    params_.searchEngines = searchEngines;
    params_.uniqueOnHostAndPath = uniqueOnHostAndPath;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnKeywordsImportReady_Name,
        codec.align(ProfileImportObserver_OnKeywordsImportReady_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnKeywordsImportReady_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onAutofillFormDataImportStart = function() {
    return ProfileImportObserverProxy.prototype.onAutofillFormDataImportStart
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onAutofillFormDataImportStart = function(totalAutofillFormDataEntryCount) {
    var params_ = new ProfileImportObserver_OnAutofillFormDataImportStart_Params();
    params_.totalAutofillFormDataEntryCount = totalAutofillFormDataEntryCount;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnAutofillFormDataImportStart_Name,
        codec.align(ProfileImportObserver_OnAutofillFormDataImportStart_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnAutofillFormDataImportStart_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportObserverPtr.prototype.onAutofillFormDataImportGroup = function() {
    return ProfileImportObserverProxy.prototype.onAutofillFormDataImportGroup
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportObserverProxy.prototype.onAutofillFormDataImportGroup = function(autofillFormDataEntryGroup) {
    var params_ = new ProfileImportObserver_OnAutofillFormDataImportGroup_Params();
    params_.autofillFormDataEntryGroup = autofillFormDataEntryGroup;
    var builder = new codec.MessageV0Builder(
        kProfileImportObserver_OnAutofillFormDataImportGroup_Name,
        codec.align(ProfileImportObserver_OnAutofillFormDataImportGroup_Params.encodedSize));
    builder.encodeStruct(ProfileImportObserver_OnAutofillFormDataImportGroup_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };

  function ProfileImportObserverStub(delegate) {
    this.delegate_ = delegate;
  }
  ProfileImportObserverStub.prototype.onImportStart = function() {
    return this.delegate_ && this.delegate_.onImportStart && this.delegate_.onImportStart();
  }
  ProfileImportObserverStub.prototype.onImportFinished = function(succeeded, errorMsg) {
    return this.delegate_ && this.delegate_.onImportFinished && this.delegate_.onImportFinished(succeeded, errorMsg);
  }
  ProfileImportObserverStub.prototype.onImportItemStart = function(item) {
    return this.delegate_ && this.delegate_.onImportItemStart && this.delegate_.onImportItemStart(item);
  }
  ProfileImportObserverStub.prototype.onImportItemFinished = function(item) {
    return this.delegate_ && this.delegate_.onImportItemFinished && this.delegate_.onImportItemFinished(item);
  }
  ProfileImportObserverStub.prototype.onHistoryImportStart = function(totalHistoryRowsCount) {
    return this.delegate_ && this.delegate_.onHistoryImportStart && this.delegate_.onHistoryImportStart(totalHistoryRowsCount);
  }
  ProfileImportObserverStub.prototype.onHistoryImportGroup = function(historyRowsGroup, visitSource) {
    return this.delegate_ && this.delegate_.onHistoryImportGroup && this.delegate_.onHistoryImportGroup(historyRowsGroup, visitSource);
  }
  ProfileImportObserverStub.prototype.onHomePageImportReady = function(homePage) {
    return this.delegate_ && this.delegate_.onHomePageImportReady && this.delegate_.onHomePageImportReady(homePage);
  }
  ProfileImportObserverStub.prototype.onBookmarksImportStart = function(firstFolderName, totalBookmarksCount) {
    return this.delegate_ && this.delegate_.onBookmarksImportStart && this.delegate_.onBookmarksImportStart(firstFolderName, totalBookmarksCount);
  }
  ProfileImportObserverStub.prototype.onBookmarksImportGroup = function(bookmarksGroup) {
    return this.delegate_ && this.delegate_.onBookmarksImportGroup && this.delegate_.onBookmarksImportGroup(bookmarksGroup);
  }
  ProfileImportObserverStub.prototype.onFaviconsImportStart = function(totalFaviconsCount) {
    return this.delegate_ && this.delegate_.onFaviconsImportStart && this.delegate_.onFaviconsImportStart(totalFaviconsCount);
  }
  ProfileImportObserverStub.prototype.onFaviconsImportGroup = function(faviconsGroup) {
    return this.delegate_ && this.delegate_.onFaviconsImportGroup && this.delegate_.onFaviconsImportGroup(faviconsGroup);
  }
  ProfileImportObserverStub.prototype.onPasswordFormImportReady = function(form) {
    return this.delegate_ && this.delegate_.onPasswordFormImportReady && this.delegate_.onPasswordFormImportReady(form);
  }
  ProfileImportObserverStub.prototype.onKeywordsImportReady = function(searchEngines, uniqueOnHostAndPath) {
    return this.delegate_ && this.delegate_.onKeywordsImportReady && this.delegate_.onKeywordsImportReady(searchEngines, uniqueOnHostAndPath);
  }
  ProfileImportObserverStub.prototype.onAutofillFormDataImportStart = function(totalAutofillFormDataEntryCount) {
    return this.delegate_ && this.delegate_.onAutofillFormDataImportStart && this.delegate_.onAutofillFormDataImportStart(totalAutofillFormDataEntryCount);
  }
  ProfileImportObserverStub.prototype.onAutofillFormDataImportGroup = function(autofillFormDataEntryGroup) {
    return this.delegate_ && this.delegate_.onAutofillFormDataImportGroup && this.delegate_.onAutofillFormDataImportGroup(autofillFormDataEntryGroup);
  }

  ProfileImportObserverStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kProfileImportObserver_OnImportStart_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnImportStart_Params);
      this.onImportStart();
      return true;
    case kProfileImportObserver_OnImportFinished_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnImportFinished_Params);
      this.onImportFinished(params.succeeded, params.errorMsg);
      return true;
    case kProfileImportObserver_OnImportItemStart_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnImportItemStart_Params);
      this.onImportItemStart(params.item);
      return true;
    case kProfileImportObserver_OnImportItemFinished_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnImportItemFinished_Params);
      this.onImportItemFinished(params.item);
      return true;
    case kProfileImportObserver_OnHistoryImportStart_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnHistoryImportStart_Params);
      this.onHistoryImportStart(params.totalHistoryRowsCount);
      return true;
    case kProfileImportObserver_OnHistoryImportGroup_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnHistoryImportGroup_Params);
      this.onHistoryImportGroup(params.historyRowsGroup, params.visitSource);
      return true;
    case kProfileImportObserver_OnHomePageImportReady_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnHomePageImportReady_Params);
      this.onHomePageImportReady(params.homePage);
      return true;
    case kProfileImportObserver_OnBookmarksImportStart_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnBookmarksImportStart_Params);
      this.onBookmarksImportStart(params.firstFolderName, params.totalBookmarksCount);
      return true;
    case kProfileImportObserver_OnBookmarksImportGroup_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnBookmarksImportGroup_Params);
      this.onBookmarksImportGroup(params.bookmarksGroup);
      return true;
    case kProfileImportObserver_OnFaviconsImportStart_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnFaviconsImportStart_Params);
      this.onFaviconsImportStart(params.totalFaviconsCount);
      return true;
    case kProfileImportObserver_OnFaviconsImportGroup_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnFaviconsImportGroup_Params);
      this.onFaviconsImportGroup(params.faviconsGroup);
      return true;
    case kProfileImportObserver_OnPasswordFormImportReady_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnPasswordFormImportReady_Params);
      this.onPasswordFormImportReady(params.form);
      return true;
    case kProfileImportObserver_OnKeywordsImportReady_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnKeywordsImportReady_Params);
      this.onKeywordsImportReady(params.searchEngines, params.uniqueOnHostAndPath);
      return true;
    case kProfileImportObserver_OnAutofillFormDataImportStart_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnAutofillFormDataImportStart_Params);
      this.onAutofillFormDataImportStart(params.totalAutofillFormDataEntryCount);
      return true;
    case kProfileImportObserver_OnAutofillFormDataImportGroup_Name:
      var params = reader.decodeStruct(ProfileImportObserver_OnAutofillFormDataImportGroup_Params);
      this.onAutofillFormDataImportGroup(params.autofillFormDataEntryGroup);
      return true;
    default:
      return false;
    }
  };

  ProfileImportObserverStub.prototype.acceptWithResponder =
      function(message, responder) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    default:
      return false;
    }
  };

  function validateProfileImportObserverRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kProfileImportObserver_OnImportStart_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnImportStart_Params;
      break;
      case kProfileImportObserver_OnImportFinished_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnImportFinished_Params;
      break;
      case kProfileImportObserver_OnImportItemStart_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnImportItemStart_Params;
      break;
      case kProfileImportObserver_OnImportItemFinished_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnImportItemFinished_Params;
      break;
      case kProfileImportObserver_OnHistoryImportStart_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnHistoryImportStart_Params;
      break;
      case kProfileImportObserver_OnHistoryImportGroup_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnHistoryImportGroup_Params;
      break;
      case kProfileImportObserver_OnHomePageImportReady_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnHomePageImportReady_Params;
      break;
      case kProfileImportObserver_OnBookmarksImportStart_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnBookmarksImportStart_Params;
      break;
      case kProfileImportObserver_OnBookmarksImportGroup_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnBookmarksImportGroup_Params;
      break;
      case kProfileImportObserver_OnFaviconsImportStart_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnFaviconsImportStart_Params;
      break;
      case kProfileImportObserver_OnFaviconsImportGroup_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnFaviconsImportGroup_Params;
      break;
      case kProfileImportObserver_OnPasswordFormImportReady_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnPasswordFormImportReady_Params;
      break;
      case kProfileImportObserver_OnKeywordsImportReady_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnKeywordsImportReady_Params;
      break;
      case kProfileImportObserver_OnAutofillFormDataImportStart_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnAutofillFormDataImportStart_Params;
      break;
      case kProfileImportObserver_OnAutofillFormDataImportGroup_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImportObserver_OnAutofillFormDataImportGroup_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  function validateProfileImportObserverResponse(messageValidator) {
    return validator.validationError.NONE;
  }

  var ProfileImportObserver = {
    name: 'chrome.mojom.ProfileImportObserver',
    kVersion: 0,
    ptrClass: ProfileImportObserverPtr,
    proxyClass: ProfileImportObserverProxy,
    stubClass: ProfileImportObserverStub,
    validateRequest: validateProfileImportObserverRequest,
    validateResponse: null,
  };
  ProfileImportObserverStub.prototype.validator = validateProfileImportObserverRequest;
  ProfileImportObserverProxy.prototype.validator = null;
  var kProfileImport_StartImport_Name = 0;
  var kProfileImport_CancelImport_Name = 1;
  var kProfileImport_ReportImportItemFinished_Name = 2;

  function ProfileImportPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(ProfileImport,
                                                   handleOrPtrInfo);
  }

  function ProfileImportAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        ProfileImport, associatedInterfacePtrInfo);
  }

  ProfileImportAssociatedPtr.prototype =
      Object.create(ProfileImportPtr.prototype);
  ProfileImportAssociatedPtr.prototype.constructor =
      ProfileImportAssociatedPtr;

  function ProfileImportProxy(receiver) {
    this.receiver_ = receiver;
  }
  ProfileImportPtr.prototype.startImport = function() {
    return ProfileImportProxy.prototype.startImport
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportProxy.prototype.startImport = function(sourceProfile, items, localizedStrings, observer) {
    var params_ = new ProfileImport_StartImport_Params();
    params_.sourceProfile = sourceProfile;
    params_.items = items;
    params_.localizedStrings = localizedStrings;
    params_.observer = observer;
    var builder = new codec.MessageV0Builder(
        kProfileImport_StartImport_Name,
        codec.align(ProfileImport_StartImport_Params.encodedSize));
    builder.encodeStruct(ProfileImport_StartImport_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportPtr.prototype.cancelImport = function() {
    return ProfileImportProxy.prototype.cancelImport
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportProxy.prototype.cancelImport = function() {
    var params_ = new ProfileImport_CancelImport_Params();
    var builder = new codec.MessageV0Builder(
        kProfileImport_CancelImport_Name,
        codec.align(ProfileImport_CancelImport_Params.encodedSize));
    builder.encodeStruct(ProfileImport_CancelImport_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ProfileImportPtr.prototype.reportImportItemFinished = function() {
    return ProfileImportProxy.prototype.reportImportItemFinished
        .apply(this.ptr.getProxy(), arguments);
  };

  ProfileImportProxy.prototype.reportImportItemFinished = function(item) {
    var params_ = new ProfileImport_ReportImportItemFinished_Params();
    params_.item = item;
    var builder = new codec.MessageV0Builder(
        kProfileImport_ReportImportItemFinished_Name,
        codec.align(ProfileImport_ReportImportItemFinished_Params.encodedSize));
    builder.encodeStruct(ProfileImport_ReportImportItemFinished_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };

  function ProfileImportStub(delegate) {
    this.delegate_ = delegate;
  }
  ProfileImportStub.prototype.startImport = function(sourceProfile, items, localizedStrings, observer) {
    return this.delegate_ && this.delegate_.startImport && this.delegate_.startImport(sourceProfile, items, localizedStrings, observer);
  }
  ProfileImportStub.prototype.cancelImport = function() {
    return this.delegate_ && this.delegate_.cancelImport && this.delegate_.cancelImport();
  }
  ProfileImportStub.prototype.reportImportItemFinished = function(item) {
    return this.delegate_ && this.delegate_.reportImportItemFinished && this.delegate_.reportImportItemFinished(item);
  }

  ProfileImportStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kProfileImport_StartImport_Name:
      var params = reader.decodeStruct(ProfileImport_StartImport_Params);
      this.startImport(params.sourceProfile, params.items, params.localizedStrings, params.observer);
      return true;
    case kProfileImport_CancelImport_Name:
      var params = reader.decodeStruct(ProfileImport_CancelImport_Params);
      this.cancelImport();
      return true;
    case kProfileImport_ReportImportItemFinished_Name:
      var params = reader.decodeStruct(ProfileImport_ReportImportItemFinished_Params);
      this.reportImportItemFinished(params.item);
      return true;
    default:
      return false;
    }
  };

  ProfileImportStub.prototype.acceptWithResponder =
      function(message, responder) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    default:
      return false;
    }
  };

  function validateProfileImportRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kProfileImport_StartImport_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImport_StartImport_Params;
      break;
      case kProfileImport_CancelImport_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImport_CancelImport_Params;
      break;
      case kProfileImport_ReportImportItemFinished_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ProfileImport_ReportImportItemFinished_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  function validateProfileImportResponse(messageValidator) {
    return validator.validationError.NONE;
  }

  var ProfileImport = {
    name: 'chrome.mojom.ProfileImport',
    kVersion: 0,
    ptrClass: ProfileImportPtr,
    proxyClass: ProfileImportProxy,
    stubClass: ProfileImportStub,
    validateRequest: validateProfileImportRequest,
    validateResponse: null,
  };
  ProfileImportStub.prototype.validator = validateProfileImportRequest;
  ProfileImportProxy.prototype.validator = null;
  exports.ImportItem = ImportItem;
  exports.ImportedBookmarkEntry = ImportedBookmarkEntry;
  exports.ImporterAutofillFormDataEntry = ImporterAutofillFormDataEntry;
  exports.SearchEngineInfo = SearchEngineInfo;
  exports.ImporterURLRow = ImporterURLRow;
  exports.SourceProfile = SourceProfile;
  exports.FaviconUsageDataList = FaviconUsageDataList;
  exports.ImporterIE7PasswordInfo = ImporterIE7PasswordInfo;
  exports.ImportedPasswordForm = ImportedPasswordForm;
  exports.ProfileImportObserver = ProfileImportObserver;
  exports.ProfileImportObserverPtr = ProfileImportObserverPtr;
  exports.ProfileImportObserverAssociatedPtr = ProfileImportObserverAssociatedPtr;
  exports.ProfileImport = ProfileImport;
  exports.ProfileImportPtr = ProfileImportPtr;
  exports.ProfileImportAssociatedPtr = ProfileImportAssociatedPtr;
})();