// 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"
	"mojo/public/interfaces/bindings/mojom_types"
	"mojo/public/interfaces/bindings/service_describer"
	"sort"
)

// These IDs are the Mojom Identifiers / Type Keys.
// Mojom libraries importing this one will use these identifiers when building
// TypeReference objects.
var ID_discovery_Service__ string = "discovery_Service__"
var ID_discovery_Error__ string = "discovery_Error__"
var ID_discovery_Advertiser__ string = "discovery_Advertiser__"
var ID_discovery_Scanner__ string = "discovery_Scanner__"
var ID_discovery_ScanHandler__ string = "discovery_ScanHandler__"

var discoveryDesc__ = make(map[string]mojom_types.UserDefinedType)

func init() {
	discoveryDesc__["discovery_Service__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Service__(),
	}

	discoveryDesc__["discovery_Error__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Error__(),
	}

	discoveryDesc__["discovery_Advertiser__"] = &mojom_types.UserDefinedTypeInterfaceType{
		Value: discovery_Advertiser__(),
	}
	discoveryDesc__["discovery_Advertiser_Advertise_Params__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Advertiser_Advertise_Params__(),
	}

	discoveryDesc__["discovery_Advertiser_Advertise_ResponseParams__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Advertiser_Advertise_ResponseParams__(),
	}

	discoveryDesc__["discovery_Advertiser_Stop_Params__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Advertiser_Stop_Params__(),
	}

	discoveryDesc__["discovery_Advertiser_Stop_ResponseParams__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Advertiser_Stop_ResponseParams__(),
	}

	discoveryDesc__["discovery_Scanner__"] = &mojom_types.UserDefinedTypeInterfaceType{
		Value: discovery_Scanner__(),
	}
	discoveryDesc__["discovery_Scanner_Scan_Params__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Scanner_Scan_Params__(),
	}

	discoveryDesc__["discovery_ScanHandler__"] = &mojom_types.UserDefinedTypeInterfaceType{
		Value: discovery_ScanHandler__(),
	}
	discoveryDesc__["discovery_ScanHandler_Found_Params__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_ScanHandler_Found_Params__(),
	}

	discoveryDesc__["discovery_ScanHandler_Lost_Params__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_ScanHandler_Lost_Params__(),
	}

	discoveryDesc__["discovery_Scanner_Scan_ResponseParams__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Scanner_Scan_ResponseParams__(),
	}

	discoveryDesc__["discovery_Scanner_Stop_Params__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Scanner_Stop_Params__(),
	}

	discoveryDesc__["discovery_Scanner_Stop_ResponseParams__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Scanner_Stop_ResponseParams__(),
	}

}
func GetAllMojomTypeDefinitions() map[string]mojom_types.UserDefinedType {
	return discoveryDesc__
}

type Advertiser interface {
	Advertise(inService Service, inVisibility *[]string) (outHandle uint32, outInstanceId string, outErr *Error, err error)
	Stop(inH uint32) (outErr *Error, err error)
}

var advertiser_Name = "discovery::Advertiser"

type Advertiser_Request bindings.InterfaceRequest

func (r *Advertiser_Request) Name() string {
	return advertiser_Name
}

type Advertiser_Pointer bindings.InterfacePointer

func (p *Advertiser_Pointer) Name() string {
	return advertiser_Name
}

type Advertiser_ServiceFactory struct {
	Delegate Advertiser_Factory
}

type Advertiser_Factory interface {
	Create(request Advertiser_Request)
}

func (f *Advertiser_ServiceFactory) Name() string {
	return advertiser_Name
}

func (f *Advertiser_ServiceFactory) ServiceDescription() service_describer.ServiceDescription {
	return &Advertiser_ServiceDescription{}
}

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

// CreateMessagePipeForAdvertiser creates a message pipe for use with the
// Advertiser interface with a Advertiser_Request on one end and a Advertiser_Pointer on the other.
func CreateMessagePipeForAdvertiser() (Advertiser_Request, Advertiser_Pointer) {
	r, p := bindings.CreateMessagePipeForMojoInterface()
	return Advertiser_Request(r), Advertiser_Pointer(p)
}

const advertiser_Advertise_Name uint32 = 0
const advertiser_Stop_Name uint32 = 1

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

func NewAdvertiserProxy(p Advertiser_Pointer, waiter bindings.AsyncWaiter) *Advertiser_Proxy {
	return &Advertiser_Proxy{
		bindings.NewRouter(p.PassMessagePipe(), waiter),
		bindings.NewCounter(),
	}
}

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

type advertiser_Advertise_Params struct {
	inService    Service
	inVisibility *[]string
}

func (s *advertiser_Advertise_Params) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(16, 0)
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	if err := s.inService.Encode(encoder); err != nil {
		return err
	}
	if s.inVisibility == nil {
		encoder.WriteNullPointer()
	} else {
		if err := encoder.WritePointer(); err != nil {
			return err
		}
		encoder.StartArray(uint32(len((*s.inVisibility))), 64)
		for _, elem0 := range *s.inVisibility {
			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 advertiser_Advertise_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{24, 0},
}

func (s *advertiser_Advertise_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(advertiser_Advertise_Params_Versions), func(i int) bool {
		return advertiser_Advertise_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(advertiser_Advertise_Params_Versions) {
		if advertiser_Advertise_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := advertiser_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 header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			s.inVisibility = nil
		} else {
			s.inVisibility = new([]string)
			len0, err := decoder.StartArray(64)
			if err != nil {
				return err
			}
			(*s.inVisibility) = 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.inVisibility)[i0] = value1
				}
			}
			if err := decoder.Finish(); err != nil {
				return err
			}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

// String names and labels used by the MojomStruct types.
var (
	structName_AdvertiserAdvertiseParams                   = "AdvertiserAdvertiseParams"
	structFieldName_AdvertiserAdvertiseParams_InService    = "InService"
	structFieldName_AdvertiserAdvertiseParams_InVisibility = "InVisibility"
)

func discovery_Advertiser_Advertise_Params__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &structName_AdvertiserAdvertiseParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_AdvertiserAdvertiseParams_InService,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Identifier: &ID_discovery_Service__,
					TypeKey: &ID_discovery_Service__},
			},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_AdvertiserAdvertiseParams_InVisibility,
			},
			Type: &mojom_types.TypeArrayType{
				Value: mojom_types.ArrayType{Nullable: true, ElementType: &mojom_types.TypeStringType{mojom_types.StringType{false}}},
			},
		}},
	}
}

type advertiser_Advertise_ResponseParams struct {
	outHandle     uint32
	outInstanceId string
	outErr        *Error
}

func (s *advertiser_Advertise_ResponseParams) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(24, 0)
	if err := encoder.WriteUint32(s.outHandle); err != nil {
		return err
	}
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	if err := encoder.WriteString(s.outInstanceId); 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 advertiser_Advertise_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{32, 0},
}

func (s *advertiser_Advertise_ResponseParams) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(advertiser_Advertise_ResponseParams_Versions), func(i int) bool {
		return advertiser_Advertise_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(advertiser_Advertise_ResponseParams_Versions) {
		if advertiser_Advertise_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := advertiser_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.ReadUint32()
		if err != nil {
			return err
		}
		s.outHandle = 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.outInstanceId = 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
}

// String names and labels used by the MojomStruct types.
var (
	structName_AdvertiserAdvertiseResponseParams                    = "AdvertiserAdvertiseResponseParams"
	structFieldName_AdvertiserAdvertiseResponseParams_OutHandle     = "OutHandle"
	structFieldName_AdvertiserAdvertiseResponseParams_OutInstanceId = "OutInstanceId"
	structFieldName_AdvertiserAdvertiseResponseParams_OutErr        = "OutErr"
)

func discovery_Advertiser_Advertise_ResponseParams__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &structName_AdvertiserAdvertiseResponseParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_AdvertiserAdvertiseResponseParams_OutHandle,
			},
			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT32},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_AdvertiserAdvertiseResponseParams_OutInstanceId,
			},
			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_AdvertiserAdvertiseResponseParams_OutErr,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
					TypeKey: &ID_discovery_Error__},
			},
		}},
	}
}

func (p *Advertiser_Proxy) Advertise(inService Service, inVisibility *[]string) (outHandle uint32, outInstanceId string, outErr *Error, err error) {
	payload := &advertiser_Advertise_Params{
		inService,
		inVisibility,
	}
	header := bindings.MessageHeader{
		Type:      advertiser_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, advertiser_Advertise_Name; got != want {
		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
		}
		return
	}
	var response advertiser_Advertise_ResponseParams
	if err = readResult.Message.DecodePayload(&response); err != nil {
		p.Close_Proxy()
		return
	}
	outHandle = response.outHandle
	outInstanceId = response.outInstanceId
	outErr = response.outErr
	return
}

type advertiser_Stop_Params struct {
	inH uint32
}

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

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

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

// String names and labels used by the MojomStruct types.
var (
	structName_AdvertiserStopParams          = "AdvertiserStopParams"
	structFieldName_AdvertiserStopParams_InH = "InH"
)

func discovery_Advertiser_Stop_Params__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &structName_AdvertiserStopParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_AdvertiserStopParams_InH,
			},
			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT32},
		}},
	}
}

type advertiser_Stop_ResponseParams struct {
	outErr *Error
}

func (s *advertiser_Stop_ResponseParams) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(8, 0)
	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 advertiser_Stop_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{16, 0},
}

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

// String names and labels used by the MojomStruct types.
var (
	structName_AdvertiserStopResponseParams             = "AdvertiserStopResponseParams"
	structFieldName_AdvertiserStopResponseParams_OutErr = "OutErr"
)

func discovery_Advertiser_Stop_ResponseParams__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &structName_AdvertiserStopResponseParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_AdvertiserStopResponseParams_OutErr,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
					TypeKey: &ID_discovery_Error__},
			},
		}},
	}
}

func (p *Advertiser_Proxy) Stop(inH uint32) (outErr *Error, err error) {
	payload := &advertiser_Stop_Params{
		inH,
	}
	header := bindings.MessageHeader{
		Type:      advertiser_Stop_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, advertiser_Stop_Name; got != want {
		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
		}
		return
	}
	var response advertiser_Stop_ResponseParams
	if err = readResult.Message.DecodePayload(&response); err != nil {
		p.Close_Proxy()
		return
	}
	outErr = response.outErr
	return
}

type advertiser_Stub struct {
	connector *bindings.Connector
	impl      Advertiser
}

func NewAdvertiserStub(r Advertiser_Request, impl Advertiser, waiter bindings.AsyncWaiter) *bindings.Stub {
	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
	return bindings.NewStub(connector, &advertiser_Stub{connector, impl})
}

var (
	interfaceName_Advertiser                 = "Advertiser"
	interfaceMethodName_Advertiser_Advertise = "Advertise"
	interfaceMethodName_Advertiser_Stop      = "Stop"
)

func discovery_Advertiser__() mojom_types.MojomInterface {
	responseParamsMap := make(map[string]*mojom_types.MojomStruct)
	_ = responseParamsMap // To avoid the declared but unused compiler error
	mstruct_Advertise := discovery_Advertiser_Advertise_ResponseParams__()
	responseParamsMap[interfaceMethodName_Advertiser_Advertise] = &mstruct_Advertise
	mstruct_Stop := discovery_Advertiser_Stop_ResponseParams__()
	responseParamsMap[interfaceMethodName_Advertiser_Stop] = &mstruct_Stop
	return mojom_types.MojomInterface{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &interfaceName_Advertiser,
		},
		Methods: map[uint32]mojom_types.MojomMethod{advertiser_Advertise_Name: mojom_types.MojomMethod{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &interfaceMethodName_Advertiser_Advertise,
			},
			Parameters:     discovery_Advertiser_Advertise_Params__(),
			ResponseParams: responseParamsMap[interfaceMethodName_Advertiser_Advertise],
		}, advertiser_Stop_Name: mojom_types.MojomMethod{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &interfaceMethodName_Advertiser_Stop,
			},
			Parameters:     discovery_Advertiser_Stop_Params__(),
			ResponseParams: responseParamsMap[interfaceMethodName_Advertiser_Stop],
		}},
	}
}

func (f *Advertiser_Request) ServiceDescription() service_describer.ServiceDescription {
	return &Advertiser_ServiceDescription{}
}

type Advertiser_ServiceDescription struct{}

func (sd *Advertiser_ServiceDescription) GetTopLevelInterface() (outMojomInterface mojom_types.MojomInterface, err error) {
	return discovery_Advertiser__(), nil
}

func (sd *Advertiser_ServiceDescription) GetTypeDefinition(inTypeKey string) (outType mojom_types.UserDefinedType, err error) {
	if udt, ok := GetAllMojomTypeDefinitions()[inTypeKey]; ok {
		return udt, nil
	}
	return nil, fmt.Errorf("%s_ServiceDescription does not recognize %s", "Advertiser", inTypeKey)
}

func (sd *Advertiser_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) {
	o := GetAllMojomTypeDefinitions()
	return &o, nil
}

var _ service_describer.ServiceDescription = (*Advertiser_ServiceDescription)(nil)

func (s *advertiser_Stub) Accept(message *bindings.Message) (err error) {
	switch message.Header.Type {
	case advertiser_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 advertiser_Advertise_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		var response advertiser_Advertise_ResponseParams
		response.outHandle, response.outInstanceId, response.outErr, err = s.impl.Advertise(request.inService, request.inVisibility)
		if err != nil {
			return
		}
		header := bindings.MessageHeader{
			Type:      advertiser_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 advertiser_Stop_Name:
		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
			}
		}
		var request advertiser_Stop_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		var response advertiser_Stop_ResponseParams
		response.outErr, err = s.impl.Stop(request.inH)
		if err != nil {
			return
		}
		header := bindings.MessageHeader{
			Type:      advertiser_Stop_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 Scanner interface {
	Scan(inQuery string, inScanHandler ScanHandler_Pointer) (outHandle uint32, outErr *Error, err error)
	Stop(inH uint32) (outErr *Error, err error)
}

var scanner_Name = "discovery::Scanner"

type Scanner_Request bindings.InterfaceRequest

func (r *Scanner_Request) Name() string {
	return scanner_Name
}

type Scanner_Pointer bindings.InterfacePointer

func (p *Scanner_Pointer) Name() string {
	return scanner_Name
}

type Scanner_ServiceFactory struct {
	Delegate Scanner_Factory
}

type Scanner_Factory interface {
	Create(request Scanner_Request)
}

func (f *Scanner_ServiceFactory) Name() string {
	return scanner_Name
}

func (f *Scanner_ServiceFactory) ServiceDescription() service_describer.ServiceDescription {
	return &Scanner_ServiceDescription{}
}

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

// CreateMessagePipeForScanner creates a message pipe for use with the
// Scanner interface with a Scanner_Request on one end and a Scanner_Pointer on the other.
func CreateMessagePipeForScanner() (Scanner_Request, Scanner_Pointer) {
	r, p := bindings.CreateMessagePipeForMojoInterface()
	return Scanner_Request(r), Scanner_Pointer(p)
}

const scanner_Scan_Name uint32 = 0
const scanner_Stop_Name uint32 = 1

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

func NewScannerProxy(p Scanner_Pointer, waiter bindings.AsyncWaiter) *Scanner_Proxy {
	return &Scanner_Proxy{
		bindings.NewRouter(p.PassMessagePipe(), waiter),
		bindings.NewCounter(),
	}
}

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

type scanner_Scan_Params struct {
	inQuery       string
	inScanHandler ScanHandler_Pointer
}

func (s *scanner_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 scanner_Scan_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{24, 0},
}

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

// String names and labels used by the MojomStruct types.
var (
	structName_ScannerScanParams                    = "ScannerScanParams"
	structFieldName_ScannerScanParams_InQuery       = "InQuery"
	structFieldName_ScannerScanParams_InScanHandler = "InScanHandler"
)

func discovery_Scanner_Scan_Params__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &structName_ScannerScanParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_ScannerScanParams_InQuery,
			},
			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_ScannerScanParams_InScanHandler,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Identifier: &ID_discovery_ScanHandler__,
					TypeKey: &ID_discovery_ScanHandler__},
			},
		}},
	}
}

type scanner_Scan_ResponseParams struct {
	outHandle uint32
	outErr    *Error
}

func (s *scanner_Scan_ResponseParams) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(16, 0)
	if err := encoder.WriteUint32(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 scanner_Scan_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{24, 0},
}

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

// String names and labels used by the MojomStruct types.
var (
	structName_ScannerScanResponseParams                = "ScannerScanResponseParams"
	structFieldName_ScannerScanResponseParams_OutHandle = "OutHandle"
	structFieldName_ScannerScanResponseParams_OutErr    = "OutErr"
)

func discovery_Scanner_Scan_ResponseParams__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &structName_ScannerScanResponseParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_ScannerScanResponseParams_OutHandle,
			},
			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT32},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_ScannerScanResponseParams_OutErr,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
					TypeKey: &ID_discovery_Error__},
			},
		}},
	}
}

func (p *Scanner_Proxy) Scan(inQuery string, inScanHandler ScanHandler_Pointer) (outHandle uint32, outErr *Error, err error) {
	payload := &scanner_Scan_Params{
		inQuery,
		inScanHandler,
	}
	header := bindings.MessageHeader{
		Type:      scanner_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, scanner_Scan_Name; got != want {
		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
		}
		return
	}
	var response scanner_Scan_ResponseParams
	if err = readResult.Message.DecodePayload(&response); err != nil {
		p.Close_Proxy()
		return
	}
	outHandle = response.outHandle
	outErr = response.outErr
	return
}

type scanner_Stop_Params struct {
	inH uint32
}

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

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

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

// String names and labels used by the MojomStruct types.
var (
	structName_ScannerStopParams          = "ScannerStopParams"
	structFieldName_ScannerStopParams_InH = "InH"
)

func discovery_Scanner_Stop_Params__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &structName_ScannerStopParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_ScannerStopParams_InH,
			},
			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT32},
		}},
	}
}

type scanner_Stop_ResponseParams struct {
	outErr *Error
}

func (s *scanner_Stop_ResponseParams) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(8, 0)
	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 scanner_Stop_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
	bindings.DataHeader{16, 0},
}

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

// String names and labels used by the MojomStruct types.
var (
	structName_ScannerStopResponseParams             = "ScannerStopResponseParams"
	structFieldName_ScannerStopResponseParams_OutErr = "OutErr"
)

func discovery_Scanner_Stop_ResponseParams__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &structName_ScannerStopResponseParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_ScannerStopResponseParams_OutErr,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
					TypeKey: &ID_discovery_Error__},
			},
		}},
	}
}

func (p *Scanner_Proxy) Stop(inH uint32) (outErr *Error, err error) {
	payload := &scanner_Stop_Params{
		inH,
	}
	header := bindings.MessageHeader{
		Type:      scanner_Stop_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, scanner_Stop_Name; got != want {
		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
		}
		return
	}
	var response scanner_Stop_ResponseParams
	if err = readResult.Message.DecodePayload(&response); err != nil {
		p.Close_Proxy()
		return
	}
	outErr = response.outErr
	return
}

type scanner_Stub struct {
	connector *bindings.Connector
	impl      Scanner
}

func NewScannerStub(r Scanner_Request, impl Scanner, waiter bindings.AsyncWaiter) *bindings.Stub {
	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
	return bindings.NewStub(connector, &scanner_Stub{connector, impl})
}

var (
	interfaceName_Scanner            = "Scanner"
	interfaceMethodName_Scanner_Scan = "Scan"
	interfaceMethodName_Scanner_Stop = "Stop"
)

func discovery_Scanner__() mojom_types.MojomInterface {
	responseParamsMap := make(map[string]*mojom_types.MojomStruct)
	_ = responseParamsMap // To avoid the declared but unused compiler error
	mstruct_Scan := discovery_Scanner_Scan_ResponseParams__()
	responseParamsMap[interfaceMethodName_Scanner_Scan] = &mstruct_Scan
	mstruct_Stop := discovery_Scanner_Stop_ResponseParams__()
	responseParamsMap[interfaceMethodName_Scanner_Stop] = &mstruct_Stop
	return mojom_types.MojomInterface{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &interfaceName_Scanner,
		},
		Methods: map[uint32]mojom_types.MojomMethod{scanner_Scan_Name: mojom_types.MojomMethod{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &interfaceMethodName_Scanner_Scan,
			},
			Parameters:     discovery_Scanner_Scan_Params__(),
			ResponseParams: responseParamsMap[interfaceMethodName_Scanner_Scan],
		}, scanner_Stop_Name: mojom_types.MojomMethod{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &interfaceMethodName_Scanner_Stop,
			},
			Parameters:     discovery_Scanner_Stop_Params__(),
			ResponseParams: responseParamsMap[interfaceMethodName_Scanner_Stop],
		}},
	}
}

func (f *Scanner_Request) ServiceDescription() service_describer.ServiceDescription {
	return &Scanner_ServiceDescription{}
}

type Scanner_ServiceDescription struct{}

func (sd *Scanner_ServiceDescription) GetTopLevelInterface() (outMojomInterface mojom_types.MojomInterface, err error) {
	return discovery_Scanner__(), nil
}

func (sd *Scanner_ServiceDescription) GetTypeDefinition(inTypeKey string) (outType mojom_types.UserDefinedType, err error) {
	if udt, ok := GetAllMojomTypeDefinitions()[inTypeKey]; ok {
		return udt, nil
	}
	return nil, fmt.Errorf("%s_ServiceDescription does not recognize %s", "Scanner", inTypeKey)
}

func (sd *Scanner_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) {
	o := GetAllMojomTypeDefinitions()
	return &o, nil
}

var _ service_describer.ServiceDescription = (*Scanner_ServiceDescription)(nil)

func (s *scanner_Stub) Accept(message *bindings.Message) (err error) {
	switch message.Header.Type {
	case scanner_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 scanner_Scan_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		var response scanner_Scan_ResponseParams
		response.outHandle, response.outErr, err = s.impl.Scan(request.inQuery, request.inScanHandler)
		if err != nil {
			return
		}
		header := bindings.MessageHeader{
			Type:      scanner_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 scanner_Stop_Name:
		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
			}
		}
		var request scanner_Stop_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		var response scanner_Stop_ResponseParams
		response.outErr, err = s.impl.Stop(request.inH)
		if err != nil {
			return
		}
		header := bindings.MessageHeader{
			Type:      scanner_Stop_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 ScanHandler interface {
	Found(inService Service) (err error)
	Lost(inInstanceId string) (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) ServiceDescription() service_describer.ServiceDescription {
	return &ScanHandler_ServiceDescription{}
}

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 {
	inService 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.inService.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.inService.Decode(decoder); err != nil {
				return err
			}
		}
	}
	if err := decoder.Finish(); err != nil {
		return err
	}
	return nil
}

// String names and labels used by the MojomStruct types.
var (
	structName_ScanHandlerFoundParams                = "ScanHandlerFoundParams"
	structFieldName_ScanHandlerFoundParams_InService = "InService"
)

func discovery_ScanHandler_Found_Params__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &structName_ScanHandlerFoundParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_ScanHandlerFoundParams_InService,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Identifier: &ID_discovery_Service__,
					TypeKey: &ID_discovery_Service__},
			},
		}},
	}
}

func (p *ScanHandler_Proxy) Found(inService Service) (err error) {
	payload := &scanHandler_Found_Params{
		inService,
	}
	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 {
	inInstanceId string
}

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

// String names and labels used by the MojomStruct types.
var (
	structName_ScanHandlerLostParams                   = "ScanHandlerLostParams"
	structFieldName_ScanHandlerLostParams_InInstanceId = "InInstanceId"
)

func discovery_ScanHandler_Lost_Params__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &structName_ScanHandlerLostParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_ScanHandlerLostParams_InInstanceId,
			},
			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
		}},
	}
}

func (p *ScanHandler_Proxy) Lost(inInstanceId string) (err error) {
	payload := &scanHandler_Lost_Params{
		inInstanceId,
	}
	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})
}

var (
	interfaceName_ScanHandler             = "ScanHandler"
	interfaceMethodName_ScanHandler_Found = "Found"
	interfaceMethodName_ScanHandler_Lost  = "Lost"
)

func discovery_ScanHandler__() mojom_types.MojomInterface {
	responseParamsMap := make(map[string]*mojom_types.MojomStruct)
	_ = responseParamsMap // To avoid the declared but unused compiler error
	return mojom_types.MojomInterface{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &interfaceName_ScanHandler,
		},
		Methods: map[uint32]mojom_types.MojomMethod{scanHandler_Found_Name: mojom_types.MojomMethod{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &interfaceMethodName_ScanHandler_Found,
			},
			Parameters:     discovery_ScanHandler_Found_Params__(),
			ResponseParams: responseParamsMap[interfaceMethodName_ScanHandler_Found],
		}, scanHandler_Lost_Name: mojom_types.MojomMethod{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &interfaceMethodName_ScanHandler_Lost,
			},
			Parameters:     discovery_ScanHandler_Lost_Params__(),
			ResponseParams: responseParamsMap[interfaceMethodName_ScanHandler_Lost],
		}},
	}
}

func (f *ScanHandler_Request) ServiceDescription() service_describer.ServiceDescription {
	return &ScanHandler_ServiceDescription{}
}

type ScanHandler_ServiceDescription struct{}

func (sd *ScanHandler_ServiceDescription) GetTopLevelInterface() (outMojomInterface mojom_types.MojomInterface, err error) {
	return discovery_ScanHandler__(), nil
}

func (sd *ScanHandler_ServiceDescription) GetTypeDefinition(inTypeKey string) (outType mojom_types.UserDefinedType, err error) {
	if udt, ok := GetAllMojomTypeDefinitions()[inTypeKey]; ok {
		return udt, nil
	}
	return nil, fmt.Errorf("%s_ServiceDescription does not recognize %s", "ScanHandler", inTypeKey)
}

func (sd *ScanHandler_ServiceDescription) GetAllTypeDefinitions() (outDefinitions *map[string]mojom_types.UserDefinedType, err error) {
	o := GetAllMojomTypeDefinitions()
	return &o, nil
}

var _ service_describer.ServiceDescription = (*ScanHandler_ServiceDescription)(nil)

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.inService)
		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.inInstanceId)
		if err != nil {
			return
		}
	default:
		return &bindings.ValidationError{
			bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("unknown method %v", message.Header.Type),
		}
	}
	return
}

type Service struct {
	InstanceId    *string
	InstanceName  *string
	InterfaceName string
	Attrs         *map[string]string
	Addrs         []string
}

func (s *Service) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(40, 0)
	if s.InstanceId == nil {
		encoder.WriteNullPointer()
	} else {
		if err := encoder.WritePointer(); err != nil {
			return err
		}
		if err := encoder.WriteString((*s.InstanceId)); err != nil {
			return err
		}
	}
	if s.InstanceName == nil {
		encoder.WriteNullPointer()
	} else {
		if err := encoder.WritePointer(); err != nil {
			return err
		}
		if err := encoder.WriteString((*s.InstanceName)); err != nil {
			return err
		}
	}
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	if err := encoder.WriteString(s.InterfaceName); err != nil {
		return err
	}
	if s.Attrs == nil {
		encoder.WriteNullPointer()
	} else {
		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{48, 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 {
			s.InstanceId = nil
		} else {
			s.InstanceId = new(string)
			value0, err := decoder.ReadString()
			if err != nil {
				return err
			}
			(*s.InstanceId) = value0
		}
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			s.InstanceName = nil
		} else {
			s.InstanceName = new(string)
			value0, err := decoder.ReadString()
			if err != nil {
				return err
			}
			(*s.InstanceName) = 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.InterfaceName = value0
		}
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			s.Attrs = nil
		} else {
			s.Attrs = new(map[string]string)
			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
}

// String names and labels used by the MojomStruct types.
var (
	structName_Service                    = "Service"
	structFieldName_Service_InstanceId    = "InstanceId"
	structFieldName_Service_InstanceName  = "InstanceName"
	structFieldName_Service_InterfaceName = "InterfaceName"
	structFieldName_Service_Attrs         = "Attrs"
	structFieldName_Service_Addrs         = "Addrs"
)

func discovery_Service__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &structName_Service,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_Service_InstanceId,
			},
			Type: &mojom_types.TypeStringType{mojom_types.StringType{true}},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_Service_InstanceName,
			},
			Type: &mojom_types.TypeStringType{mojom_types.StringType{true}},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_Service_InterfaceName,
			},
			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_Service_Attrs,
			},
			Type: &mojom_types.TypeMapType{
				Value: mojom_types.MapType{Nullable: true, KeyType: &mojom_types.TypeStringType{mojom_types.StringType{false}},
					ValueType: &mojom_types.TypeStringType{mojom_types.StringType{false}},
				},
			},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_Service_Addrs,
			},
			Type: &mojom_types.TypeArrayType{
				Value: mojom_types.ArrayType{ElementType: &mojom_types.TypeStringType{mojom_types.StringType{false}}},
			},
		}},
	}
}

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
}

// String names and labels used by the MojomStruct types.
var (
	structName_Error             = "Error"
	structFieldName_Error_Id     = "Id"
	structFieldName_Error_Action = "Action"
	structFieldName_Error_Msg    = "Msg"
)

func discovery_Error__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName: &structName_Error,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_Error_Id,
			},
			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_Error_Action,
			},
			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_InT32},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_Error_Msg,
			},
			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
		}},
	}
}
