// services/network/public/mojom/host_resolver.mojom.js is auto generated by mojom_bindings_generator.py, do not edit

// 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.

'use strict';

(function() {
  var mojomId = 'services/network/public/mojom/host_resolver.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('network.mojom');
  var time$ =
      mojo.internal.exposeNamespace('mojoBase.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'mojo/public/mojom/base/time.mojom', '../../../../mojo/public/mojom/base/time.mojom.js');
  }
  var address_list$ =
      mojo.internal.exposeNamespace('network.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'services/network/public/mojom/address_list.mojom', 'address_list.mojom.js');
  }
  var ip_address$ =
      mojo.internal.exposeNamespace('network.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'services/network/public/mojom/ip_address.mojom', 'ip_address.mojom.js');
  }
  var ip_endpoint$ =
      mojo.internal.exposeNamespace('network.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'services/network/public/mojom/ip_endpoint.mojom', 'ip_endpoint.mojom.js');
  }
  var network_isolation_key$ =
      mojo.internal.exposeNamespace('network.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'services/network/public/mojom/network_isolation_key.mojom', 'network_isolation_key.mojom.js');
  }
  var network_param$ =
      mojo.internal.exposeNamespace('network.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'services/network/public/mojom/network_param.mojom', 'network_param.mojom.js');
  }
  var request_priority$ =
      mojo.internal.exposeNamespace('network.mojom');
  if (mojo.config.autoLoadMojomDeps) {
    mojo.internal.loadMojomIfNecessary(
        'services/network/public/mojom/request_priority.mojom', 'request_priority.mojom.js');
  }


  var OptionalSecureDnsMode = {};
  OptionalSecureDnsMode.NO_OVERRIDE = 0;
  OptionalSecureDnsMode.OFF = 1;
  OptionalSecureDnsMode.AUTOMATIC = 2;
  OptionalSecureDnsMode.SECURE = 3;
  OptionalSecureDnsMode.MIN_VALUE = 0;
  OptionalSecureDnsMode.MAX_VALUE = 3;

  OptionalSecureDnsMode.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
      return true;
    }
    return false;
  };

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

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

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  var SecureDnsMode = {};
  SecureDnsMode.OFF = 0;
  SecureDnsMode.AUTOMATIC = 1;
  SecureDnsMode.SECURE = 2;
  SecureDnsMode.MIN_VALUE = 0;
  SecureDnsMode.MAX_VALUE = 2;

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

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

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

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  var SecureDnsPolicy = {};
  SecureDnsPolicy.ALLOW = 0;
  SecureDnsPolicy.DISABLE = 1;
  SecureDnsPolicy.MIN_VALUE = 0;
  SecureDnsPolicy.MAX_VALUE = 1;

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

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

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

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  var DnsQueryType = {};
  DnsQueryType.UNSPECIFIED = 0;
  DnsQueryType.A = 1;
  DnsQueryType.AAAA = 2;
  DnsQueryType.TXT = 3;
  DnsQueryType.PTR = 4;
  DnsQueryType.SRV = 5;
  DnsQueryType.HTTPS = 6;
  DnsQueryType.MIN_VALUE = 0;
  DnsQueryType.MAX_VALUE = 6;

  DnsQueryType.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
      return true;
    }
    return false;
  };

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

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

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };

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


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

  DnsOverHttpsServerConfig.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 DnsOverHttpsServerConfig.serverTemplate
    err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false)
    if (err !== validator.validationError.NONE)
        return err;


    // validate DnsOverHttpsServerConfig.endpoints
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 8, new codec.ArrayOf(new codec.PointerTo(ip_address$.IPAddress)), false, [0, 0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  DnsOverHttpsServerConfig.encodedSize = codec.kStructHeaderSize + 16;

  DnsOverHttpsServerConfig.decode = function(decoder) {
    var packed;
    var val = new DnsOverHttpsServerConfig();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.serverTemplate =
        decoder.decodeStruct(codec.String);
    val.endpoints =
        decoder.decodeArrayPointer(new codec.ArrayOf(new codec.PointerTo(ip_address$.IPAddress)));
    return val;
  };

  DnsOverHttpsServerConfig.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(DnsOverHttpsServerConfig.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.String, val.serverTemplate);
    encoder.encodeArrayPointer(new codec.ArrayOf(new codec.PointerTo(ip_address$.IPAddress)), val.endpoints);
  };
  function DnsOverHttpsConfig(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


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

  DnsOverHttpsConfig.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 DnsOverHttpsConfig.servers
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(DnsOverHttpsServerConfig), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  DnsOverHttpsConfig.encodedSize = codec.kStructHeaderSize + 8;

  DnsOverHttpsConfig.decode = function(decoder) {
    var packed;
    var val = new DnsOverHttpsConfig();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.servers =
        decoder.decodeArrayPointer(new codec.PointerTo(DnsOverHttpsServerConfig));
    return val;
  };

  DnsOverHttpsConfig.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(DnsOverHttpsConfig.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeArrayPointer(new codec.PointerTo(DnsOverHttpsServerConfig), val.servers);
  };
  function DnsConfigOverrides(values) {
    this.initDefaults_();
    this.initFields_(values);
  }

  DnsConfigOverrides.Tristate = {};
  DnsConfigOverrides.Tristate.NO_OVERRIDE = 0;
  DnsConfigOverrides.Tristate.TRISTATE_TRUE = 1;
  DnsConfigOverrides.Tristate.TRISTATE_FALSE = 2;
  DnsConfigOverrides.Tristate.MIN_VALUE = 0;
  DnsConfigOverrides.Tristate.MAX_VALUE = 2;

  DnsConfigOverrides.Tristate.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    }
    return false;
  };

  DnsConfigOverrides.Tristate.toKnownEnumValue = function(value) {
    return value;
  };

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

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };

  DnsConfigOverrides.prototype.initDefaults_ = function() {
    this.nameservers = null;
    this.search = null;
    this.appendToMultiLabelName = DnsConfigOverrides.Tristate.NO_OVERRIDE;
    this.ndots = -1;
    this.clearHosts = false;
    this.fallbackPeriod = null;
    this.attempts = -1;
    this.rotate = DnsConfigOverrides.Tristate.NO_OVERRIDE;
    this.useLocalIpv6 = DnsConfigOverrides.Tristate.NO_OVERRIDE;
    this.secureDnsMode = OptionalSecureDnsMode.NO_OVERRIDE;
    this.dnsOverHttpsConfig = null;
    this.allowDnsOverHttpsUpgrade = DnsConfigOverrides.Tristate.NO_OVERRIDE;
  };
  DnsConfigOverrides.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  DnsConfigOverrides.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 DnsConfigOverrides.nameservers
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(ip_endpoint$.IPEndPoint), true, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;


    // validate DnsConfigOverrides.search
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 8, codec.String, true, [0, 0], 0);
    if (err !== validator.validationError.NONE)
        return err;


    // validate DnsConfigOverrides.appendToMultiLabelName
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 16, DnsConfigOverrides.Tristate);
    if (err !== validator.validationError.NONE)
        return err;



    // validate DnsConfigOverrides.fallbackPeriod
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 24, time$.TimeDelta, true);
    if (err !== validator.validationError.NONE)
        return err;



    // validate DnsConfigOverrides.rotate
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 36, DnsConfigOverrides.Tristate);
    if (err !== validator.validationError.NONE)
        return err;


    // validate DnsConfigOverrides.useLocalIpv6
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 40, DnsConfigOverrides.Tristate);
    if (err !== validator.validationError.NONE)
        return err;


    // validate DnsConfigOverrides.dnsOverHttpsConfig
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 48, DnsOverHttpsConfig, true);
    if (err !== validator.validationError.NONE)
        return err;


    // validate DnsConfigOverrides.secureDnsMode
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 44, OptionalSecureDnsMode);
    if (err !== validator.validationError.NONE)
        return err;


    // validate DnsConfigOverrides.allowDnsOverHttpsUpgrade
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 56, DnsConfigOverrides.Tristate);
    if (err !== validator.validationError.NONE)
        return err;


    return validator.validationError.NONE;
  };

  DnsConfigOverrides.encodedSize = codec.kStructHeaderSize + 64;

  DnsConfigOverrides.decode = function(decoder) {
    var packed;
    var val = new DnsConfigOverrides();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.nameservers =
        decoder.decodeArrayPointer(new codec.PointerTo(ip_endpoint$.IPEndPoint));
    val.search =
        decoder.decodeArrayPointer(codec.String);
    val.appendToMultiLabelName =
        decoder.decodeStruct(new codec.Enum(DnsConfigOverrides.Tristate));
    val.ndots =
        decoder.decodeStruct(codec.Int8);
    packed = decoder.readUint8();
    val.clearHosts = (packed >> 0) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    val.fallbackPeriod =
        decoder.decodeStructPointer(time$.TimeDelta);
    val.attempts =
        decoder.decodeStruct(codec.Int32);
    val.rotate =
        decoder.decodeStruct(new codec.Enum(DnsConfigOverrides.Tristate));
    val.useLocalIpv6 =
        decoder.decodeStruct(new codec.Enum(DnsConfigOverrides.Tristate));
    val.secureDnsMode =
        decoder.decodeStruct(new codec.Enum(OptionalSecureDnsMode));
    val.dnsOverHttpsConfig =
        decoder.decodeStructPointer(DnsOverHttpsConfig);
    val.allowDnsOverHttpsUpgrade =
        decoder.decodeStruct(new codec.Enum(DnsConfigOverrides.Tristate));
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  DnsConfigOverrides.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(DnsConfigOverrides.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeArrayPointer(new codec.PointerTo(ip_endpoint$.IPEndPoint), val.nameservers);
    encoder.encodeArrayPointer(codec.String, val.search);
    encoder.encodeStruct(codec.Int32, val.appendToMultiLabelName);
    encoder.encodeStruct(codec.Int8, val.ndots);
    packed = 0;
    packed |= (val.clearHosts & 1) << 0
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStructPointer(time$.TimeDelta, val.fallbackPeriod);
    encoder.encodeStruct(codec.Int32, val.attempts);
    encoder.encodeStruct(codec.Int32, val.rotate);
    encoder.encodeStruct(codec.Int32, val.useLocalIpv6);
    encoder.encodeStruct(codec.Int32, val.secureDnsMode);
    encoder.encodeStructPointer(DnsOverHttpsConfig, val.dnsOverHttpsConfig);
    encoder.encodeStruct(codec.Int32, val.allowDnsOverHttpsUpgrade);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function ResolveHostParameters(values) {
    this.initDefaults_();
    this.initFields_(values);
  }

  ResolveHostParameters.Source = {};
  ResolveHostParameters.Source.ANY = 0;
  ResolveHostParameters.Source.SYSTEM = 1;
  ResolveHostParameters.Source.DNS = 2;
  ResolveHostParameters.Source.MULTICAST_DNS = 3;
  ResolveHostParameters.Source.LOCAL_ONLY = 4;
  ResolveHostParameters.Source.MIN_VALUE = 0;
  ResolveHostParameters.Source.MAX_VALUE = 4;

  ResolveHostParameters.Source.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
      return true;
    }
    return false;
  };

  ResolveHostParameters.Source.toKnownEnumValue = function(value) {
    return value;
  };

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

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  ResolveHostParameters.CacheUsage = {};
  ResolveHostParameters.CacheUsage.ALLOWED = 0;
  ResolveHostParameters.CacheUsage.STALE_ALLOWED = 1;
  ResolveHostParameters.CacheUsage.DISALLOWED = 2;
  ResolveHostParameters.CacheUsage.MIN_VALUE = 0;
  ResolveHostParameters.CacheUsage.MAX_VALUE = 2;

  ResolveHostParameters.CacheUsage.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    }
    return false;
  };

  ResolveHostParameters.CacheUsage.toKnownEnumValue = function(value) {
    return value;
  };

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

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  ResolveHostParameters.Purpose = {};
  ResolveHostParameters.Purpose.kUnspecified = 0;
  ResolveHostParameters.Purpose.kPreconnect = 1;
  ResolveHostParameters.Purpose.MIN_VALUE = 0;
  ResolveHostParameters.Purpose.MAX_VALUE = 1;

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

  ResolveHostParameters.Purpose.toKnownEnumValue = function(value) {
    return value;
  };

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

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };

  ResolveHostParameters.prototype.initDefaults_ = function() {
    this.dnsQueryType = DnsQueryType.UNSPECIFIED;
    this.initialPriority = request_priority$.RequestPriority.kLowest;
    this.source = ResolveHostParameters.Source.ANY;
    this.cacheUsage = ResolveHostParameters.CacheUsage.ALLOWED;
    this.controlHandle = new bindings.InterfaceRequest();
    this.includeCanonicalName = false;
    this.loopbackOnly = false;
    this.isSpeculative = false;
    this.secureDnsPolicy = SecureDnsPolicy.ALLOW;
    this.purpose = ResolveHostParameters.Purpose.kUnspecified;
  };
  ResolveHostParameters.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ResolveHostParameters.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 ResolveHostParameters.dnsQueryType
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, DnsQueryType);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ResolveHostParameters.initialPriority
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 4, request_priority$.RequestPriority);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ResolveHostParameters.source
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 8, ResolveHostParameters.Source);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ResolveHostParameters.cacheUsage
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 12, ResolveHostParameters.CacheUsage);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ResolveHostParameters.controlHandle
    err = messageValidator.validateInterfaceRequest(offset + codec.kStructHeaderSize + 16, true)
    if (err !== validator.validationError.NONE)
        return err;





    // validate ResolveHostParameters.secureDnsPolicy
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 24, SecureDnsPolicy);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ResolveHostParameters.purpose
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 28, ResolveHostParameters.Purpose);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ResolveHostParameters.encodedSize = codec.kStructHeaderSize + 32;

  ResolveHostParameters.decode = function(decoder) {
    var packed;
    var val = new ResolveHostParameters();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.dnsQueryType =
        decoder.decodeStruct(new codec.Enum(DnsQueryType));
    val.initialPriority =
        decoder.decodeStruct(new codec.Enum(request_priority$.RequestPriority));
    val.source =
        decoder.decodeStruct(new codec.Enum(ResolveHostParameters.Source));
    val.cacheUsage =
        decoder.decodeStruct(new codec.Enum(ResolveHostParameters.CacheUsage));
    val.controlHandle =
        decoder.decodeStruct(codec.NullableInterfaceRequest);
    packed = decoder.readUint8();
    val.includeCanonicalName = (packed >> 0) & 1 ? true : false;
    val.loopbackOnly = (packed >> 1) & 1 ? true : false;
    val.isSpeculative = (packed >> 2) & 1 ? true : false;
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.secureDnsPolicy =
        decoder.decodeStruct(new codec.Enum(SecureDnsPolicy));
    val.purpose =
        decoder.decodeStruct(new codec.Enum(ResolveHostParameters.Purpose));
    return val;
  };

  ResolveHostParameters.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ResolveHostParameters.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.dnsQueryType);
    encoder.encodeStruct(codec.Int32, val.initialPriority);
    encoder.encodeStruct(codec.Int32, val.source);
    encoder.encodeStruct(codec.Int32, val.cacheUsage);
    encoder.encodeStruct(codec.NullableInterfaceRequest, val.controlHandle);
    packed = 0;
    packed |= (val.includeCanonicalName & 1) << 0
    packed |= (val.loopbackOnly & 1) << 1
    packed |= (val.isSpeculative & 1) << 2
    encoder.writeUint8(packed);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStruct(codec.Int32, val.secureDnsPolicy);
    encoder.encodeStruct(codec.Int32, val.purpose);
  };
  function ResolveHostHandle_Cancel_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


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

  ResolveHostHandle_Cancel_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;
  };

  ResolveHostHandle_Cancel_Params.encodedSize = codec.kStructHeaderSize + 8;

  ResolveHostHandle_Cancel_Params.decode = function(decoder) {
    var packed;
    var val = new ResolveHostHandle_Cancel_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.result =
        decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

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


  ResolveHostClient_OnComplete_Params.prototype.initDefaults_ = function() {
    this.result = 0;
    this.resolveErrorInfo = null;
    this.resolvedAddresses = null;
  };
  ResolveHostClient_OnComplete_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  ResolveHostClient_OnComplete_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: 32}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;



    // validate ResolveHostClient_OnComplete_Params.resolveErrorInfo
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, network_param$.ResolveErrorInfo, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate ResolveHostClient_OnComplete_Params.resolvedAddresses
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 16, address_list$.AddressList, true);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ResolveHostClient_OnComplete_Params.encodedSize = codec.kStructHeaderSize + 24;

  ResolveHostClient_OnComplete_Params.decode = function(decoder) {
    var packed;
    var val = new ResolveHostClient_OnComplete_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.result =
        decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    val.resolveErrorInfo =
        decoder.decodeStructPointer(network_param$.ResolveErrorInfo);
    val.resolvedAddresses =
        decoder.decodeStructPointer(address_list$.AddressList);
    return val;
  };

  ResolveHostClient_OnComplete_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ResolveHostClient_OnComplete_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.result);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.encodeStructPointer(network_param$.ResolveErrorInfo, val.resolveErrorInfo);
    encoder.encodeStructPointer(address_list$.AddressList, val.resolvedAddresses);
  };
  function ResolveHostClient_OnTextResults_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


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

  ResolveHostClient_OnTextResults_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 ResolveHostClient_OnTextResults_Params.textResults
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, codec.String, false, [0, 0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ResolveHostClient_OnTextResults_Params.encodedSize = codec.kStructHeaderSize + 8;

  ResolveHostClient_OnTextResults_Params.decode = function(decoder) {
    var packed;
    var val = new ResolveHostClient_OnTextResults_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.textResults =
        decoder.decodeArrayPointer(codec.String);
    return val;
  };

  ResolveHostClient_OnTextResults_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ResolveHostClient_OnTextResults_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeArrayPointer(codec.String, val.textResults);
  };
  function ResolveHostClient_OnHostnameResults_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


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

  ResolveHostClient_OnHostnameResults_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 ResolveHostClient_OnHostnameResults_Params.hosts
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 0, 8, new codec.PointerTo(network_param$.HostPortPair), false, [0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  ResolveHostClient_OnHostnameResults_Params.encodedSize = codec.kStructHeaderSize + 8;

  ResolveHostClient_OnHostnameResults_Params.decode = function(decoder) {
    var packed;
    var val = new ResolveHostClient_OnHostnameResults_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.hosts =
        decoder.decodeArrayPointer(new codec.PointerTo(network_param$.HostPortPair));
    return val;
  };

  ResolveHostClient_OnHostnameResults_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(ResolveHostClient_OnHostnameResults_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeArrayPointer(new codec.PointerTo(network_param$.HostPortPair), val.hosts);
  };
  function MdnsListenClient_OnAddressResult_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MdnsListenClient_OnAddressResult_Params.prototype.initDefaults_ = function() {
    this.updateType = 0;
    this.queryType = 0;
    this.endpoint = null;
  };
  MdnsListenClient_OnAddressResult_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MdnsListenClient_OnAddressResult_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 MdnsListenClient_OnAddressResult_Params.updateType
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, MdnsListenClient.UpdateType);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MdnsListenClient_OnAddressResult_Params.queryType
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 4, DnsQueryType);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MdnsListenClient_OnAddressResult_Params.endpoint
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, ip_endpoint$.IPEndPoint, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MdnsListenClient_OnAddressResult_Params.encodedSize = codec.kStructHeaderSize + 16;

  MdnsListenClient_OnAddressResult_Params.decode = function(decoder) {
    var packed;
    var val = new MdnsListenClient_OnAddressResult_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.updateType =
        decoder.decodeStruct(new codec.Enum(MdnsListenClient.UpdateType));
    val.queryType =
        decoder.decodeStruct(new codec.Enum(DnsQueryType));
    val.endpoint =
        decoder.decodeStructPointer(ip_endpoint$.IPEndPoint);
    return val;
  };

  MdnsListenClient_OnAddressResult_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MdnsListenClient_OnAddressResult_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.updateType);
    encoder.encodeStruct(codec.Int32, val.queryType);
    encoder.encodeStructPointer(ip_endpoint$.IPEndPoint, val.endpoint);
  };
  function MdnsListenClient_OnTextResult_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MdnsListenClient_OnTextResult_Params.prototype.initDefaults_ = function() {
    this.updateType = 0;
    this.queryType = 0;
    this.textRecords = null;
  };
  MdnsListenClient_OnTextResult_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MdnsListenClient_OnTextResult_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 MdnsListenClient_OnTextResult_Params.updateType
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, MdnsListenClient.UpdateType);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MdnsListenClient_OnTextResult_Params.queryType
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 4, DnsQueryType);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MdnsListenClient_OnTextResult_Params.textRecords
    err = messageValidator.validateArrayPointer(offset + codec.kStructHeaderSize + 8, 8, codec.String, false, [0, 0], 0);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MdnsListenClient_OnTextResult_Params.encodedSize = codec.kStructHeaderSize + 16;

  MdnsListenClient_OnTextResult_Params.decode = function(decoder) {
    var packed;
    var val = new MdnsListenClient_OnTextResult_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.updateType =
        decoder.decodeStruct(new codec.Enum(MdnsListenClient.UpdateType));
    val.queryType =
        decoder.decodeStruct(new codec.Enum(DnsQueryType));
    val.textRecords =
        decoder.decodeArrayPointer(codec.String);
    return val;
  };

  MdnsListenClient_OnTextResult_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MdnsListenClient_OnTextResult_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.updateType);
    encoder.encodeStruct(codec.Int32, val.queryType);
    encoder.encodeArrayPointer(codec.String, val.textRecords);
  };
  function MdnsListenClient_OnHostnameResult_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  MdnsListenClient_OnHostnameResult_Params.prototype.initDefaults_ = function() {
    this.updateType = 0;
    this.queryType = 0;
    this.host = null;
  };
  MdnsListenClient_OnHostnameResult_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  MdnsListenClient_OnHostnameResult_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 MdnsListenClient_OnHostnameResult_Params.updateType
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, MdnsListenClient.UpdateType);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MdnsListenClient_OnHostnameResult_Params.queryType
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 4, DnsQueryType);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MdnsListenClient_OnHostnameResult_Params.host
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, network_param$.HostPortPair, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MdnsListenClient_OnHostnameResult_Params.encodedSize = codec.kStructHeaderSize + 16;

  MdnsListenClient_OnHostnameResult_Params.decode = function(decoder) {
    var packed;
    var val = new MdnsListenClient_OnHostnameResult_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.updateType =
        decoder.decodeStruct(new codec.Enum(MdnsListenClient.UpdateType));
    val.queryType =
        decoder.decodeStruct(new codec.Enum(DnsQueryType));
    val.host =
        decoder.decodeStructPointer(network_param$.HostPortPair);
    return val;
  };

  MdnsListenClient_OnHostnameResult_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MdnsListenClient_OnHostnameResult_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.updateType);
    encoder.encodeStruct(codec.Int32, val.queryType);
    encoder.encodeStructPointer(network_param$.HostPortPair, val.host);
  };
  function MdnsListenClient_OnUnhandledResult_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


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

  MdnsListenClient_OnUnhandledResult_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 MdnsListenClient_OnUnhandledResult_Params.updateType
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 0, MdnsListenClient.UpdateType);
    if (err !== validator.validationError.NONE)
        return err;


    // validate MdnsListenClient_OnUnhandledResult_Params.queryType
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 4, DnsQueryType);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  MdnsListenClient_OnUnhandledResult_Params.encodedSize = codec.kStructHeaderSize + 8;

  MdnsListenClient_OnUnhandledResult_Params.decode = function(decoder) {
    var packed;
    var val = new MdnsListenClient_OnUnhandledResult_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.updateType =
        decoder.decodeStruct(new codec.Enum(MdnsListenClient.UpdateType));
    val.queryType =
        decoder.decodeStruct(new codec.Enum(DnsQueryType));
    return val;
  };

  MdnsListenClient_OnUnhandledResult_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(MdnsListenClient_OnUnhandledResult_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.updateType);
    encoder.encodeStruct(codec.Int32, val.queryType);
  };
  function HostResolver_ResolveHost_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  HostResolver_ResolveHost_Params.prototype.initDefaults_ = function() {
    this.host = null;
    this.networkIsolationKey = null;
    this.optionalParameters = null;
    this.responseClient = new ResolveHostClientPtr();
  };
  HostResolver_ResolveHost_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  HostResolver_ResolveHost_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 HostResolver_ResolveHost_Params.host
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, network_param$.HostPortPair, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate HostResolver_ResolveHost_Params.networkIsolationKey
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 8, network_isolation_key$.NetworkIsolationKey, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate HostResolver_ResolveHost_Params.optionalParameters
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 16, ResolveHostParameters, true);
    if (err !== validator.validationError.NONE)
        return err;


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

    return validator.validationError.NONE;
  };

  HostResolver_ResolveHost_Params.encodedSize = codec.kStructHeaderSize + 32;

  HostResolver_ResolveHost_Params.decode = function(decoder) {
    var packed;
    var val = new HostResolver_ResolveHost_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.host =
        decoder.decodeStructPointer(network_param$.HostPortPair);
    val.networkIsolationKey =
        decoder.decodeStructPointer(network_isolation_key$.NetworkIsolationKey);
    val.optionalParameters =
        decoder.decodeStructPointer(ResolveHostParameters);
    val.responseClient =
        decoder.decodeStruct(new codec.Interface(ResolveHostClientPtr));
    return val;
  };

  HostResolver_ResolveHost_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(HostResolver_ResolveHost_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(network_param$.HostPortPair, val.host);
    encoder.encodeStructPointer(network_isolation_key$.NetworkIsolationKey, val.networkIsolationKey);
    encoder.encodeStructPointer(ResolveHostParameters, val.optionalParameters);
    encoder.encodeStruct(new codec.Interface(ResolveHostClientPtr), val.responseClient);
  };
  function HostResolver_MdnsListen_Params(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


  HostResolver_MdnsListen_Params.prototype.initDefaults_ = function() {
    this.host = null;
    this.queryType = 0;
    this.responseClient = new MdnsListenClientPtr();
  };
  HostResolver_MdnsListen_Params.prototype.initFields_ = function(fields) {
    for(var field in fields) {
        if (this.hasOwnProperty(field))
          this[field] = fields[field];
    }
  };

  HostResolver_MdnsListen_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: 32}
    ];
    err = messageValidator.validateStructVersion(offset, kVersionSizes);
    if (err !== validator.validationError.NONE)
        return err;


    // validate HostResolver_MdnsListen_Params.host
    err = messageValidator.validateStructPointer(offset + codec.kStructHeaderSize + 0, network_param$.HostPortPair, false);
    if (err !== validator.validationError.NONE)
        return err;


    // validate HostResolver_MdnsListen_Params.queryType
    err = messageValidator.validateEnum(offset + codec.kStructHeaderSize + 8, DnsQueryType);
    if (err !== validator.validationError.NONE)
        return err;


    // validate HostResolver_MdnsListen_Params.responseClient
    err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 12, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  HostResolver_MdnsListen_Params.encodedSize = codec.kStructHeaderSize + 24;

  HostResolver_MdnsListen_Params.decode = function(decoder) {
    var packed;
    var val = new HostResolver_MdnsListen_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.host =
        decoder.decodeStructPointer(network_param$.HostPortPair);
    val.queryType =
        decoder.decodeStruct(new codec.Enum(DnsQueryType));
    val.responseClient =
        decoder.decodeStruct(new codec.Interface(MdnsListenClientPtr));
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

  HostResolver_MdnsListen_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(HostResolver_MdnsListen_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStructPointer(network_param$.HostPortPair, val.host);
    encoder.encodeStruct(codec.Int32, val.queryType);
    encoder.encodeStruct(new codec.Interface(MdnsListenClientPtr), val.responseClient);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  function HostResolver_MdnsListen_ResponseParams(values) {
    this.initDefaults_();
    this.initFields_(values);
  }


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

  HostResolver_MdnsListen_ResponseParams.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;
  };

  HostResolver_MdnsListen_ResponseParams.encodedSize = codec.kStructHeaderSize + 8;

  HostResolver_MdnsListen_ResponseParams.decode = function(decoder) {
    var packed;
    var val = new HostResolver_MdnsListen_ResponseParams();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.result =
        decoder.decodeStruct(codec.Int32);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    decoder.skip(1);
    return val;
  };

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


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

  DnsConfigChangeManagerClient_OnDnsConfigChanged_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;
  };

  DnsConfigChangeManagerClient_OnDnsConfigChanged_Params.encodedSize = codec.kStructHeaderSize + 0;

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

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


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

  DnsConfigChangeManager_RequestNotifications_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 DnsConfigChangeManager_RequestNotifications_Params.client
    err = messageValidator.validateInterface(offset + codec.kStructHeaderSize + 0, false);
    if (err !== validator.validationError.NONE)
        return err;

    return validator.validationError.NONE;
  };

  DnsConfigChangeManager_RequestNotifications_Params.encodedSize = codec.kStructHeaderSize + 8;

  DnsConfigChangeManager_RequestNotifications_Params.decode = function(decoder) {
    var packed;
    var val = new DnsConfigChangeManager_RequestNotifications_Params();
    var numberOfBytes = decoder.readUint32();
    var version = decoder.readUint32();
    val.client =
        decoder.decodeStruct(new codec.Interface(DnsConfigChangeManagerClientPtr));
    return val;
  };

  DnsConfigChangeManager_RequestNotifications_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(DnsConfigChangeManager_RequestNotifications_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(new codec.Interface(DnsConfigChangeManagerClientPtr), val.client);
  };
  var kResolveHostHandle_Cancel_Name = 0;

  function ResolveHostHandlePtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(ResolveHostHandle,
                                                   handleOrPtrInfo);
  }

  function ResolveHostHandleAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        ResolveHostHandle, associatedInterfacePtrInfo);
  }

  ResolveHostHandleAssociatedPtr.prototype =
      Object.create(ResolveHostHandlePtr.prototype);
  ResolveHostHandleAssociatedPtr.prototype.constructor =
      ResolveHostHandleAssociatedPtr;

  function ResolveHostHandleProxy(receiver) {
    this.receiver_ = receiver;
  }
  ResolveHostHandlePtr.prototype.cancel = function() {
    return ResolveHostHandleProxy.prototype.cancel
        .apply(this.ptr.getProxy(), arguments);
  };

  ResolveHostHandleProxy.prototype.cancel = function(result) {
    var params_ = new ResolveHostHandle_Cancel_Params();
    params_.result = result;
    var builder = new codec.MessageV0Builder(
        kResolveHostHandle_Cancel_Name,
        codec.align(ResolveHostHandle_Cancel_Params.encodedSize));
    builder.encodeStruct(ResolveHostHandle_Cancel_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };

  function ResolveHostHandleStub(delegate) {
    this.delegate_ = delegate;
  }
  ResolveHostHandleStub.prototype.cancel = function(result) {
    return this.delegate_ && this.delegate_.cancel && this.delegate_.cancel(result);
  }

  ResolveHostHandleStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kResolveHostHandle_Cancel_Name:
      var params = reader.decodeStruct(ResolveHostHandle_Cancel_Params);
      this.cancel(params.result);
      return true;
    default:
      return false;
    }
  };

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

  function validateResolveHostHandleRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kResolveHostHandle_Cancel_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ResolveHostHandle_Cancel_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

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

  var ResolveHostHandle = {
    name: 'network.mojom.ResolveHostHandle',
    kVersion: 0,
    ptrClass: ResolveHostHandlePtr,
    proxyClass: ResolveHostHandleProxy,
    stubClass: ResolveHostHandleStub,
    validateRequest: validateResolveHostHandleRequest,
    validateResponse: null,
  };
  ResolveHostHandleStub.prototype.validator = validateResolveHostHandleRequest;
  ResolveHostHandleProxy.prototype.validator = null;
  var kResolveHostClient_OnComplete_Name = 0;
  var kResolveHostClient_OnTextResults_Name = 1;
  var kResolveHostClient_OnHostnameResults_Name = 2;

  function ResolveHostClientPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(ResolveHostClient,
                                                   handleOrPtrInfo);
  }

  function ResolveHostClientAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        ResolveHostClient, associatedInterfacePtrInfo);
  }

  ResolveHostClientAssociatedPtr.prototype =
      Object.create(ResolveHostClientPtr.prototype);
  ResolveHostClientAssociatedPtr.prototype.constructor =
      ResolveHostClientAssociatedPtr;

  function ResolveHostClientProxy(receiver) {
    this.receiver_ = receiver;
  }
  ResolveHostClientPtr.prototype.onComplete = function() {
    return ResolveHostClientProxy.prototype.onComplete
        .apply(this.ptr.getProxy(), arguments);
  };

  ResolveHostClientProxy.prototype.onComplete = function(result, resolveErrorInfo, resolvedAddresses) {
    var params_ = new ResolveHostClient_OnComplete_Params();
    params_.result = result;
    params_.resolveErrorInfo = resolveErrorInfo;
    params_.resolvedAddresses = resolvedAddresses;
    var builder = new codec.MessageV0Builder(
        kResolveHostClient_OnComplete_Name,
        codec.align(ResolveHostClient_OnComplete_Params.encodedSize));
    builder.encodeStruct(ResolveHostClient_OnComplete_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ResolveHostClientPtr.prototype.onTextResults = function() {
    return ResolveHostClientProxy.prototype.onTextResults
        .apply(this.ptr.getProxy(), arguments);
  };

  ResolveHostClientProxy.prototype.onTextResults = function(textResults) {
    var params_ = new ResolveHostClient_OnTextResults_Params();
    params_.textResults = textResults;
    var builder = new codec.MessageV0Builder(
        kResolveHostClient_OnTextResults_Name,
        codec.align(ResolveHostClient_OnTextResults_Params.encodedSize));
    builder.encodeStruct(ResolveHostClient_OnTextResults_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  ResolveHostClientPtr.prototype.onHostnameResults = function() {
    return ResolveHostClientProxy.prototype.onHostnameResults
        .apply(this.ptr.getProxy(), arguments);
  };

  ResolveHostClientProxy.prototype.onHostnameResults = function(hosts) {
    var params_ = new ResolveHostClient_OnHostnameResults_Params();
    params_.hosts = hosts;
    var builder = new codec.MessageV0Builder(
        kResolveHostClient_OnHostnameResults_Name,
        codec.align(ResolveHostClient_OnHostnameResults_Params.encodedSize));
    builder.encodeStruct(ResolveHostClient_OnHostnameResults_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };

  function ResolveHostClientStub(delegate) {
    this.delegate_ = delegate;
  }
  ResolveHostClientStub.prototype.onComplete = function(result, resolveErrorInfo, resolvedAddresses) {
    return this.delegate_ && this.delegate_.onComplete && this.delegate_.onComplete(result, resolveErrorInfo, resolvedAddresses);
  }
  ResolveHostClientStub.prototype.onTextResults = function(textResults) {
    return this.delegate_ && this.delegate_.onTextResults && this.delegate_.onTextResults(textResults);
  }
  ResolveHostClientStub.prototype.onHostnameResults = function(hosts) {
    return this.delegate_ && this.delegate_.onHostnameResults && this.delegate_.onHostnameResults(hosts);
  }

  ResolveHostClientStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kResolveHostClient_OnComplete_Name:
      var params = reader.decodeStruct(ResolveHostClient_OnComplete_Params);
      this.onComplete(params.result, params.resolveErrorInfo, params.resolvedAddresses);
      return true;
    case kResolveHostClient_OnTextResults_Name:
      var params = reader.decodeStruct(ResolveHostClient_OnTextResults_Params);
      this.onTextResults(params.textResults);
      return true;
    case kResolveHostClient_OnHostnameResults_Name:
      var params = reader.decodeStruct(ResolveHostClient_OnHostnameResults_Params);
      this.onHostnameResults(params.hosts);
      return true;
    default:
      return false;
    }
  };

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

  function validateResolveHostClientRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kResolveHostClient_OnComplete_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ResolveHostClient_OnComplete_Params;
      break;
      case kResolveHostClient_OnTextResults_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ResolveHostClient_OnTextResults_Params;
      break;
      case kResolveHostClient_OnHostnameResults_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = ResolveHostClient_OnHostnameResults_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

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

  var ResolveHostClient = {
    name: 'network.mojom.ResolveHostClient',
    kVersion: 0,
    ptrClass: ResolveHostClientPtr,
    proxyClass: ResolveHostClientProxy,
    stubClass: ResolveHostClientStub,
    validateRequest: validateResolveHostClientRequest,
    validateResponse: null,
  };
  ResolveHostClientStub.prototype.validator = validateResolveHostClientRequest;
  ResolveHostClientProxy.prototype.validator = null;
  var kMdnsListenClient_OnAddressResult_Name = 0;
  var kMdnsListenClient_OnTextResult_Name = 1;
  var kMdnsListenClient_OnHostnameResult_Name = 2;
  var kMdnsListenClient_OnUnhandledResult_Name = 3;

  function MdnsListenClientPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(MdnsListenClient,
                                                   handleOrPtrInfo);
  }

  function MdnsListenClientAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        MdnsListenClient, associatedInterfacePtrInfo);
  }

  MdnsListenClientAssociatedPtr.prototype =
      Object.create(MdnsListenClientPtr.prototype);
  MdnsListenClientAssociatedPtr.prototype.constructor =
      MdnsListenClientAssociatedPtr;

  function MdnsListenClientProxy(receiver) {
    this.receiver_ = receiver;
  }
  MdnsListenClientPtr.prototype.onAddressResult = function() {
    return MdnsListenClientProxy.prototype.onAddressResult
        .apply(this.ptr.getProxy(), arguments);
  };

  MdnsListenClientProxy.prototype.onAddressResult = function(updateType, queryType, endpoint) {
    var params_ = new MdnsListenClient_OnAddressResult_Params();
    params_.updateType = updateType;
    params_.queryType = queryType;
    params_.endpoint = endpoint;
    var builder = new codec.MessageV0Builder(
        kMdnsListenClient_OnAddressResult_Name,
        codec.align(MdnsListenClient_OnAddressResult_Params.encodedSize));
    builder.encodeStruct(MdnsListenClient_OnAddressResult_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MdnsListenClientPtr.prototype.onTextResult = function() {
    return MdnsListenClientProxy.prototype.onTextResult
        .apply(this.ptr.getProxy(), arguments);
  };

  MdnsListenClientProxy.prototype.onTextResult = function(updateType, queryType, textRecords) {
    var params_ = new MdnsListenClient_OnTextResult_Params();
    params_.updateType = updateType;
    params_.queryType = queryType;
    params_.textRecords = textRecords;
    var builder = new codec.MessageV0Builder(
        kMdnsListenClient_OnTextResult_Name,
        codec.align(MdnsListenClient_OnTextResult_Params.encodedSize));
    builder.encodeStruct(MdnsListenClient_OnTextResult_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MdnsListenClientPtr.prototype.onHostnameResult = function() {
    return MdnsListenClientProxy.prototype.onHostnameResult
        .apply(this.ptr.getProxy(), arguments);
  };

  MdnsListenClientProxy.prototype.onHostnameResult = function(updateType, queryType, host) {
    var params_ = new MdnsListenClient_OnHostnameResult_Params();
    params_.updateType = updateType;
    params_.queryType = queryType;
    params_.host = host;
    var builder = new codec.MessageV0Builder(
        kMdnsListenClient_OnHostnameResult_Name,
        codec.align(MdnsListenClient_OnHostnameResult_Params.encodedSize));
    builder.encodeStruct(MdnsListenClient_OnHostnameResult_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  MdnsListenClientPtr.prototype.onUnhandledResult = function() {
    return MdnsListenClientProxy.prototype.onUnhandledResult
        .apply(this.ptr.getProxy(), arguments);
  };

  MdnsListenClientProxy.prototype.onUnhandledResult = function(updateType, queryType) {
    var params_ = new MdnsListenClient_OnUnhandledResult_Params();
    params_.updateType = updateType;
    params_.queryType = queryType;
    var builder = new codec.MessageV0Builder(
        kMdnsListenClient_OnUnhandledResult_Name,
        codec.align(MdnsListenClient_OnUnhandledResult_Params.encodedSize));
    builder.encodeStruct(MdnsListenClient_OnUnhandledResult_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };

  function MdnsListenClientStub(delegate) {
    this.delegate_ = delegate;
  }
  MdnsListenClientStub.prototype.onAddressResult = function(updateType, queryType, endpoint) {
    return this.delegate_ && this.delegate_.onAddressResult && this.delegate_.onAddressResult(updateType, queryType, endpoint);
  }
  MdnsListenClientStub.prototype.onTextResult = function(updateType, queryType, textRecords) {
    return this.delegate_ && this.delegate_.onTextResult && this.delegate_.onTextResult(updateType, queryType, textRecords);
  }
  MdnsListenClientStub.prototype.onHostnameResult = function(updateType, queryType, host) {
    return this.delegate_ && this.delegate_.onHostnameResult && this.delegate_.onHostnameResult(updateType, queryType, host);
  }
  MdnsListenClientStub.prototype.onUnhandledResult = function(updateType, queryType) {
    return this.delegate_ && this.delegate_.onUnhandledResult && this.delegate_.onUnhandledResult(updateType, queryType);
  }

  MdnsListenClientStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kMdnsListenClient_OnAddressResult_Name:
      var params = reader.decodeStruct(MdnsListenClient_OnAddressResult_Params);
      this.onAddressResult(params.updateType, params.queryType, params.endpoint);
      return true;
    case kMdnsListenClient_OnTextResult_Name:
      var params = reader.decodeStruct(MdnsListenClient_OnTextResult_Params);
      this.onTextResult(params.updateType, params.queryType, params.textRecords);
      return true;
    case kMdnsListenClient_OnHostnameResult_Name:
      var params = reader.decodeStruct(MdnsListenClient_OnHostnameResult_Params);
      this.onHostnameResult(params.updateType, params.queryType, params.host);
      return true;
    case kMdnsListenClient_OnUnhandledResult_Name:
      var params = reader.decodeStruct(MdnsListenClient_OnUnhandledResult_Params);
      this.onUnhandledResult(params.updateType, params.queryType);
      return true;
    default:
      return false;
    }
  };

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

  function validateMdnsListenClientRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kMdnsListenClient_OnAddressResult_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MdnsListenClient_OnAddressResult_Params;
      break;
      case kMdnsListenClient_OnTextResult_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MdnsListenClient_OnTextResult_Params;
      break;
      case kMdnsListenClient_OnHostnameResult_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MdnsListenClient_OnHostnameResult_Params;
      break;
      case kMdnsListenClient_OnUnhandledResult_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = MdnsListenClient_OnUnhandledResult_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

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

  var MdnsListenClient = {
    name: 'network.mojom.MdnsListenClient',
    kVersion: 0,
    ptrClass: MdnsListenClientPtr,
    proxyClass: MdnsListenClientProxy,
    stubClass: MdnsListenClientStub,
    validateRequest: validateMdnsListenClientRequest,
    validateResponse: null,
  };
  MdnsListenClient.UpdateType = {};
  MdnsListenClient.UpdateType.ADDED = 0;
  MdnsListenClient.UpdateType.CHANGED = 1;
  MdnsListenClient.UpdateType.REMOVED = 2;
  MdnsListenClient.UpdateType.MIN_VALUE = 0;
  MdnsListenClient.UpdateType.MAX_VALUE = 2;

  MdnsListenClient.UpdateType.isKnownEnumValue = function(value) {
    switch (value) {
    case 0:
    case 1:
    case 2:
      return true;
    }
    return false;
  };

  MdnsListenClient.UpdateType.toKnownEnumValue = function(value) {
    return value;
  };

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

    return validator.validationError.UNKNOWN_ENUM_VALUE;
  };
  MdnsListenClientStub.prototype.validator = validateMdnsListenClientRequest;
  MdnsListenClientProxy.prototype.validator = null;
  var kHostResolver_ResolveHost_Name = 0;
  var kHostResolver_MdnsListen_Name = 1;

  function HostResolverPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(HostResolver,
                                                   handleOrPtrInfo);
  }

  function HostResolverAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        HostResolver, associatedInterfacePtrInfo);
  }

  HostResolverAssociatedPtr.prototype =
      Object.create(HostResolverPtr.prototype);
  HostResolverAssociatedPtr.prototype.constructor =
      HostResolverAssociatedPtr;

  function HostResolverProxy(receiver) {
    this.receiver_ = receiver;
  }
  HostResolverPtr.prototype.resolveHost = function() {
    return HostResolverProxy.prototype.resolveHost
        .apply(this.ptr.getProxy(), arguments);
  };

  HostResolverProxy.prototype.resolveHost = function(host, networkIsolationKey, optionalParameters, responseClient) {
    var params_ = new HostResolver_ResolveHost_Params();
    params_.host = host;
    params_.networkIsolationKey = networkIsolationKey;
    params_.optionalParameters = optionalParameters;
    params_.responseClient = responseClient;
    var builder = new codec.MessageV0Builder(
        kHostResolver_ResolveHost_Name,
        codec.align(HostResolver_ResolveHost_Params.encodedSize));
    builder.encodeStruct(HostResolver_ResolveHost_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };
  HostResolverPtr.prototype.mdnsListen = function() {
    return HostResolverProxy.prototype.mdnsListen
        .apply(this.ptr.getProxy(), arguments);
  };

  HostResolverProxy.prototype.mdnsListen = function(host, queryType, responseClient) {
    var params_ = new HostResolver_MdnsListen_Params();
    params_.host = host;
    params_.queryType = queryType;
    params_.responseClient = responseClient;
    return new Promise(function(resolve, reject) {
      var builder = new codec.MessageV1Builder(
          kHostResolver_MdnsListen_Name,
          codec.align(HostResolver_MdnsListen_Params.encodedSize),
          codec.kMessageExpectsResponse, 0);
      builder.encodeStruct(HostResolver_MdnsListen_Params, params_);
      var message = builder.finish();
      this.receiver_.acceptAndExpectResponse(message).then(function(message) {
        var reader = new codec.MessageReader(message);
        var responseParams =
            reader.decodeStruct(HostResolver_MdnsListen_ResponseParams);
        resolve(responseParams);
      }).catch(function(result) {
        reject(Error("Connection error: " + result));
      });
    }.bind(this));
  };

  function HostResolverStub(delegate) {
    this.delegate_ = delegate;
  }
  HostResolverStub.prototype.resolveHost = function(host, networkIsolationKey, optionalParameters, responseClient) {
    return this.delegate_ && this.delegate_.resolveHost && this.delegate_.resolveHost(host, networkIsolationKey, optionalParameters, responseClient);
  }
  HostResolverStub.prototype.mdnsListen = function(host, queryType, responseClient) {
    return this.delegate_ && this.delegate_.mdnsListen && this.delegate_.mdnsListen(host, queryType, responseClient);
  }

  HostResolverStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kHostResolver_ResolveHost_Name:
      var params = reader.decodeStruct(HostResolver_ResolveHost_Params);
      this.resolveHost(params.host, params.networkIsolationKey, params.optionalParameters, params.responseClient);
      return true;
    default:
      return false;
    }
  };

  HostResolverStub.prototype.acceptWithResponder =
      function(message, responder) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kHostResolver_MdnsListen_Name:
      var params = reader.decodeStruct(HostResolver_MdnsListen_Params);
      this.mdnsListen(params.host, params.queryType, params.responseClient).then(function(response) {
        var responseParams =
            new HostResolver_MdnsListen_ResponseParams();
        responseParams.result = response.result;
        var builder = new codec.MessageV1Builder(
            kHostResolver_MdnsListen_Name,
            codec.align(HostResolver_MdnsListen_ResponseParams.encodedSize),
            codec.kMessageIsResponse, reader.requestID);
        builder.encodeStruct(HostResolver_MdnsListen_ResponseParams,
                             responseParams);
        var message = builder.finish();
        responder.accept(message);
      });
      return true;
    default:
      return false;
    }
  };

  function validateHostResolverRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kHostResolver_ResolveHost_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = HostResolver_ResolveHost_Params;
      break;
      case kHostResolver_MdnsListen_Name:
        if (message.expectsResponse())
          paramsClass = HostResolver_MdnsListen_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  function validateHostResolverResponse(messageValidator) {
   var message = messageValidator.message;
   var paramsClass = null;
   switch (message.getName()) {
      case kHostResolver_MdnsListen_Name:
        if (message.isResponse())
          paramsClass = HostResolver_MdnsListen_ResponseParams;
        break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

  var HostResolver = {
    name: 'network.mojom.HostResolver',
    kVersion: 0,
    ptrClass: HostResolverPtr,
    proxyClass: HostResolverProxy,
    stubClass: HostResolverStub,
    validateRequest: validateHostResolverRequest,
    validateResponse: validateHostResolverResponse,
  };
  HostResolverStub.prototype.validator = validateHostResolverRequest;
  HostResolverProxy.prototype.validator = validateHostResolverResponse;
  var kDnsConfigChangeManagerClient_OnDnsConfigChanged_Name = 0;

  function DnsConfigChangeManagerClientPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(DnsConfigChangeManagerClient,
                                                   handleOrPtrInfo);
  }

  function DnsConfigChangeManagerClientAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        DnsConfigChangeManagerClient, associatedInterfacePtrInfo);
  }

  DnsConfigChangeManagerClientAssociatedPtr.prototype =
      Object.create(DnsConfigChangeManagerClientPtr.prototype);
  DnsConfigChangeManagerClientAssociatedPtr.prototype.constructor =
      DnsConfigChangeManagerClientAssociatedPtr;

  function DnsConfigChangeManagerClientProxy(receiver) {
    this.receiver_ = receiver;
  }
  DnsConfigChangeManagerClientPtr.prototype.onDnsConfigChanged = function() {
    return DnsConfigChangeManagerClientProxy.prototype.onDnsConfigChanged
        .apply(this.ptr.getProxy(), arguments);
  };

  DnsConfigChangeManagerClientProxy.prototype.onDnsConfigChanged = function() {
    var params_ = new DnsConfigChangeManagerClient_OnDnsConfigChanged_Params();
    var builder = new codec.MessageV0Builder(
        kDnsConfigChangeManagerClient_OnDnsConfigChanged_Name,
        codec.align(DnsConfigChangeManagerClient_OnDnsConfigChanged_Params.encodedSize));
    builder.encodeStruct(DnsConfigChangeManagerClient_OnDnsConfigChanged_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };

  function DnsConfigChangeManagerClientStub(delegate) {
    this.delegate_ = delegate;
  }
  DnsConfigChangeManagerClientStub.prototype.onDnsConfigChanged = function() {
    return this.delegate_ && this.delegate_.onDnsConfigChanged && this.delegate_.onDnsConfigChanged();
  }

  DnsConfigChangeManagerClientStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kDnsConfigChangeManagerClient_OnDnsConfigChanged_Name:
      var params = reader.decodeStruct(DnsConfigChangeManagerClient_OnDnsConfigChanged_Params);
      this.onDnsConfigChanged();
      return true;
    default:
      return false;
    }
  };

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

  function validateDnsConfigChangeManagerClientRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kDnsConfigChangeManagerClient_OnDnsConfigChanged_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = DnsConfigChangeManagerClient_OnDnsConfigChanged_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

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

  var DnsConfigChangeManagerClient = {
    name: 'network.mojom.DnsConfigChangeManagerClient',
    kVersion: 0,
    ptrClass: DnsConfigChangeManagerClientPtr,
    proxyClass: DnsConfigChangeManagerClientProxy,
    stubClass: DnsConfigChangeManagerClientStub,
    validateRequest: validateDnsConfigChangeManagerClientRequest,
    validateResponse: null,
  };
  DnsConfigChangeManagerClientStub.prototype.validator = validateDnsConfigChangeManagerClientRequest;
  DnsConfigChangeManagerClientProxy.prototype.validator = null;
  var kDnsConfigChangeManager_RequestNotifications_Name = 0;

  function DnsConfigChangeManagerPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(DnsConfigChangeManager,
                                                   handleOrPtrInfo);
  }

  function DnsConfigChangeManagerAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        DnsConfigChangeManager, associatedInterfacePtrInfo);
  }

  DnsConfigChangeManagerAssociatedPtr.prototype =
      Object.create(DnsConfigChangeManagerPtr.prototype);
  DnsConfigChangeManagerAssociatedPtr.prototype.constructor =
      DnsConfigChangeManagerAssociatedPtr;

  function DnsConfigChangeManagerProxy(receiver) {
    this.receiver_ = receiver;
  }
  DnsConfigChangeManagerPtr.prototype.requestNotifications = function() {
    return DnsConfigChangeManagerProxy.prototype.requestNotifications
        .apply(this.ptr.getProxy(), arguments);
  };

  DnsConfigChangeManagerProxy.prototype.requestNotifications = function(client) {
    var params_ = new DnsConfigChangeManager_RequestNotifications_Params();
    params_.client = client;
    var builder = new codec.MessageV0Builder(
        kDnsConfigChangeManager_RequestNotifications_Name,
        codec.align(DnsConfigChangeManager_RequestNotifications_Params.encodedSize));
    builder.encodeStruct(DnsConfigChangeManager_RequestNotifications_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };

  function DnsConfigChangeManagerStub(delegate) {
    this.delegate_ = delegate;
  }
  DnsConfigChangeManagerStub.prototype.requestNotifications = function(client) {
    return this.delegate_ && this.delegate_.requestNotifications && this.delegate_.requestNotifications(client);
  }

  DnsConfigChangeManagerStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kDnsConfigChangeManager_RequestNotifications_Name:
      var params = reader.decodeStruct(DnsConfigChangeManager_RequestNotifications_Params);
      this.requestNotifications(params.client);
      return true;
    default:
      return false;
    }
  };

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

  function validateDnsConfigChangeManagerRequest(messageValidator) {
    var message = messageValidator.message;
    var paramsClass = null;
    switch (message.getName()) {
      case kDnsConfigChangeManager_RequestNotifications_Name:
        if (!message.expectsResponse() && !message.isResponse())
          paramsClass = DnsConfigChangeManager_RequestNotifications_Params;
      break;
    }
    if (paramsClass === null)
      return validator.validationError.NONE;
    return paramsClass.validate(messageValidator, messageValidator.message.getHeaderNumBytes());
  }

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

  var DnsConfigChangeManager = {
    name: 'network.mojom.DnsConfigChangeManager',
    kVersion: 0,
    ptrClass: DnsConfigChangeManagerPtr,
    proxyClass: DnsConfigChangeManagerProxy,
    stubClass: DnsConfigChangeManagerStub,
    validateRequest: validateDnsConfigChangeManagerRequest,
    validateResponse: null,
  };
  DnsConfigChangeManagerStub.prototype.validator = validateDnsConfigChangeManagerRequest;
  DnsConfigChangeManagerProxy.prototype.validator = null;
  exports.OptionalSecureDnsMode = OptionalSecureDnsMode;
  exports.SecureDnsMode = SecureDnsMode;
  exports.SecureDnsPolicy = SecureDnsPolicy;
  exports.DnsQueryType = DnsQueryType;
  exports.DnsOverHttpsServerConfig = DnsOverHttpsServerConfig;
  exports.DnsOverHttpsConfig = DnsOverHttpsConfig;
  exports.DnsConfigOverrides = DnsConfigOverrides;
  exports.ResolveHostParameters = ResolveHostParameters;
  exports.ResolveHostHandle = ResolveHostHandle;
  exports.ResolveHostHandlePtr = ResolveHostHandlePtr;
  exports.ResolveHostHandleAssociatedPtr = ResolveHostHandleAssociatedPtr;
  exports.ResolveHostClient = ResolveHostClient;
  exports.ResolveHostClientPtr = ResolveHostClientPtr;
  exports.ResolveHostClientAssociatedPtr = ResolveHostClientAssociatedPtr;
  exports.MdnsListenClient = MdnsListenClient;
  exports.MdnsListenClientPtr = MdnsListenClientPtr;
  exports.MdnsListenClientAssociatedPtr = MdnsListenClientAssociatedPtr;
  exports.HostResolver = HostResolver;
  exports.HostResolverPtr = HostResolverPtr;
  exports.HostResolverAssociatedPtr = HostResolverAssociatedPtr;
  exports.DnsConfigChangeManagerClient = DnsConfigChangeManagerClient;
  exports.DnsConfigChangeManagerClientPtr = DnsConfigChangeManagerClientPtr;
  exports.DnsConfigChangeManagerClientAssociatedPtr = DnsConfigChangeManagerClientAssociatedPtr;
  exports.DnsConfigChangeManager = DnsConfigChangeManager;
  exports.DnsConfigChangeManagerPtr = DnsConfigChangeManagerPtr;
  exports.DnsConfigChangeManagerAssociatedPtr = DnsConfigChangeManagerAssociatedPtr;
})();