// 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 "fmt"
	bindings "mojo/public/go/bindings"
	system "mojo/public/go/system"
	mojom_types "mojo/public/interfaces/bindings/mojom_types"
	service_describer "mojo/public/interfaces/bindings/service_describer"
	sort "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_UpdateType__ string = "discovery_UpdateType__"
var ID_discovery_Service__ string = "discovery_Service__"
var ID_discovery_Update__ string = "discovery_Update__"
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_UpdateType__"] = &mojom_types.UserDefinedTypeEnumType{
		Value: discovery_UpdateType__(),
	}
	discoveryDesc__["discovery_Service__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Service__(),
	}

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

	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_Update_Params__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_ScanHandler_Update_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 UpdateType int32

const (
	UpdateType_Found = 1
	UpdateType_Lost  = UpdateType_Found + 1
)

// String names and labels used by the MojomEnum types.
var (
	enumName_UpdateType            = "UpdateType"
	enumFullIdentifier_UpdateType  = "discovery.UpdateType"
	enumFieldName_UpdateType_Found = "Found"
	enumFieldName_UpdateType_Lost  = "Lost"
)

func discovery_UpdateType__() mojom_types.MojomEnum {
	return mojom_types.MojomEnum{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &enumName_UpdateType,
			FullIdentifier: &enumFullIdentifier_UpdateType,
		},
		Values: []mojom_types.EnumValue{mojom_types.EnumValue{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &enumFieldName_UpdateType_Found,
			},
			EnumTypeKey: ID_discovery_UpdateType__,
			IntValue:    int32(1),
		}, mojom_types.EnumValue{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &enumFieldName_UpdateType_Lost,
			},
			EnumTypeKey: ID_discovery_UpdateType__,
			IntValue:    int32(2),
		}},
	}
}

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 = "v23::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"
	structFullIdentifier_AdvertiserAdvertiseParams         = "discovery.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,
			FullIdentifier: &structFullIdentifier_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"
	structFullIdentifier_AdvertiserAdvertiseResponseParams          = "discovery.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,
			FullIdentifier: &structFullIdentifier_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"
	structFullIdentifier_AdvertiserStopParams = "discovery.AdvertiserStopParams"
	structFieldName_AdvertiserStopParams_InH  = "InH"
)

func discovery_Advertiser_Stop_Params__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_AdvertiserStopParams,
			FullIdentifier: &structFullIdentifier_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"
	structFullIdentifier_AdvertiserStopResponseParams   = "discovery.AdvertiserStopResponseParams"
	structFieldName_AdvertiserStopResponseParams_OutErr = "OutErr"
)

func discovery_Advertiser_Stop_ResponseParams__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_AdvertiserStopResponseParams,
			FullIdentifier: &structFullIdentifier_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"
	interfaceFullIdentifier_Advertiser       = "discovery.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,
			FullIdentifier: &interfaceFullIdentifier_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 = "v23::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"
	structFullIdentifier_ScannerScanParams          = "discovery.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,
			FullIdentifier: &structFullIdentifier_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"
	structFullIdentifier_ScannerScanResponseParams      = "discovery.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,
			FullIdentifier: &structFullIdentifier_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"
	structFullIdentifier_ScannerStopParams = "discovery.ScannerStopParams"
	structFieldName_ScannerStopParams_InH  = "InH"
)

func discovery_Scanner_Stop_Params__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_ScannerStopParams,
			FullIdentifier: &structFullIdentifier_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"
	structFullIdentifier_ScannerStopResponseParams   = "discovery.ScannerStopResponseParams"
	structFieldName_ScannerStopResponseParams_OutErr = "OutErr"
)

func discovery_Scanner_Stop_ResponseParams__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_ScannerStopResponseParams,
			FullIdentifier: &structFullIdentifier_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"
	interfaceFullIdentifier_Scanner  = "discovery.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,
			FullIdentifier: &interfaceFullIdentifier_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 {
	Update(inUpdate Update) (err error)
}

var scanHandler_Name = "v23::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_Update_Name uint32 = 0

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_Update_Params struct {
	inUpdate Update
}

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

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

func (s *scanHandler_Update_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(scanHandler_Update_Params_Versions), func(i int) bool {
		return scanHandler_Update_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(scanHandler_Update_Params_Versions) {
		if scanHandler_Update_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := scanHandler_Update_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.inUpdate.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_ScanHandlerUpdateParams               = "ScanHandlerUpdateParams"
	structFullIdentifier_ScanHandlerUpdateParams     = "discovery.ScanHandlerUpdateParams"
	structFieldName_ScanHandlerUpdateParams_InUpdate = "InUpdate"
)

func discovery_ScanHandler_Update_Params__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_ScanHandlerUpdateParams,
			FullIdentifier: &structFullIdentifier_ScanHandlerUpdateParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_ScanHandlerUpdateParams_InUpdate,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Identifier: &ID_discovery_Update__,
					TypeKey: &ID_discovery_Update__},
			},
		}},
	}
}

func (p *ScanHandler_Proxy) Update(inUpdate Update) (err error) {
	payload := &scanHandler_Update_Params{
		inUpdate,
	}
	header := bindings.MessageHeader{
		Type:  scanHandler_Update_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"
	interfaceFullIdentifier_ScanHandler    = "discovery.ScanHandler"
	interfaceMethodName_ScanHandler_Update = "Update"
)

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,
			FullIdentifier: &interfaceFullIdentifier_ScanHandler,
		},
		Methods: map[uint32]mojom_types.MojomMethod{scanHandler_Update_Name: mojom_types.MojomMethod{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &interfaceMethodName_ScanHandler_Update,
			},
			Parameters:     discovery_ScanHandler_Update_Params__(),
			ResponseParams: responseParamsMap[interfaceMethodName_ScanHandler_Update],
		}},
	}
}

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_Update_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_Update_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		err = s.impl.Update(request.inUpdate)
		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"
	structFullIdentifier_Service          = "discovery.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,
			FullIdentifier: &structFullIdentifier_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 Update struct {
	Service    Service
	UpdateType UpdateType
}

func (s *Update) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(16, 0)
	if err := encoder.WritePointer(); err != nil {
		return err
	}
	if err := s.Service.Encode(encoder); err != nil {
		return err
	}
	if err := encoder.WriteInt32(int32(s.UpdateType)); err != nil {
		return err
	}
	if err := encoder.Finish(); err != nil {
		return err
	}
	return nil
}

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

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

// String names and labels used by the MojomStruct types.
var (
	structName_Update                 = "Update"
	structFullIdentifier_Update       = "discovery.Update"
	structFieldName_Update_Service    = "Service"
	structFieldName_Update_UpdateType = "UpdateType"
)

func discovery_Update__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_Update,
			FullIdentifier: &structFullIdentifier_Update,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_Update_Service,
			},
			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_Update_UpdateType,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Identifier: &ID_discovery_UpdateType__,
					TypeKey: &ID_discovery_UpdateType__},
			},
		}},
	}
}

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"
	structFullIdentifier_Error   = "discovery.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,
			FullIdentifier: &structFullIdentifier_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}},
		}},
	}
}
