// services/network/public/mojom/network_annotation_monitor.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 = 'services/network/public/mojom/network_annotation_monitor.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');



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


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

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

  NetworkAnnotationMonitor_Report_Params.encodedSize = codec.kStructHeaderSize + 8;

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

  NetworkAnnotationMonitor_Report_Params.encode = function(encoder, val) {
    var packed;
    encoder.writeUint32(NetworkAnnotationMonitor_Report_Params.encodedSize);
    encoder.writeUint32(0);
    encoder.encodeStruct(codec.Int32, val.hashCode);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
    encoder.skip(1);
  };
  var kNetworkAnnotationMonitor_Report_Name = 0;

  function NetworkAnnotationMonitorPtr(handleOrPtrInfo) {
    this.ptr = new bindings.InterfacePtrController(NetworkAnnotationMonitor,
                                                   handleOrPtrInfo);
  }

  function NetworkAnnotationMonitorAssociatedPtr(associatedInterfacePtrInfo) {
    this.ptr = new associatedBindings.AssociatedInterfacePtrController(
        NetworkAnnotationMonitor, associatedInterfacePtrInfo);
  }

  NetworkAnnotationMonitorAssociatedPtr.prototype =
      Object.create(NetworkAnnotationMonitorPtr.prototype);
  NetworkAnnotationMonitorAssociatedPtr.prototype.constructor =
      NetworkAnnotationMonitorAssociatedPtr;

  function NetworkAnnotationMonitorProxy(receiver) {
    this.receiver_ = receiver;
  }
  NetworkAnnotationMonitorPtr.prototype.report = function() {
    return NetworkAnnotationMonitorProxy.prototype.report
        .apply(this.ptr.getProxy(), arguments);
  };

  NetworkAnnotationMonitorProxy.prototype.report = function(hashCode) {
    var params_ = new NetworkAnnotationMonitor_Report_Params();
    params_.hashCode = hashCode;
    var builder = new codec.MessageV0Builder(
        kNetworkAnnotationMonitor_Report_Name,
        codec.align(NetworkAnnotationMonitor_Report_Params.encodedSize));
    builder.encodeStruct(NetworkAnnotationMonitor_Report_Params, params_);
    var message = builder.finish();
    this.receiver_.accept(message);
  };

  function NetworkAnnotationMonitorStub(delegate) {
    this.delegate_ = delegate;
  }
  NetworkAnnotationMonitorStub.prototype.report = function(hashCode) {
    return this.delegate_ && this.delegate_.report && this.delegate_.report(hashCode);
  }

  NetworkAnnotationMonitorStub.prototype.accept = function(message) {
    var reader = new codec.MessageReader(message);
    switch (reader.messageName) {
    case kNetworkAnnotationMonitor_Report_Name:
      var params = reader.decodeStruct(NetworkAnnotationMonitor_Report_Params);
      this.report(params.hashCode);
      return true;
    default:
      return false;
    }
  };

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

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

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

  var NetworkAnnotationMonitor = {
    name: 'network.mojom.NetworkAnnotationMonitor',
    kVersion: 0,
    ptrClass: NetworkAnnotationMonitorPtr,
    proxyClass: NetworkAnnotationMonitorProxy,
    stubClass: NetworkAnnotationMonitorStub,
    validateRequest: validateNetworkAnnotationMonitorRequest,
    validateResponse: null,
  };
  NetworkAnnotationMonitorStub.prototype.validator = validateNetworkAnnotationMonitorRequest;
  NetworkAnnotationMonitorProxy.prototype.validator = null;
  exports.NetworkAnnotationMonitor = NetworkAnnotationMonitor;
  exports.NetworkAnnotationMonitorPtr = NetworkAnnotationMonitorPtr;
  exports.NetworkAnnotationMonitorAssociatedPtr = NetworkAnnotationMonitorAssociatedPtr;
})();