// 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/v.io/x/ref/services/discovery/discovery.mojom
//

package discovery

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

type Discovery interface {
	Advertise(inService Service) (outHandle DiscoveryStopper_Pointer, err error)
	Scan(inQuery string, inHandler DiscoveryHandler_Pointer) (outHandle DiscoveryStopper_Pointer, err error)
}

var discovery_Name = "discovery::Discovery"

type Discovery_Request bindings.InterfaceRequest

func (r *Discovery_Request) Name() string {
	return discovery_Name
}

type Discovery_Pointer bindings.InterfacePointer

func (p *Discovery_Pointer) Name() string {
	return discovery_Name
}

type Discovery_ServiceFactory struct{
	Delegate Discovery_Factory
}

type Discovery_Factory interface {
	Create(request Discovery_Request)
}

func (f *Discovery_ServiceFactory) Name() string {
	return discovery_Name
}

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

// CreateMessagePipeForDiscovery creates a message pipe for use with the
// Discovery interface with a Discovery_Request on one end and a Discovery_Pointer on the other.
func CreateMessagePipeForDiscovery() (Discovery_Request, Discovery_Pointer) {
        r, p := bindings.CreateMessagePipeForMojoInterface()
        return Discovery_Request(r), Discovery_Pointer(p)
}

const discovery_Advertise_Name uint32 = 0
const discovery_Scan_Name uint32 = 1

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

func NewDiscoveryProxy(p Discovery_Pointer, waiter bindings.AsyncWaiter) *Discovery_Proxy {
	return &Discovery_Proxy{
		bindings.NewRouter(p.PassMessagePipe(), waiter),
		bindings.NewCounter(),
	}
}

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

type discovery_Advertise_Params struct {
	inService Service
}

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

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

func (s *discovery_Advertise_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discovery_Advertise_Params_Versions), func(i int) bool {
		return discovery_Advertise_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discovery_Advertise_Params_Versions) {
		if discovery_Advertise_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discovery_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.inService.Decode(decoder); err != nil {
				return err
			}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

type discovery_Advertise_ResponseParams struct {
	outHandle DiscoveryStopper_Pointer
}

func (s *discovery_Advertise_ResponseParams) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(8, 0)
	if err := encoder.WriteInterface(s.outHandle.PassMessagePipe()); err != nil {
		return err
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

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

func (s *discovery_Advertise_ResponseParams) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discovery_Advertise_ResponseParams_Versions), func(i int) bool {
		return discovery_Advertise_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discovery_Advertise_ResponseParams_Versions) {
		if discovery_Advertise_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discovery_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 {
		handle0, err := decoder.ReadInterface()
		if err != nil {
			return err
		}
		if handle0.IsValid() {
			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
			s.outHandle = DiscoveryStopper_Pointer{handleOwner}
		} else {
			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

func (p *Discovery_Proxy) Advertise(inService Service) (outHandle DiscoveryStopper_Pointer, err error) {
	payload := &discovery_Advertise_Params{
		inService,
	}
	header := bindings.MessageHeader{
		Type: discovery_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, discovery_Advertise_Name; got != want {
		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
		}
		return
	}
	var response discovery_Advertise_ResponseParams
	if err = readResult.Message.DecodePayload(&response); err != nil {
		p.Close_Proxy()
		return
	}
	outHandle = response.outHandle
	return
}

type discovery_Scan_Params struct {
	inQuery string
	inHandler DiscoveryHandler_Pointer
}

func (s *discovery_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.inHandler.PassMessagePipe()); err != nil {
		return err
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

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

func (s *discovery_Scan_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discovery_Scan_Params_Versions), func(i int) bool {
		return discovery_Scan_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discovery_Scan_Params_Versions) {
		if discovery_Scan_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discovery_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.inHandler = DiscoveryHandler_Pointer{handleOwner}
		} else {
			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

type discovery_Scan_ResponseParams struct {
	outHandle DiscoveryStopper_Pointer
}

func (s *discovery_Scan_ResponseParams) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(8, 0)
	if err := encoder.WriteInterface(s.outHandle.PassMessagePipe()); err != nil {
		return err
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

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

func (s *discovery_Scan_ResponseParams) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discovery_Scan_ResponseParams_Versions), func(i int) bool {
		return discovery_Scan_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discovery_Scan_ResponseParams_Versions) {
		if discovery_Scan_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discovery_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 {
		handle0, err := decoder.ReadInterface()
		if err != nil {
			return err
		}
		if handle0.IsValid() {
			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
			s.outHandle = DiscoveryStopper_Pointer{handleOwner}
		} else {
			return &bindings.ValidationError{bindings.UnexpectedInvalidHandle, "unexpected invalid handle"}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

func (p *Discovery_Proxy) Scan(inQuery string, inHandler DiscoveryHandler_Pointer) (outHandle DiscoveryStopper_Pointer, err error) {
	payload := &discovery_Scan_Params{
		inQuery,
		inHandler,
	}
	header := bindings.MessageHeader{
		Type: discovery_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, discovery_Scan_Name; got != want {
		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
		}
		return
	}
	var response discovery_Scan_ResponseParams
	if err = readResult.Message.DecodePayload(&response); err != nil {
		p.Close_Proxy()
		return
	}
	outHandle = response.outHandle
	return
}

type discovery_Stub struct {
	connector *bindings.Connector
	impl Discovery
}

func NewDiscoveryStub(r Discovery_Request, impl Discovery, waiter bindings.AsyncWaiter) *bindings.Stub {
	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
	return bindings.NewStub(connector, &discovery_Stub{connector, impl})
}

func (s *discovery_Stub) Accept(message *bindings.Message) (err error) {
	switch message.Header.Type {
	case discovery_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 discovery_Advertise_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		var response discovery_Advertise_ResponseParams
		response.outHandle, err = s.impl.Advertise(request.inService)
		if err != nil {
			return
		}
		header := bindings.MessageHeader{
			Type: discovery_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 discovery_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 discovery_Scan_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		var response discovery_Scan_ResponseParams
		response.outHandle, err = s.impl.Scan(request.inQuery, request.inHandler)
		if err != nil {
			return
		}
		header := bindings.MessageHeader{
			Type: discovery_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)
	default:
		return &bindings.ValidationError{
			bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("unknown method %v", message.Header.Type),
		}
	}
	return
}

type DiscoveryStopper interface {
	Stop() (err error)
}

var discoveryStopper_Name = "discovery::DiscoveryStopper"

type DiscoveryStopper_Request bindings.InterfaceRequest

func (r *DiscoveryStopper_Request) Name() string {
	return discoveryStopper_Name
}

type DiscoveryStopper_Pointer bindings.InterfacePointer

func (p *DiscoveryStopper_Pointer) Name() string {
	return discoveryStopper_Name
}

type DiscoveryStopper_ServiceFactory struct{
	Delegate DiscoveryStopper_Factory
}

type DiscoveryStopper_Factory interface {
	Create(request DiscoveryStopper_Request)
}

func (f *DiscoveryStopper_ServiceFactory) Name() string {
	return discoveryStopper_Name
}

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

// CreateMessagePipeForDiscoveryStopper creates a message pipe for use with the
// DiscoveryStopper interface with a DiscoveryStopper_Request on one end and a DiscoveryStopper_Pointer on the other.
func CreateMessagePipeForDiscoveryStopper() (DiscoveryStopper_Request, DiscoveryStopper_Pointer) {
        r, p := bindings.CreateMessagePipeForMojoInterface()
        return DiscoveryStopper_Request(r), DiscoveryStopper_Pointer(p)
}

const discoveryStopper_Stop_Name uint32 = 0

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

func NewDiscoveryStopperProxy(p DiscoveryStopper_Pointer, waiter bindings.AsyncWaiter) *DiscoveryStopper_Proxy {
	return &DiscoveryStopper_Proxy{
		bindings.NewRouter(p.PassMessagePipe(), waiter),
		bindings.NewCounter(),
	}
}

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

type discoveryStopper_Stop_Params struct {
}

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

var discoveryStopper_Stop_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{8, 0},
}

func (s *discoveryStopper_Stop_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discoveryStopper_Stop_Params_Versions), func(i int) bool {
		return discoveryStopper_Stop_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discoveryStopper_Stop_Params_Versions) {
		if discoveryStopper_Stop_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discoveryStopper_Stop_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 err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

func (p *DiscoveryStopper_Proxy) Stop() (err error) {
	payload := &discoveryStopper_Stop_Params{
	}
	header := bindings.MessageHeader{
		Type: discoveryStopper_Stop_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 discoveryStopper_Stub struct {
	connector *bindings.Connector
	impl DiscoveryStopper
}

func NewDiscoveryStopperStub(r DiscoveryStopper_Request, impl DiscoveryStopper, waiter bindings.AsyncWaiter) *bindings.Stub {
	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
	return bindings.NewStub(connector, &discoveryStopper_Stub{connector, impl})
}

func (s *discoveryStopper_Stub) Accept(message *bindings.Message) (err error) {
	switch message.Header.Type {
	case discoveryStopper_Stop_Name:
		if message.Header.Flags != bindings.MessageNoFlag {
			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
			}
		}
		var request discoveryStopper_Stop_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		err = s.impl.Stop()
		if err != nil {
			return
		}
	default:
		return &bindings.ValidationError{
			bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("unknown method %v", message.Header.Type),
		}
	}
	return
}

type DiscoveryHandler interface {
	Found(inS Service) (err error)
	Lost(inId []uint8) (err error)
}

var discoveryHandler_Name = "discovery::DiscoveryHandler"

type DiscoveryHandler_Request bindings.InterfaceRequest

func (r *DiscoveryHandler_Request) Name() string {
	return discoveryHandler_Name
}

type DiscoveryHandler_Pointer bindings.InterfacePointer

func (p *DiscoveryHandler_Pointer) Name() string {
	return discoveryHandler_Name
}

type DiscoveryHandler_ServiceFactory struct{
	Delegate DiscoveryHandler_Factory
}

type DiscoveryHandler_Factory interface {
	Create(request DiscoveryHandler_Request)
}

func (f *DiscoveryHandler_ServiceFactory) Name() string {
	return discoveryHandler_Name
}

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

// CreateMessagePipeForDiscoveryHandler creates a message pipe for use with the
// DiscoveryHandler interface with a DiscoveryHandler_Request on one end and a DiscoveryHandler_Pointer on the other.
func CreateMessagePipeForDiscoveryHandler() (DiscoveryHandler_Request, DiscoveryHandler_Pointer) {
        r, p := bindings.CreateMessagePipeForMojoInterface()
        return DiscoveryHandler_Request(r), DiscoveryHandler_Pointer(p)
}

const discoveryHandler_Found_Name uint32 = 0
const discoveryHandler_Lost_Name uint32 = 1

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

func NewDiscoveryHandlerProxy(p DiscoveryHandler_Pointer, waiter bindings.AsyncWaiter) *DiscoveryHandler_Proxy {
	return &DiscoveryHandler_Proxy{
		bindings.NewRouter(p.PassMessagePipe(), waiter),
		bindings.NewCounter(),
	}
}

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

type discoveryHandler_Found_Params struct {
	inS Service
}

func (s *discoveryHandler_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 discoveryHandler_Found_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{16, 0},
}

func (s *discoveryHandler_Found_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discoveryHandler_Found_Params_Versions), func(i int) bool {
		return discoveryHandler_Found_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discoveryHandler_Found_Params_Versions) {
		if discoveryHandler_Found_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discoveryHandler_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 *DiscoveryHandler_Proxy) Found(inS Service) (err error) {
	payload := &discoveryHandler_Found_Params{
		inS,
	}
	header := bindings.MessageHeader{
		Type: discoveryHandler_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 discoveryHandler_Lost_Params struct {
	inId []uint8
}

func (s *discoveryHandler_Lost_Params) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(8, 0)
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	encoder.StartArray(uint32(len(s.inId)), 8)
	for _, elem0 := range s.inId {
		if err := encoder.WriteUint8(elem0); err != nil {
			return err
		}
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

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

func (s *discoveryHandler_Lost_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discoveryHandler_Lost_Params_Versions), func(i int) bool {
		return discoveryHandler_Lost_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discoveryHandler_Lost_Params_Versions) {
		if discoveryHandler_Lost_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discoveryHandler_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 {
			len0, err := decoder.StartArray(8)
			if err != nil {
				return err
			}
			s.inId = make([]uint8, len0)
			for i0 := uint32(0); i0 < len0; i0++ {
				value1, err := decoder.ReadUint8()
				if err != nil {
					return err
				}
				s.inId[i0] = value1
			}
			if err := decoder.Finish(); err != nil {
				return err
			}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

func (p *DiscoveryHandler_Proxy) Lost(inId []uint8) (err error) {
	payload := &discoveryHandler_Lost_Params{
		inId,
	}
	header := bindings.MessageHeader{
		Type: discoveryHandler_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 discoveryHandler_Stub struct {
	connector *bindings.Connector
	impl DiscoveryHandler
}

func NewDiscoveryHandlerStub(r DiscoveryHandler_Request, impl DiscoveryHandler, waiter bindings.AsyncWaiter) *bindings.Stub {
	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
	return bindings.NewStub(connector, &discoveryHandler_Stub{connector, impl})
}

func (s *discoveryHandler_Stub) Accept(message *bindings.Message) (err error) {
	switch message.Header.Type {
	case discoveryHandler_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 discoveryHandler_Found_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		err = s.impl.Found(request.inS)
		if err != nil {
			return
		}
	case discoveryHandler_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 discoveryHandler_Lost_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		err = s.impl.Lost(request.inId)
		if err != nil {
			return
		}
	default:
		return &bindings.ValidationError{
			bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("unknown method %v", message.Header.Type),
		}
	}
	return
}

type Service struct {
	InterfaceNames string
	Attrs map[string]string
	Addrs []string
}

func (s *Service) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(24, 0)
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	if err := encoder.WriteString(s.InterfaceNames); 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{32, 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 {
			value0, err := decoder.ReadString()
			if err != nil {
				return err
			}
			s.InterfaceNames = 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
}

