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

// This file is autogenerated by:
//     mojo/public/tools/bindings/mojom_bindings_generator.py
// For:
//     mojom/vanadium/discovery.mojom
//

package io.v.mojo.discovery;

class Discovery_Internal {

    public static final org.chromium.mojo.bindings.Interface.NamedManager<Discovery, Discovery.Proxy> MANAGER =
            new org.chromium.mojo.bindings.Interface.NamedManager<Discovery, Discovery.Proxy>() {
    
        public String getName() {
            return "v23::discovery::Discovery";
        }
    
        public int getVersion() {
          return 0;
        }
    
        public Proxy buildProxy(org.chromium.mojo.system.Core core,
                                org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
            return new Proxy(core, messageReceiver);
        }
    
        public Stub buildStub(org.chromium.mojo.system.Core core, Discovery impl) {
            return new Stub(core, impl);
        }
    
        public Discovery[] buildArray(int size) {
          return new Discovery[size];
        }
    };

    private static final int START_ADVERTISING_ORDINAL = 0;
    private static final int STOP_ADVERTISING_ORDINAL = 1;
    private static final int START_SCAN_ORDINAL = 2;
    private static final int STOP_SCAN_ORDINAL = 3;

    static final class Proxy extends org.chromium.mojo.bindings.Interface.AbstractProxy implements Discovery.Proxy {

        Proxy(org.chromium.mojo.system.Core core,
              org.chromium.mojo.bindings.MessageReceiverWithResponder messageReceiver) {
            super(core, messageReceiver);
        }

        @Override
        public void startAdvertising(Service service, String[] visibility, StartAdvertisingResponse callback) {
            DiscoveryStartAdvertisingParams _message = new DiscoveryStartAdvertisingParams();
            _message.service = service;
            _message.visibility = visibility;
            getProxyHandler().getMessageReceiver().acceptWithResponder(
                    _message.serializeWithHeader(
                            getProxyHandler().getCore(),
                            new org.chromium.mojo.bindings.MessageHeader(
                                    START_ADVERTISING_ORDINAL,
                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
                                    0)),
                    new DiscoveryStartAdvertisingResponseParamsForwardToCallback(callback));
        }

        @Override
        public void stopAdvertising(String instanceId, StopAdvertisingResponse callback) {
            DiscoveryStopAdvertisingParams _message = new DiscoveryStopAdvertisingParams();
            _message.instanceId = instanceId;
            getProxyHandler().getMessageReceiver().acceptWithResponder(
                    _message.serializeWithHeader(
                            getProxyHandler().getCore(),
                            new org.chromium.mojo.bindings.MessageHeader(
                                    STOP_ADVERTISING_ORDINAL,
                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
                                    0)),
                    new DiscoveryStopAdvertisingResponseParamsForwardToCallback(callback));
        }

        @Override
        public void startScan(String query, ScanHandler handler, StartScanResponse callback) {
            DiscoveryStartScanParams _message = new DiscoveryStartScanParams();
            _message.query = query;
            _message.handler = handler;
            getProxyHandler().getMessageReceiver().acceptWithResponder(
                    _message.serializeWithHeader(
                            getProxyHandler().getCore(),
                            new org.chromium.mojo.bindings.MessageHeader(
                                    START_SCAN_ORDINAL,
                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
                                    0)),
                    new DiscoveryStartScanResponseParamsForwardToCallback(callback));
        }

        @Override
        public void stopScan(int scanId, StopScanResponse callback) {
            DiscoveryStopScanParams _message = new DiscoveryStopScanParams();
            _message.scanId = scanId;
            getProxyHandler().getMessageReceiver().acceptWithResponder(
                    _message.serializeWithHeader(
                            getProxyHandler().getCore(),
                            new org.chromium.mojo.bindings.MessageHeader(
                                    STOP_SCAN_ORDINAL,
                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG,
                                    0)),
                    new DiscoveryStopScanResponseParamsForwardToCallback(callback));
        }

    }

    static final class Stub extends org.chromium.mojo.bindings.Interface.Stub<Discovery> {

        Stub(org.chromium.mojo.system.Core core, Discovery impl) {
            super(core, impl);
        }

        @Override
        public boolean accept(org.chromium.mojo.bindings.Message message) {
            try {
                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
                        message.asServiceMessage();
                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
                if (!header.validateHeader(org.chromium.mojo.bindings.MessageHeader.NO_FLAG)) {
                    return false;
                }
                switch(header.getType()) {
                    case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_OR_CLOSE_PIPE_MESSAGE_ID:
                        return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRunOrClosePipe(
                                Discovery_Internal.MANAGER, messageWithHeader);
                    default:
                        return false;
                }
            } catch (org.chromium.mojo.bindings.DeserializationException e) {
                System.err.println(e.toString());
                return false;
            }
        }

        @Override
        public boolean acceptWithResponder(org.chromium.mojo.bindings.Message message, org.chromium.mojo.bindings.MessageReceiver receiver) {
            try {
                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
                        message.asServiceMessage();
                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
                if (!header.validateHeader(org.chromium.mojo.bindings.MessageHeader.MESSAGE_EXPECTS_RESPONSE_FLAG)) {
                    return false;
                }
                switch(header.getType()) {
                    case org.chromium.mojo.bindings.InterfaceControlMessagesConstants.RUN_MESSAGE_ID:
                        return org.chromium.mojo.bindings.InterfaceControlMessagesHelper.handleRun(
                                getCore(), Discovery_Internal.MANAGER, messageWithHeader, receiver);
                    case START_ADVERTISING_ORDINAL: {
                        DiscoveryStartAdvertisingParams data =
                                DiscoveryStartAdvertisingParams.deserialize(messageWithHeader.getPayload());
                        getImpl().startAdvertising(data.service, data.visibility, new DiscoveryStartAdvertisingResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
                        return true;
                    }
                    case STOP_ADVERTISING_ORDINAL: {
                        DiscoveryStopAdvertisingParams data =
                                DiscoveryStopAdvertisingParams.deserialize(messageWithHeader.getPayload());
                        getImpl().stopAdvertising(data.instanceId, new DiscoveryStopAdvertisingResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
                        return true;
                    }
                    case START_SCAN_ORDINAL: {
                        DiscoveryStartScanParams data =
                                DiscoveryStartScanParams.deserialize(messageWithHeader.getPayload());
                        getImpl().startScan(data.query, data.handler, new DiscoveryStartScanResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
                        return true;
                    }
                    case STOP_SCAN_ORDINAL: {
                        DiscoveryStopScanParams data =
                                DiscoveryStopScanParams.deserialize(messageWithHeader.getPayload());
                        getImpl().stopScan(data.scanId, new DiscoveryStopScanResponseParamsProxyToResponder(getCore(), receiver, header.getRequestId()));
                        return true;
                    }
                    default:
                        return false;
                }
            } catch (org.chromium.mojo.bindings.DeserializationException e) {
                System.err.println(e.toString());
                return false;
            }
        }
    }

    static final class DiscoveryStartAdvertisingParams extends org.chromium.mojo.bindings.Struct {
    
        private static final int STRUCT_SIZE = 24;
        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(24, 0)};
        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
    
        public Service service;
        public String[] visibility;
    
        private DiscoveryStartAdvertisingParams(int version) {
            super(STRUCT_SIZE, version);
        }
    
        public DiscoveryStartAdvertisingParams() {
            this(0);
        }
    
        public static DiscoveryStartAdvertisingParams deserialize(org.chromium.mojo.bindings.Message message) {
            return decode(new org.chromium.mojo.bindings.Decoder(message));
        }
    
        @SuppressWarnings("unchecked")
        public static DiscoveryStartAdvertisingParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
            if (decoder0 == null) {
                return null;
            }
            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
            DiscoveryStartAdvertisingParams result = new DiscoveryStartAdvertisingParams(mainDataHeader.elementsOrVersion);
            if (mainDataHeader.elementsOrVersion >= 0) {
                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(8, false);
                result.service = Service.decode(decoder1);
            }
            if (mainDataHeader.elementsOrVersion >= 0) {
                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(16, true);
                if (decoder1 == null) {
                    result.visibility = null;
                } else {
                    org.chromium.mojo.bindings.DataHeader si1 = decoder1.readDataHeaderForPointerArray(org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
                    result.visibility = new String[si1.elementsOrVersion];
                    for (int i1 = 0; i1 < si1.elementsOrVersion; ++i1) {
                        result.visibility[i1] = decoder1.readString(org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i1, false);
                    }
                }
            }
            return result;
        }
    
        @SuppressWarnings("unchecked")
        @Override
        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
            encoder0.encode(service, 8, false);
            if (visibility == null) {
                encoder0.encodeNullPointer(16, true);
            } else {
                org.chromium.mojo.bindings.Encoder encoder1 = encoder0.encodePointerArray(visibility.length, 16, org.chromium.mojo.bindings.BindingsHelper.UNSPECIFIED_ARRAY_LENGTH);
                for (int i0 = 0; i0 < visibility.length; ++i0) {
                    encoder1.encode(visibility[i0], org.chromium.mojo.bindings.DataHeader.HEADER_SIZE + org.chromium.mojo.bindings.BindingsHelper.POINTER_SIZE * i0, false);
                }
            }
        }
    
        /**
         * @see Object#equals(Object)
         */
        @Override
        public boolean equals(Object object) {
            if (object == this)
                return true;
            if (object == null)
                return false;
            if (getClass() != object.getClass())
                return false;
            DiscoveryStartAdvertisingParams other = (DiscoveryStartAdvertisingParams) object;
            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.service, other.service))
                return false;
            if (!java.util.Arrays.deepEquals(this.visibility, other.visibility))
                return false;
            return true;
        }
    
        /**
         * @see Object#hashCode()
         */
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = prime + getClass().hashCode();
            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(service);
            result = prime * result + java.util.Arrays.deepHashCode(visibility);
            return result;
        }
    }

    static final class DiscoveryStartAdvertisingResponseParams extends org.chromium.mojo.bindings.Struct {
    
        private static final int STRUCT_SIZE = 24;
        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(24, 0)};
        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
    
        public String instanceId;
        public Error err;
    
        private DiscoveryStartAdvertisingResponseParams(int version) {
            super(STRUCT_SIZE, version);
        }
    
        public DiscoveryStartAdvertisingResponseParams() {
            this(0);
        }
    
        public static DiscoveryStartAdvertisingResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
            return decode(new org.chromium.mojo.bindings.Decoder(message));
        }
    
        @SuppressWarnings("unchecked")
        public static DiscoveryStartAdvertisingResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
            if (decoder0 == null) {
                return null;
            }
            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
            DiscoveryStartAdvertisingResponseParams result = new DiscoveryStartAdvertisingResponseParams(mainDataHeader.elementsOrVersion);
            if (mainDataHeader.elementsOrVersion >= 0) {
                result.instanceId = decoder0.readString(8, false);
            }
            if (mainDataHeader.elementsOrVersion >= 0) {
                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(16, true);
                result.err = Error.decode(decoder1);
            }
            return result;
        }
    
        @SuppressWarnings("unchecked")
        @Override
        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
            encoder0.encode(instanceId, 8, false);
            encoder0.encode(err, 16, true);
        }
    
        /**
         * @see Object#equals(Object)
         */
        @Override
        public boolean equals(Object object) {
            if (object == this)
                return true;
            if (object == null)
                return false;
            if (getClass() != object.getClass())
                return false;
            DiscoveryStartAdvertisingResponseParams other = (DiscoveryStartAdvertisingResponseParams) object;
            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.instanceId, other.instanceId))
                return false;
            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.err, other.err))
                return false;
            return true;
        }
    
        /**
         * @see Object#hashCode()
         */
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = prime + getClass().hashCode();
            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(instanceId);
            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(err);
            return result;
        }
    }

    static class DiscoveryStartAdvertisingResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
            implements org.chromium.mojo.bindings.MessageReceiver {
        private final Discovery.StartAdvertisingResponse mCallback;

        DiscoveryStartAdvertisingResponseParamsForwardToCallback(Discovery.StartAdvertisingResponse callback) {
            this.mCallback = callback;
        }

        @Override
        public boolean accept(org.chromium.mojo.bindings.Message message) {
            try {
                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
                        message.asServiceMessage();
                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
                if (!header.validateHeader(START_ADVERTISING_ORDINAL,
                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
                    return false;
                }
                DiscoveryStartAdvertisingResponseParams response = DiscoveryStartAdvertisingResponseParams.deserialize(messageWithHeader.getPayload());
                mCallback.call(response.instanceId, response.err);
                return true;
            } catch (org.chromium.mojo.bindings.DeserializationException e) {
                return false;
            }
        }
    }

    static class DiscoveryStartAdvertisingResponseParamsProxyToResponder implements Discovery.StartAdvertisingResponse {

        private final org.chromium.mojo.system.Core mCore;
        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
        private final long mRequestId;

        DiscoveryStartAdvertisingResponseParamsProxyToResponder(
                org.chromium.mojo.system.Core core,
                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
                long requestId) {
            mCore = core;
            mMessageReceiver = messageReceiver;
            mRequestId = requestId;
        }

        @Override
        public void call(String instanceId, Error err) {
            DiscoveryStartAdvertisingResponseParams _response = new DiscoveryStartAdvertisingResponseParams();
            _response.instanceId = instanceId;
            _response.err = err;
            org.chromium.mojo.bindings.ServiceMessage _message =
                    _response.serializeWithHeader(
                            mCore,
                            new org.chromium.mojo.bindings.MessageHeader(
                                    START_ADVERTISING_ORDINAL,
                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
                                    mRequestId));
            mMessageReceiver.accept(_message);
        }
    }

    static final class DiscoveryStopAdvertisingParams extends org.chromium.mojo.bindings.Struct {
    
        private static final int STRUCT_SIZE = 16;
        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
    
        public String instanceId;
    
        private DiscoveryStopAdvertisingParams(int version) {
            super(STRUCT_SIZE, version);
        }
    
        public DiscoveryStopAdvertisingParams() {
            this(0);
        }
    
        public static DiscoveryStopAdvertisingParams deserialize(org.chromium.mojo.bindings.Message message) {
            return decode(new org.chromium.mojo.bindings.Decoder(message));
        }
    
        @SuppressWarnings("unchecked")
        public static DiscoveryStopAdvertisingParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
            if (decoder0 == null) {
                return null;
            }
            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
            DiscoveryStopAdvertisingParams result = new DiscoveryStopAdvertisingParams(mainDataHeader.elementsOrVersion);
            if (mainDataHeader.elementsOrVersion >= 0) {
                result.instanceId = decoder0.readString(8, false);
            }
            return result;
        }
    
        @SuppressWarnings("unchecked")
        @Override
        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
            encoder0.encode(instanceId, 8, false);
        }
    
        /**
         * @see Object#equals(Object)
         */
        @Override
        public boolean equals(Object object) {
            if (object == this)
                return true;
            if (object == null)
                return false;
            if (getClass() != object.getClass())
                return false;
            DiscoveryStopAdvertisingParams other = (DiscoveryStopAdvertisingParams) object;
            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.instanceId, other.instanceId))
                return false;
            return true;
        }
    
        /**
         * @see Object#hashCode()
         */
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = prime + getClass().hashCode();
            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(instanceId);
            return result;
        }
    }

    static final class DiscoveryStopAdvertisingResponseParams extends org.chromium.mojo.bindings.Struct {
    
        private static final int STRUCT_SIZE = 16;
        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
    
        public Error err;
    
        private DiscoveryStopAdvertisingResponseParams(int version) {
            super(STRUCT_SIZE, version);
        }
    
        public DiscoveryStopAdvertisingResponseParams() {
            this(0);
        }
    
        public static DiscoveryStopAdvertisingResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
            return decode(new org.chromium.mojo.bindings.Decoder(message));
        }
    
        @SuppressWarnings("unchecked")
        public static DiscoveryStopAdvertisingResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
            if (decoder0 == null) {
                return null;
            }
            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
            DiscoveryStopAdvertisingResponseParams result = new DiscoveryStopAdvertisingResponseParams(mainDataHeader.elementsOrVersion);
            if (mainDataHeader.elementsOrVersion >= 0) {
                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(8, true);
                result.err = Error.decode(decoder1);
            }
            return result;
        }
    
        @SuppressWarnings("unchecked")
        @Override
        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
            encoder0.encode(err, 8, true);
        }
    
        /**
         * @see Object#equals(Object)
         */
        @Override
        public boolean equals(Object object) {
            if (object == this)
                return true;
            if (object == null)
                return false;
            if (getClass() != object.getClass())
                return false;
            DiscoveryStopAdvertisingResponseParams other = (DiscoveryStopAdvertisingResponseParams) object;
            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.err, other.err))
                return false;
            return true;
        }
    
        /**
         * @see Object#hashCode()
         */
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = prime + getClass().hashCode();
            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(err);
            return result;
        }
    }

    static class DiscoveryStopAdvertisingResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
            implements org.chromium.mojo.bindings.MessageReceiver {
        private final Discovery.StopAdvertisingResponse mCallback;

        DiscoveryStopAdvertisingResponseParamsForwardToCallback(Discovery.StopAdvertisingResponse callback) {
            this.mCallback = callback;
        }

        @Override
        public boolean accept(org.chromium.mojo.bindings.Message message) {
            try {
                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
                        message.asServiceMessage();
                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
                if (!header.validateHeader(STOP_ADVERTISING_ORDINAL,
                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
                    return false;
                }
                DiscoveryStopAdvertisingResponseParams response = DiscoveryStopAdvertisingResponseParams.deserialize(messageWithHeader.getPayload());
                mCallback.call(response.err);
                return true;
            } catch (org.chromium.mojo.bindings.DeserializationException e) {
                return false;
            }
        }
    }

    static class DiscoveryStopAdvertisingResponseParamsProxyToResponder implements Discovery.StopAdvertisingResponse {

        private final org.chromium.mojo.system.Core mCore;
        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
        private final long mRequestId;

        DiscoveryStopAdvertisingResponseParamsProxyToResponder(
                org.chromium.mojo.system.Core core,
                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
                long requestId) {
            mCore = core;
            mMessageReceiver = messageReceiver;
            mRequestId = requestId;
        }

        @Override
        public void call(Error err) {
            DiscoveryStopAdvertisingResponseParams _response = new DiscoveryStopAdvertisingResponseParams();
            _response.err = err;
            org.chromium.mojo.bindings.ServiceMessage _message =
                    _response.serializeWithHeader(
                            mCore,
                            new org.chromium.mojo.bindings.MessageHeader(
                                    STOP_ADVERTISING_ORDINAL,
                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
                                    mRequestId));
            mMessageReceiver.accept(_message);
        }
    }

    static final class DiscoveryStartScanParams extends org.chromium.mojo.bindings.Struct {
    
        private static final int STRUCT_SIZE = 24;
        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(24, 0)};
        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
    
        public String query;
        public ScanHandler handler;
    
        private DiscoveryStartScanParams(int version) {
            super(STRUCT_SIZE, version);
        }
    
        public DiscoveryStartScanParams() {
            this(0);
        }
    
        public static DiscoveryStartScanParams deserialize(org.chromium.mojo.bindings.Message message) {
            return decode(new org.chromium.mojo.bindings.Decoder(message));
        }
    
        @SuppressWarnings("unchecked")
        public static DiscoveryStartScanParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
            if (decoder0 == null) {
                return null;
            }
            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
            DiscoveryStartScanParams result = new DiscoveryStartScanParams(mainDataHeader.elementsOrVersion);
            if (mainDataHeader.elementsOrVersion >= 0) {
                result.query = decoder0.readString(8, false);
            }
            if (mainDataHeader.elementsOrVersion >= 0) {
                result.handler = decoder0.readServiceInterface(16, false, ScanHandler.MANAGER);
            }
            return result;
        }
    
        @SuppressWarnings("unchecked")
        @Override
        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
            encoder0.encode(query, 8, false);
            encoder0.encode(handler, 16, false, ScanHandler.MANAGER);
        }
    
        /**
         * @see Object#equals(Object)
         */
        @Override
        public boolean equals(Object object) {
            if (object == this)
                return true;
            if (object == null)
                return false;
            if (getClass() != object.getClass())
                return false;
            DiscoveryStartScanParams other = (DiscoveryStartScanParams) object;
            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.query, other.query))
                return false;
            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.handler, other.handler))
                return false;
            return true;
        }
    
        /**
         * @see Object#hashCode()
         */
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = prime + getClass().hashCode();
            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(query);
            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(handler);
            return result;
        }
    }

    static final class DiscoveryStartScanResponseParams extends org.chromium.mojo.bindings.Struct {
    
        private static final int STRUCT_SIZE = 24;
        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(24, 0)};
        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
    
        public int scanId;
        public Error err;
    
        private DiscoveryStartScanResponseParams(int version) {
            super(STRUCT_SIZE, version);
        }
    
        public DiscoveryStartScanResponseParams() {
            this(0);
        }
    
        public static DiscoveryStartScanResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
            return decode(new org.chromium.mojo.bindings.Decoder(message));
        }
    
        @SuppressWarnings("unchecked")
        public static DiscoveryStartScanResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
            if (decoder0 == null) {
                return null;
            }
            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
            DiscoveryStartScanResponseParams result = new DiscoveryStartScanResponseParams(mainDataHeader.elementsOrVersion);
            if (mainDataHeader.elementsOrVersion >= 0) {
                result.scanId = decoder0.readInt(8);
            }
            if (mainDataHeader.elementsOrVersion >= 0) {
                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(16, true);
                result.err = Error.decode(decoder1);
            }
            return result;
        }
    
        @SuppressWarnings("unchecked")
        @Override
        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
            encoder0.encode(scanId, 8);
            encoder0.encode(err, 16, true);
        }
    
        /**
         * @see Object#equals(Object)
         */
        @Override
        public boolean equals(Object object) {
            if (object == this)
                return true;
            if (object == null)
                return false;
            if (getClass() != object.getClass())
                return false;
            DiscoveryStartScanResponseParams other = (DiscoveryStartScanResponseParams) object;
            if (this.scanId != other.scanId)
                return false;
            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.err, other.err))
                return false;
            return true;
        }
    
        /**
         * @see Object#hashCode()
         */
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = prime + getClass().hashCode();
            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(scanId);
            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(err);
            return result;
        }
    }

    static class DiscoveryStartScanResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
            implements org.chromium.mojo.bindings.MessageReceiver {
        private final Discovery.StartScanResponse mCallback;

        DiscoveryStartScanResponseParamsForwardToCallback(Discovery.StartScanResponse callback) {
            this.mCallback = callback;
        }

        @Override
        public boolean accept(org.chromium.mojo.bindings.Message message) {
            try {
                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
                        message.asServiceMessage();
                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
                if (!header.validateHeader(START_SCAN_ORDINAL,
                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
                    return false;
                }
                DiscoveryStartScanResponseParams response = DiscoveryStartScanResponseParams.deserialize(messageWithHeader.getPayload());
                mCallback.call(response.scanId, response.err);
                return true;
            } catch (org.chromium.mojo.bindings.DeserializationException e) {
                return false;
            }
        }
    }

    static class DiscoveryStartScanResponseParamsProxyToResponder implements Discovery.StartScanResponse {

        private final org.chromium.mojo.system.Core mCore;
        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
        private final long mRequestId;

        DiscoveryStartScanResponseParamsProxyToResponder(
                org.chromium.mojo.system.Core core,
                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
                long requestId) {
            mCore = core;
            mMessageReceiver = messageReceiver;
            mRequestId = requestId;
        }

        @Override
        public void call(Integer scanId, Error err) {
            DiscoveryStartScanResponseParams _response = new DiscoveryStartScanResponseParams();
            _response.scanId = scanId;
            _response.err = err;
            org.chromium.mojo.bindings.ServiceMessage _message =
                    _response.serializeWithHeader(
                            mCore,
                            new org.chromium.mojo.bindings.MessageHeader(
                                    START_SCAN_ORDINAL,
                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
                                    mRequestId));
            mMessageReceiver.accept(_message);
        }
    }

    static final class DiscoveryStopScanParams extends org.chromium.mojo.bindings.Struct {
    
        private static final int STRUCT_SIZE = 16;
        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
    
        public int scanId;
    
        private DiscoveryStopScanParams(int version) {
            super(STRUCT_SIZE, version);
        }
    
        public DiscoveryStopScanParams() {
            this(0);
        }
    
        public static DiscoveryStopScanParams deserialize(org.chromium.mojo.bindings.Message message) {
            return decode(new org.chromium.mojo.bindings.Decoder(message));
        }
    
        @SuppressWarnings("unchecked")
        public static DiscoveryStopScanParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
            if (decoder0 == null) {
                return null;
            }
            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
            DiscoveryStopScanParams result = new DiscoveryStopScanParams(mainDataHeader.elementsOrVersion);
            if (mainDataHeader.elementsOrVersion >= 0) {
                result.scanId = decoder0.readInt(8);
            }
            return result;
        }
    
        @SuppressWarnings("unchecked")
        @Override
        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
            encoder0.encode(scanId, 8);
        }
    
        /**
         * @see Object#equals(Object)
         */
        @Override
        public boolean equals(Object object) {
            if (object == this)
                return true;
            if (object == null)
                return false;
            if (getClass() != object.getClass())
                return false;
            DiscoveryStopScanParams other = (DiscoveryStopScanParams) object;
            if (this.scanId != other.scanId)
                return false;
            return true;
        }
    
        /**
         * @see Object#hashCode()
         */
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = prime + getClass().hashCode();
            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(scanId);
            return result;
        }
    }

    static final class DiscoveryStopScanResponseParams extends org.chromium.mojo.bindings.Struct {
    
        private static final int STRUCT_SIZE = 16;
        private static final org.chromium.mojo.bindings.DataHeader[] VERSION_ARRAY = new org.chromium.mojo.bindings.DataHeader[] {new org.chromium.mojo.bindings.DataHeader(16, 0)};
        private static final org.chromium.mojo.bindings.DataHeader DEFAULT_STRUCT_INFO = VERSION_ARRAY[0];
    
        public Error err;
    
        private DiscoveryStopScanResponseParams(int version) {
            super(STRUCT_SIZE, version);
        }
    
        public DiscoveryStopScanResponseParams() {
            this(0);
        }
    
        public static DiscoveryStopScanResponseParams deserialize(org.chromium.mojo.bindings.Message message) {
            return decode(new org.chromium.mojo.bindings.Decoder(message));
        }
    
        @SuppressWarnings("unchecked")
        public static DiscoveryStopScanResponseParams decode(org.chromium.mojo.bindings.Decoder decoder0) {
            if (decoder0 == null) {
                return null;
            }
            org.chromium.mojo.bindings.DataHeader mainDataHeader = decoder0.readAndValidateDataHeader(VERSION_ARRAY);
            DiscoveryStopScanResponseParams result = new DiscoveryStopScanResponseParams(mainDataHeader.elementsOrVersion);
            if (mainDataHeader.elementsOrVersion >= 0) {
                org.chromium.mojo.bindings.Decoder decoder1 = decoder0.readPointer(8, true);
                result.err = Error.decode(decoder1);
            }
            return result;
        }
    
        @SuppressWarnings("unchecked")
        @Override
        protected final void encode(org.chromium.mojo.bindings.Encoder encoder) {
            org.chromium.mojo.bindings.Encoder encoder0 = encoder.getEncoderAtDataOffset(DEFAULT_STRUCT_INFO);
            encoder0.encode(err, 8, true);
        }
    
        /**
         * @see Object#equals(Object)
         */
        @Override
        public boolean equals(Object object) {
            if (object == this)
                return true;
            if (object == null)
                return false;
            if (getClass() != object.getClass())
                return false;
            DiscoveryStopScanResponseParams other = (DiscoveryStopScanResponseParams) object;
            if (!org.chromium.mojo.bindings.BindingsHelper.equals(this.err, other.err))
                return false;
            return true;
        }
    
        /**
         * @see Object#hashCode()
         */
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = prime + getClass().hashCode();
            result = prime * result + org.chromium.mojo.bindings.BindingsHelper.hashCode(err);
            return result;
        }
    }

    static class DiscoveryStopScanResponseParamsForwardToCallback extends org.chromium.mojo.bindings.SideEffectFreeCloseable
            implements org.chromium.mojo.bindings.MessageReceiver {
        private final Discovery.StopScanResponse mCallback;

        DiscoveryStopScanResponseParamsForwardToCallback(Discovery.StopScanResponse callback) {
            this.mCallback = callback;
        }

        @Override
        public boolean accept(org.chromium.mojo.bindings.Message message) {
            try {
                org.chromium.mojo.bindings.ServiceMessage messageWithHeader =
                        message.asServiceMessage();
                org.chromium.mojo.bindings.MessageHeader header = messageWithHeader.getHeader();
                if (!header.validateHeader(STOP_SCAN_ORDINAL,
                                           org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG)) {
                    return false;
                }
                DiscoveryStopScanResponseParams response = DiscoveryStopScanResponseParams.deserialize(messageWithHeader.getPayload());
                mCallback.call(response.err);
                return true;
            } catch (org.chromium.mojo.bindings.DeserializationException e) {
                return false;
            }
        }
    }

    static class DiscoveryStopScanResponseParamsProxyToResponder implements Discovery.StopScanResponse {

        private final org.chromium.mojo.system.Core mCore;
        private final org.chromium.mojo.bindings.MessageReceiver mMessageReceiver;
        private final long mRequestId;

        DiscoveryStopScanResponseParamsProxyToResponder(
                org.chromium.mojo.system.Core core,
                org.chromium.mojo.bindings.MessageReceiver messageReceiver,
                long requestId) {
            mCore = core;
            mMessageReceiver = messageReceiver;
            mRequestId = requestId;
        }

        @Override
        public void call(Error err) {
            DiscoveryStopScanResponseParams _response = new DiscoveryStopScanResponseParams();
            _response.err = err;
            org.chromium.mojo.bindings.ServiceMessage _message =
                    _response.serializeWithHeader(
                            mCore,
                            new org.chromium.mojo.bindings.MessageHeader(
                                    STOP_SCAN_ORDINAL,
                                    org.chromium.mojo.bindings.MessageHeader.MESSAGE_IS_RESPONSE_FLAG,
                                    mRequestId));
            mMessageReceiver.accept(_message);
        }
    }

}

