// Copyright 2015 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 discovery

import (
	"fmt"
	"mojo/public/go/bindings"
	"mojo/public/go/system"
	"sort"
)

type Discoverer interface {
	Advertise(inS Service, inPattern []string) (outHandle int32, outErr *Error, err error)
	StopAdvertising(inH int32) (err error)
	Scan(inQuery string, inScanHandler ScanHandler_Pointer) (outHandle int32, outErr *Error, err error)
	StopScan(inH int32) (err error)
}

var discoverer_Name = "discovery::Discoverer"

type Discoverer_Request bindings.InterfaceRequest

func (r *Discoverer_Request) Name() string {
	return discoverer_Name
}

type Discoverer_Pointer bindings.InterfacePointer

func (p *Discoverer_Pointer) Name() string {
	return discoverer_Name
}

type Discoverer_ServiceFactory struct {
	Delegate Discoverer_Factory
}

type Discoverer_Factory interface {
	Create(request Discoverer_Request)
}

func (f *Discoverer_ServiceFactory) Name() string {
	return discoverer_Name
}

func (f *Discoverer_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
	request := Discoverer_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
	f.Delegate.Create(request)
}

// CreateMessagePipeForDiscoverer creates a message pipe for use with the
// Discoverer interface with a Discoverer_Request on one end and a Discoverer_Pointer on the other.
func CreateMessagePipeForDiscoverer() (Discoverer_Request, Discoverer_Pointer) {
	r, p := bindings.CreateMessagePipeForMojoInterface()
	return Discoverer_Request(r), Discoverer_Pointer(p)
}

const discoverer_Advertise_Name uint32 = 0
const discoverer_StopAdvertising_Name uint32 = 1
const discoverer_Scan_Name uint32 = 2
const discoverer_StopScan_Name uint32 = 3

type Discoverer_Proxy struct {
	router *bindings.Router
	ids    bindings.Counter
}

func NewDiscovererProxy(p Discoverer_Pointer, waiter bindings.AsyncWaiter) *Discoverer_Proxy {
	return &Discoverer_Proxy{
		bindings.NewRouter(p.PassMessagePipe(), waiter),
		bindings.NewCounter(),
	}
}

func (p *Discoverer_Proxy) Close_Proxy() {
	p.router.Close()
}

type discoverer_Advertise_Params struct {
	inS       Service
	inPattern []string
}

func (s *discoverer_Advertise_Params) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(16, 0)
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	if err := s.inS.Encode(encoder); err != nil {
		return err
	}
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	encoder.StartArray(uint32(len(s.inPattern)), 64)
	for _, elem0 := range s.inPattern {
		if err := encoder.WritePointer(); err != nil {
			return err
		}
		if err := encoder.WriteString(elem0); err != nil {
			return err
		}
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

var discoverer_Advertise_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{24, 0},
}

func (s *discoverer_Advertise_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discoverer_Advertise_Params_Versions), func(i int) bool {
		return discoverer_Advertise_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discoverer_Advertise_Params_Versions) {
		if discoverer_Advertise_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discoverer_Advertise_Params_Versions[index].Size
		if expectedSize != header.Size {
			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
		} else {
			if err := s.inS.Decode(decoder); err != nil {
				return err
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
		} else {
			len0, err := decoder.StartArray(64)
			if err != nil {
				return err
			}
			s.inPattern = make([]string, len0)
			for i0 := uint32(0); i0 < len0; i0++ {
				pointer1, err := decoder.ReadPointer()
				if err != nil {
					return err
				}
				if pointer1 == 0 {
					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
				} else {
					value1, err := decoder.ReadString()
					if err != nil {
						return err
					}
					s.inPattern[i0] = value1
				}
			}
			if err := decoder.Finish(); err != nil {
				return err
			}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

type discoverer_Advertise_ResponseParams struct {
	outHandle int32
	outErr    *Error
}

func (s *discoverer_Advertise_ResponseParams) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(16, 0)
	if err := encoder.WriteInt32(s.outHandle); err != nil {
		return err
	}
	if s.outErr == nil {
		encoder.WriteNullPointer()
	} else {
		if err := encoder.WritePointer(); err != nil {
			return err
		}
		if err := (*s.outErr).Encode(encoder); err != nil {
			return err
		}
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

var discoverer_Advertise_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{24, 0},
}

func (s *discoverer_Advertise_ResponseParams) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discoverer_Advertise_ResponseParams_Versions), func(i int) bool {
		return discoverer_Advertise_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discoverer_Advertise_ResponseParams_Versions) {
		if discoverer_Advertise_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discoverer_Advertise_ResponseParams_Versions[index].Size
		if expectedSize != header.Size {
			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		value0, err := decoder.ReadInt32()
		if err != nil {
			return err
		}
		s.outHandle = value0
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			s.outErr = nil
		} else {
			s.outErr = new(Error)
			if err := (*s.outErr).Decode(decoder); err != nil {
				return err
			}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

func (p *Discoverer_Proxy) Advertise(inS Service, inPattern []string) (outHandle int32, outErr *Error, err error) {
	payload := &discoverer_Advertise_Params{
		inS,
		inPattern,
	}
	header := bindings.MessageHeader{
		Type:      discoverer_Advertise_Name,
		Flags:     bindings.MessageExpectsResponseFlag,
		RequestId: p.ids.Count(),
	}
	var message *bindings.Message
	if message, err = bindings.EncodeMessage(header, payload); err != nil {
		err = fmt.Errorf("can't encode request: %v", err.Error())
		p.Close_Proxy()
		return
	}
	readResult := <-p.router.AcceptWithResponse(message)
	if err = readResult.Error; err != nil {
		p.Close_Proxy()
		return
	}
	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
		}
		return
	}
	if got, want := readResult.Message.Header.Type, discoverer_Advertise_Name; got != want {
		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
		}
		return
	}
	var response discoverer_Advertise_ResponseParams
	if err = readResult.Message.DecodePayload(&response); err != nil {
		p.Close_Proxy()
		return
	}
	outHandle = response.outHandle
	outErr = response.outErr
	return
}

type discoverer_StopAdvertising_Params struct {
	inH int32
}

func (s *discoverer_StopAdvertising_Params) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(8, 0)
	if err := encoder.WriteInt32(s.inH); err != nil {
		return err
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

var discoverer_StopAdvertising_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{16, 0},
}

func (s *discoverer_StopAdvertising_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discoverer_StopAdvertising_Params_Versions), func(i int) bool {
		return discoverer_StopAdvertising_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discoverer_StopAdvertising_Params_Versions) {
		if discoverer_StopAdvertising_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discoverer_StopAdvertising_Params_Versions[index].Size
		if expectedSize != header.Size {
			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		value0, err := decoder.ReadInt32()
		if err != nil {
			return err
		}
		s.inH = value0
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

func (p *Discoverer_Proxy) StopAdvertising(inH int32) (err error) {
	payload := &discoverer_StopAdvertising_Params{
		inH,
	}
	header := bindings.MessageHeader{
		Type:  discoverer_StopAdvertising_Name,
		Flags: bindings.MessageNoFlag,
	}
	var message *bindings.Message
	if message, err = bindings.EncodeMessage(header, payload); err != nil {
		err = fmt.Errorf("can't encode request: %v", err.Error())
		p.Close_Proxy()
		return
	}
	if err = p.router.Accept(message); err != nil {
		p.Close_Proxy()
		return
	}
	return
}

type discoverer_Scan_Params struct {
	inQuery       string
	inScanHandler ScanHandler_Pointer
}

func (s *discoverer_Scan_Params) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(16, 0)
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	if err := encoder.WriteString(s.inQuery); err != nil {
		return err
	}
	if err := encoder.WriteInterface(s.inScanHandler.PassMessagePipe()); err != nil {
		return err
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

var discoverer_Scan_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{24, 0},
}

func (s *discoverer_Scan_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discoverer_Scan_Params_Versions), func(i int) bool {
		return discoverer_Scan_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discoverer_Scan_Params_Versions) {
		if discoverer_Scan_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discoverer_Scan_Params_Versions[index].Size
		if expectedSize != header.Size {
			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
		} else {
			value0, err := decoder.ReadString()
			if err != nil {
				return err
			}
			s.inQuery = value0
		}
	}
	if header.ElementsOrVersion >= 0 {
		handle0, err := decoder.ReadInterface()
		if err != nil {
			return err
		}
		if handle0.IsValid() {
			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
			s.inScanHandler = ScanHandler_Pointer{handleOwner}
		} else {
			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

type discoverer_Scan_ResponseParams struct {
	outHandle int32
	outErr    *Error
}

func (s *discoverer_Scan_ResponseParams) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(16, 0)
	if err := encoder.WriteInt32(s.outHandle); err != nil {
		return err
	}
	if s.outErr == nil {
		encoder.WriteNullPointer()
	} else {
		if err := encoder.WritePointer(); err != nil {
			return err
		}
		if err := (*s.outErr).Encode(encoder); err != nil {
			return err
		}
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

var discoverer_Scan_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{24, 0},
}

func (s *discoverer_Scan_ResponseParams) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discoverer_Scan_ResponseParams_Versions), func(i int) bool {
		return discoverer_Scan_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discoverer_Scan_ResponseParams_Versions) {
		if discoverer_Scan_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discoverer_Scan_ResponseParams_Versions[index].Size
		if expectedSize != header.Size {
			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		value0, err := decoder.ReadInt32()
		if err != nil {
			return err
		}
		s.outHandle = value0
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			s.outErr = nil
		} else {
			s.outErr = new(Error)
			if err := (*s.outErr).Decode(decoder); err != nil {
				return err
			}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

func (p *Discoverer_Proxy) Scan(inQuery string, inScanHandler ScanHandler_Pointer) (outHandle int32, outErr *Error, err error) {
	payload := &discoverer_Scan_Params{
		inQuery,
		inScanHandler,
	}
	header := bindings.MessageHeader{
		Type:      discoverer_Scan_Name,
		Flags:     bindings.MessageExpectsResponseFlag,
		RequestId: p.ids.Count(),
	}
	var message *bindings.Message
	if message, err = bindings.EncodeMessage(header, payload); err != nil {
		err = fmt.Errorf("can't encode request: %v", err.Error())
		p.Close_Proxy()
		return
	}
	readResult := <-p.router.AcceptWithResponse(message)
	if err = readResult.Error; err != nil {
		p.Close_Proxy()
		return
	}
	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
		}
		return
	}
	if got, want := readResult.Message.Header.Type, discoverer_Scan_Name; got != want {
		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
		}
		return
	}
	var response discoverer_Scan_ResponseParams
	if err = readResult.Message.DecodePayload(&response); err != nil {
		p.Close_Proxy()
		return
	}
	outHandle = response.outHandle
	outErr = response.outErr
	return
}

type discoverer_StopScan_Params struct {
	inH int32
}

func (s *discoverer_StopScan_Params) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(8, 0)
	if err := encoder.WriteInt32(s.inH); err != nil {
		return err
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

var discoverer_StopScan_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{16, 0},
}

func (s *discoverer_StopScan_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discoverer_StopScan_Params_Versions), func(i int) bool {
		return discoverer_StopScan_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discoverer_StopScan_Params_Versions) {
		if discoverer_StopScan_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discoverer_StopScan_Params_Versions[index].Size
		if expectedSize != header.Size {
			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		value0, err := decoder.ReadInt32()
		if err != nil {
			return err
		}
		s.inH = value0
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

func (p *Discoverer_Proxy) StopScan(inH int32) (err error) {
	payload := &discoverer_StopScan_Params{
		inH,
	}
	header := bindings.MessageHeader{
		Type:  discoverer_StopScan_Name,
		Flags: bindings.MessageNoFlag,
	}
	var message *bindings.Message
	if message, err = bindings.EncodeMessage(header, payload); err != nil {
		err = fmt.Errorf("can't encode request: %v", err.Error())
		p.Close_Proxy()
		return
	}
	if err = p.router.Accept(message); err != nil {
		p.Close_Proxy()
		return
	}
	return
}

type discoverer_Stub struct {
	connector *bindings.Connector
	impl      Discoverer
}

func NewDiscovererStub(r Discoverer_Request, impl Discoverer, waiter bindings.AsyncWaiter) *bindings.Stub {
	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
	return bindings.NewStub(connector, &discoverer_Stub{connector, impl})
}

func (s *discoverer_Stub) Accept(message *bindings.Message) (err error) {
	switch message.Header.Type {
	case discoverer_Advertise_Name:
		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
			}
		}
		var request discoverer_Advertise_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		var response discoverer_Advertise_ResponseParams
		response.outHandle, response.outErr, err = s.impl.Advertise(request.inS, request.inPattern)
		if err != nil {
			return
		}
		header := bindings.MessageHeader{
			Type:      discoverer_Advertise_Name,
			Flags:     bindings.MessageIsResponseFlag,
			RequestId: message.Header.RequestId,
		}
		message, err = bindings.EncodeMessage(header, &response)
		if err != nil {
			return err
		}
		return s.connector.WriteMessage(message)
	case discoverer_StopAdvertising_Name:
		if message.Header.Flags != bindings.MessageNoFlag {
			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
			}
		}
		var request discoverer_StopAdvertising_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		err = s.impl.StopAdvertising(request.inH)
		if err != nil {
			return
		}
	case discoverer_Scan_Name:
		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
			}
		}
		var request discoverer_Scan_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		var response discoverer_Scan_ResponseParams
		response.outHandle, response.outErr, err = s.impl.Scan(request.inQuery, request.inScanHandler)
		if err != nil {
			return
		}
		header := bindings.MessageHeader{
			Type:      discoverer_Scan_Name,
			Flags:     bindings.MessageIsResponseFlag,
			RequestId: message.Header.RequestId,
		}
		message, err = bindings.EncodeMessage(header, &response)
		if err != nil {
			return err
		}
		return s.connector.WriteMessage(message)
	case discoverer_StopScan_Name:
		if message.Header.Flags != bindings.MessageNoFlag {
			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
			}
		}
		var request discoverer_StopScan_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		err = s.impl.StopScan(request.inH)
		if err != nil {
			return
		}
	default:
		return &bindings.ValidationError{
			bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("unknown method %v", message.Header.Type),
		}
	}
	return
}

type ScanHandler interface {
	Found(inS Service) (err error)
	Lost(inS Service) (err error)
}

var scanHandler_Name = "discovery::ScanHandler"

type ScanHandler_Request bindings.InterfaceRequest

func (r *ScanHandler_Request) Name() string {
	return scanHandler_Name
}

type ScanHandler_Pointer bindings.InterfacePointer

func (p *ScanHandler_Pointer) Name() string {
	return scanHandler_Name
}

type ScanHandler_ServiceFactory struct {
	Delegate ScanHandler_Factory
}

type ScanHandler_Factory interface {
	Create(request ScanHandler_Request)
}

func (f *ScanHandler_ServiceFactory) Name() string {
	return scanHandler_Name
}

func (f *ScanHandler_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
	request := ScanHandler_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
	f.Delegate.Create(request)
}

// CreateMessagePipeForScanHandler creates a message pipe for use with the
// ScanHandler interface with a ScanHandler_Request on one end and a ScanHandler_Pointer on the other.
func CreateMessagePipeForScanHandler() (ScanHandler_Request, ScanHandler_Pointer) {
	r, p := bindings.CreateMessagePipeForMojoInterface()
	return ScanHandler_Request(r), ScanHandler_Pointer(p)
}

const scanHandler_Found_Name uint32 = 0
const scanHandler_Lost_Name uint32 = 1

type ScanHandler_Proxy struct {
	router *bindings.Router
	ids    bindings.Counter
}

func NewScanHandlerProxy(p ScanHandler_Pointer, waiter bindings.AsyncWaiter) *ScanHandler_Proxy {
	return &ScanHandler_Proxy{
		bindings.NewRouter(p.PassMessagePipe(), waiter),
		bindings.NewCounter(),
	}
}

func (p *ScanHandler_Proxy) Close_Proxy() {
	p.router.Close()
}

type scanHandler_Found_Params struct {
	inS Service
}

func (s *scanHandler_Found_Params) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(8, 0)
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	if err := s.inS.Encode(encoder); err != nil {
		return err
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

var scanHandler_Found_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{16, 0},
}

func (s *scanHandler_Found_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(scanHandler_Found_Params_Versions), func(i int) bool {
		return scanHandler_Found_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(scanHandler_Found_Params_Versions) {
		if scanHandler_Found_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := scanHandler_Found_Params_Versions[index].Size
		if expectedSize != header.Size {
			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
		} else {
			if err := s.inS.Decode(decoder); err != nil {
				return err
			}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

func (p *ScanHandler_Proxy) Found(inS Service) (err error) {
	payload := &scanHandler_Found_Params{
		inS,
	}
	header := bindings.MessageHeader{
		Type:  scanHandler_Found_Name,
		Flags: bindings.MessageNoFlag,
	}
	var message *bindings.Message
	if message, err = bindings.EncodeMessage(header, payload); err != nil {
		err = fmt.Errorf("can't encode request: %v", err.Error())
		p.Close_Proxy()
		return
	}
	if err = p.router.Accept(message); err != nil {
		p.Close_Proxy()
		return
	}
	return
}

type scanHandler_Lost_Params struct {
	inS Service
}

func (s *scanHandler_Lost_Params) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(8, 0)
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	if err := s.inS.Encode(encoder); err != nil {
		return err
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

var scanHandler_Lost_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{16, 0},
}

func (s *scanHandler_Lost_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(scanHandler_Lost_Params_Versions), func(i int) bool {
		return scanHandler_Lost_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(scanHandler_Lost_Params_Versions) {
		if scanHandler_Lost_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := scanHandler_Lost_Params_Versions[index].Size
		if expectedSize != header.Size {
			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
		} else {
			if err := s.inS.Decode(decoder); err != nil {
				return err
			}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

func (p *ScanHandler_Proxy) Lost(inS Service) (err error) {
	payload := &scanHandler_Lost_Params{
		inS,
	}
	header := bindings.MessageHeader{
		Type:  scanHandler_Lost_Name,
		Flags: bindings.MessageNoFlag,
	}
	var message *bindings.Message
	if message, err = bindings.EncodeMessage(header, payload); err != nil {
		err = fmt.Errorf("can't encode request: %v", err.Error())
		p.Close_Proxy()
		return
	}
	if err = p.router.Accept(message); err != nil {
		p.Close_Proxy()
		return
	}
	return
}

type scanHandler_Stub struct {
	connector *bindings.Connector
	impl      ScanHandler
}

func NewScanHandlerStub(r ScanHandler_Request, impl ScanHandler, waiter bindings.AsyncWaiter) *bindings.Stub {
	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
	return bindings.NewStub(connector, &scanHandler_Stub{connector, impl})
}

func (s *scanHandler_Stub) Accept(message *bindings.Message) (err error) {
	switch message.Header.Type {
	case scanHandler_Found_Name:
		if message.Header.Flags != bindings.MessageNoFlag {
			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
			}
		}
		var request scanHandler_Found_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		err = s.impl.Found(request.inS)
		if err != nil {
			return
		}
	case scanHandler_Lost_Name:
		if message.Header.Flags != bindings.MessageNoFlag {
			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
			}
		}
		var request scanHandler_Lost_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		err = s.impl.Lost(request.inS)
		if err != nil {
			return
		}
	default:
		return &bindings.ValidationError{
			bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("unknown method %v", message.Header.Type),
		}
	}
	return
}

type Service struct {
	InstanceUuid  []uint8
	InterfaceName string
	Attrs         map[string]string
	Addrs         []string
}

func (s *Service) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(32, 0)
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	encoder.StartArray(uint32(len(s.InstanceUuid)), 8)
	for _, elem0 := range s.InstanceUuid {
		if err := encoder.WriteUint8(elem0); err != nil {
			return err
		}
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	if err := encoder.WriteString(s.InterfaceName); err != nil {
		return err
	}
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	encoder.StartMap()
	{
		var keys0 []string
		var values0 []string
		for key0, value0 := range s.Attrs {
			keys0 = append(keys0, key0)
			values0 = append(values0, value0)
		}
		if err := encoder.WritePointer(); err != nil {
			return err
		}
		encoder.StartArray(uint32(len(keys0)), 64)
		for _, elem1 := range keys0 {
			if err := encoder.WritePointer(); err != nil {
				return err
			}
			if err := encoder.WriteString(elem1); err != nil {
				return err
			}
		}
		if err := encoder.Finish(); err != nil {
			return err
		}
		if err := encoder.WritePointer(); err != nil {
			return err
		}
		encoder.StartArray(uint32(len(values0)), 64)
		for _, elem1 := range values0 {
			if err := encoder.WritePointer(); err != nil {
				return err
			}
			if err := encoder.WriteString(elem1); err != nil {
				return err
			}
		}
		if err := encoder.Finish(); err != nil {
			return err
		}
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	encoder.StartArray(uint32(len(s.Addrs)), 64)
	for _, elem0 := range s.Addrs {
		if err := encoder.WritePointer(); err != nil {
			return err
		}
		if err := encoder.WriteString(elem0); err != nil {
			return err
		}
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

var service_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{40, 0},
}

func (s *Service) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(service_Versions), func(i int) bool {
		return service_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(service_Versions) {
		if service_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := service_Versions[index].Size
		if expectedSize != header.Size {
			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
		} else {
			len0, err := decoder.StartArray(8)
			if err != nil {
				return err
			}
			s.InstanceUuid = make([]uint8, len0)
			for i0 := uint32(0); i0 < len0; i0++ {
				value1, err := decoder.ReadUint8()
				if err != nil {
					return err
				}
				s.InstanceUuid[i0] = value1
			}
			if err := decoder.Finish(); err != nil {
				return err
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
		} else {
			value0, err := decoder.ReadString()
			if err != nil {
				return err
			}
			s.InterfaceName = value0
		}
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
		} else {
			if err := decoder.StartMap(); err != nil {
				return err
			}
			var keys0 []string
			{
				pointer1, err := decoder.ReadPointer()
				if err != nil {
					return err
				}
				if pointer1 == 0 {
					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
				} else {
					len1, err := decoder.StartArray(64)
					if err != nil {
						return err
					}
					keys0 = make([]string, len1)
					for i1 := uint32(0); i1 < len1; i1++ {
						pointer2, err := decoder.ReadPointer()
						if err != nil {
							return err
						}
						if pointer2 == 0 {
							return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
						} else {
							value2, err := decoder.ReadString()
							if err != nil {
								return err
							}
							keys0[i1] = value2
						}
					}
					if err := decoder.Finish(); err != nil {
						return err
					}
				}
			}
			var values0 []string
			{
				pointer1, err := decoder.ReadPointer()
				if err != nil {
					return err
				}
				if pointer1 == 0 {
					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
				} else {
					len1, err := decoder.StartArray(64)
					if err != nil {
						return err
					}
					values0 = make([]string, len1)
					for i1 := uint32(0); i1 < len1; i1++ {
						pointer2, err := decoder.ReadPointer()
						if err != nil {
							return err
						}
						if pointer2 == 0 {
							return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
						} else {
							value2, err := decoder.ReadString()
							if err != nil {
								return err
							}
							values0[i1] = value2
						}
					}
					if err := decoder.Finish(); err != nil {
						return err
					}
				}
			}
			if len(keys0) != len(values0) {
				return &bindings.ValidationError{bindings.DifferentSizedArraysInMap,
					fmt.Sprintf("Number of keys %d is different from number of values %d", len(keys0), len(values0)),
				}
			}
			if err := decoder.Finish(); err != nil {
				return err
			}
			len0 := len(keys0)
			map0 := make(map[string]string)
			for i0 := 0; i0 < len0; i0++ {
				map0[keys0[i0]] = values0[i0]
			}
			s.Attrs = map0
		}
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
		} else {
			len0, err := decoder.StartArray(64)
			if err != nil {
				return err
			}
			s.Addrs = make([]string, len0)
			for i0 := uint32(0); i0 < len0; i0++ {
				pointer1, err := decoder.ReadPointer()
				if err != nil {
					return err
				}
				if pointer1 == 0 {
					return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
				} else {
					value1, err := decoder.ReadString()
					if err != nil {
						return err
					}
					s.Addrs[i0] = value1
				}
			}
			if err := decoder.Finish(); err != nil {
				return err
			}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

type Error struct {
	Id     string
	Action int32
	Msg    string
}

func (s *Error) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(24, 0)
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	if err := encoder.WriteString(s.Id); err != nil {
		return err
	}
	if err := encoder.WriteInt32(s.Action); err != nil {
		return err
	}
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	if err := encoder.WriteString(s.Msg); err != nil {
		return err
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

var error_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{32, 0},
}

func (s *Error) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(error_Versions), func(i int) bool {
		return error_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(error_Versions) {
		if error_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := error_Versions[index].Size
		if expectedSize != header.Size {
			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
		} else {
			value0, err := decoder.ReadString()
			if err != nil {
				return err
			}
			s.Id = value0
		}
	}
	if header.ElementsOrVersion >= 0 {
		value0, err := decoder.ReadInt32()
		if err != nil {
			return err
		}
		s.Action = value0
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
		} else {
			value0, err := decoder.ReadString()
			if err != nil {
				return err
			}
			s.Msg = value0
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}
