// 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_Discovery__ string = "discovery_Discovery__"
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_Discovery__"] = &mojom_types.UserDefinedTypeInterfaceType{
		Value: discovery_Discovery__(),
	}
	discoveryDesc__["discovery_Discovery_StartAdvertising_Params__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Discovery_StartAdvertising_Params__(),
	}

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

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

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

	discoveryDesc__["discovery_Discovery_StartScan_Params__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Discovery_StartScan_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_Discovery_StartScan_ResponseParams__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Discovery_StartScan_ResponseParams__(),
	}

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

	discoveryDesc__["discovery_Discovery_StopScan_ResponseParams__"] = &mojom_types.UserDefinedTypeStructType{
		Value: discovery_Discovery_StopScan_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 Discovery interface {
	StartAdvertising(inService Service, inVisibility *[]string) (outInstanceId string, outErr *Error, err error)
	StopAdvertising(inInstanceId string) (outErr *Error, err error)
	StartScan(inQuery string, inHandler ScanHandler_Pointer) (outScanId uint32, outErr *Error, err error)
	StopScan(inScanId uint32) (outErr *Error, err error)
}

var discovery_Name = "v23::discovery::Discovery"

type Discovery_Request bindings.InterfaceRequest

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

type Discovery_Pointer bindings.InterfacePointer

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

type Discovery_ServiceFactory struct {
	Delegate Discovery_Factory
}

type Discovery_Factory interface {
	Create(request Discovery_Request)
}

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

func (f *Discovery_ServiceFactory) ServiceDescription() service_describer.ServiceDescription {
	return &Discovery_ServiceDescription{}
}

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

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

const discovery_StartAdvertising_Name uint32 = 0
const discovery_StopAdvertising_Name uint32 = 1
const discovery_StartScan_Name uint32 = 2
const discovery_StopScan_Name uint32 = 3

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

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

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

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

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

func (s *discovery_StartAdvertising_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discovery_StartAdvertising_Params_Versions), func(i int) bool {
		return discovery_StartAdvertising_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discovery_StartAdvertising_Params_Versions) {
		if discovery_StartAdvertising_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discovery_StartAdvertising_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_DiscoveryStartAdvertisingParams                   = "DiscoveryStartAdvertisingParams"
	structFullIdentifier_DiscoveryStartAdvertisingParams         = "discovery.DiscoveryStartAdvertisingParams"
	structFieldName_DiscoveryStartAdvertisingParams_InService    = "InService"
	structFieldName_DiscoveryStartAdvertisingParams_InVisibility = "InVisibility"
)

func discovery_Discovery_StartAdvertising_Params__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_DiscoveryStartAdvertisingParams,
			FullIdentifier: &structFullIdentifier_DiscoveryStartAdvertisingParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_DiscoveryStartAdvertisingParams_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_DiscoveryStartAdvertisingParams_InVisibility,
			},
			Type: &mojom_types.TypeArrayType{
				Value: mojom_types.ArrayType{Nullable: true, ElementType: &mojom_types.TypeStringType{mojom_types.StringType{false}}},
			},
		}},
	}
}

type discovery_StartAdvertising_ResponseParams struct {
	outInstanceId string
	outErr        *Error
}

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

func (s *discovery_StartAdvertising_ResponseParams) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discovery_StartAdvertising_ResponseParams_Versions), func(i int) bool {
		return discovery_StartAdvertising_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discovery_StartAdvertising_ResponseParams_Versions) {
		if discovery_StartAdvertising_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discovery_StartAdvertising_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 {
			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_DiscoveryStartAdvertisingResponseParams                    = "DiscoveryStartAdvertisingResponseParams"
	structFullIdentifier_DiscoveryStartAdvertisingResponseParams          = "discovery.DiscoveryStartAdvertisingResponseParams"
	structFieldName_DiscoveryStartAdvertisingResponseParams_OutInstanceId = "OutInstanceId"
	structFieldName_DiscoveryStartAdvertisingResponseParams_OutErr        = "OutErr"
)

func discovery_Discovery_StartAdvertising_ResponseParams__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_DiscoveryStartAdvertisingResponseParams,
			FullIdentifier: &structFullIdentifier_DiscoveryStartAdvertisingResponseParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_DiscoveryStartAdvertisingResponseParams_OutInstanceId,
			},
			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_DiscoveryStartAdvertisingResponseParams_OutErr,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
					TypeKey: &ID_discovery_Error__},
			},
		}},
	}
}

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

type discovery_StopAdvertising_Params struct {
	inInstanceId string
}

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

func (s *discovery_StopAdvertising_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discovery_StopAdvertising_Params_Versions), func(i int) bool {
		return discovery_StopAdvertising_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discovery_StopAdvertising_Params_Versions) {
		if discovery_StopAdvertising_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discovery_StopAdvertising_Params_Versions[index].Size
		if expectedSize != header.Size {
			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		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_DiscoveryStopAdvertisingParams                   = "DiscoveryStopAdvertisingParams"
	structFullIdentifier_DiscoveryStopAdvertisingParams         = "discovery.DiscoveryStopAdvertisingParams"
	structFieldName_DiscoveryStopAdvertisingParams_InInstanceId = "InInstanceId"
)

func discovery_Discovery_StopAdvertising_Params__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_DiscoveryStopAdvertisingParams,
			FullIdentifier: &structFullIdentifier_DiscoveryStopAdvertisingParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_DiscoveryStopAdvertisingParams_InInstanceId,
			},
			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
		}},
	}
}

type discovery_StopAdvertising_ResponseParams struct {
	outErr *Error
}

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

func (s *discovery_StopAdvertising_ResponseParams) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discovery_StopAdvertising_ResponseParams_Versions), func(i int) bool {
		return discovery_StopAdvertising_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discovery_StopAdvertising_ResponseParams_Versions) {
		if discovery_StopAdvertising_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discovery_StopAdvertising_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_DiscoveryStopAdvertisingResponseParams             = "DiscoveryStopAdvertisingResponseParams"
	structFullIdentifier_DiscoveryStopAdvertisingResponseParams   = "discovery.DiscoveryStopAdvertisingResponseParams"
	structFieldName_DiscoveryStopAdvertisingResponseParams_OutErr = "OutErr"
)

func discovery_Discovery_StopAdvertising_ResponseParams__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_DiscoveryStopAdvertisingResponseParams,
			FullIdentifier: &structFullIdentifier_DiscoveryStopAdvertisingResponseParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_DiscoveryStopAdvertisingResponseParams_OutErr,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
					TypeKey: &ID_discovery_Error__},
			},
		}},
	}
}

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

type discovery_StartScan_Params struct {
	inQuery   string
	inHandler ScanHandler_Pointer
}

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

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

func (s *discovery_StartScan_Params) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discovery_StartScan_Params_Versions), func(i int) bool {
		return discovery_StartScan_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discovery_StartScan_Params_Versions) {
		if discovery_StartScan_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discovery_StartScan_Params_Versions[index].Size
		if expectedSize != header.Size {
			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
			}
		}
	}
	if header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			return &bindings.ValidationError{bindings.UnexpectedNullPointer, "unexpected null pointer"}
		} else {
			value0, err := decoder.ReadString()
			if err != nil {
				return err
			}
			s.inQuery = value0
		}
	}
	if header.ElementsOrVersion >= 0 {
		handle0, err := decoder.ReadInterface()
		if err != nil {
			return err
		}
		if handle0.IsValid() {
			handleOwner := bindings.NewMessagePipeHandleOwner(handle0)
			s.inHandler = 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_DiscoveryStartScanParams                = "DiscoveryStartScanParams"
	structFullIdentifier_DiscoveryStartScanParams      = "discovery.DiscoveryStartScanParams"
	structFieldName_DiscoveryStartScanParams_InQuery   = "InQuery"
	structFieldName_DiscoveryStartScanParams_InHandler = "InHandler"
)

func discovery_Discovery_StartScan_Params__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_DiscoveryStartScanParams,
			FullIdentifier: &structFullIdentifier_DiscoveryStartScanParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_DiscoveryStartScanParams_InQuery,
			},
			Type: &mojom_types.TypeStringType{mojom_types.StringType{false}},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_DiscoveryStartScanParams_InHandler,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Identifier: &ID_discovery_ScanHandler__,
					TypeKey: &ID_discovery_ScanHandler__},
			},
		}},
	}
}

type discovery_StartScan_ResponseParams struct {
	outScanId uint32
	outErr    *Error
}

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

func (s *discovery_StartScan_ResponseParams) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discovery_StartScan_ResponseParams_Versions), func(i int) bool {
		return discovery_StartScan_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discovery_StartScan_ResponseParams_Versions) {
		if discovery_StartScan_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discovery_StartScan_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.outScanId = 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_DiscoveryStartScanResponseParams                = "DiscoveryStartScanResponseParams"
	structFullIdentifier_DiscoveryStartScanResponseParams      = "discovery.DiscoveryStartScanResponseParams"
	structFieldName_DiscoveryStartScanResponseParams_OutScanId = "OutScanId"
	structFieldName_DiscoveryStartScanResponseParams_OutErr    = "OutErr"
)

func discovery_Discovery_StartScan_ResponseParams__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_DiscoveryStartScanResponseParams,
			FullIdentifier: &structFullIdentifier_DiscoveryStartScanResponseParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_DiscoveryStartScanResponseParams_OutScanId,
			},
			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT32},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_DiscoveryStartScanResponseParams_OutErr,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
					TypeKey: &ID_discovery_Error__},
			},
		}},
	}
}

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

type discovery_StopScan_Params struct {
	inScanId uint32
}

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

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

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

// String names and labels used by the MojomStruct types.
var (
	structName_DiscoveryStopScanParams               = "DiscoveryStopScanParams"
	structFullIdentifier_DiscoveryStopScanParams     = "discovery.DiscoveryStopScanParams"
	structFieldName_DiscoveryStopScanParams_InScanId = "InScanId"
)

func discovery_Discovery_StopScan_Params__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_DiscoveryStopScanParams,
			FullIdentifier: &structFullIdentifier_DiscoveryStopScanParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_DiscoveryStopScanParams_InScanId,
			},
			Type: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT32},
		}},
	}
}

type discovery_StopScan_ResponseParams struct {
	outErr *Error
}

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

func (s *discovery_StopScan_ResponseParams) Decode(decoder *bindings.Decoder) error {
	header, err := decoder.StartStruct()
	if err != nil {
		return err
	}
	index := sort.Search(len(discovery_StopScan_ResponseParams_Versions), func(i int) bool {
		return discovery_StopScan_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
	})
	if index < len(discovery_StopScan_ResponseParams_Versions) {
		if discovery_StopScan_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
			index--
		}
		expectedSize := discovery_StopScan_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_DiscoveryStopScanResponseParams             = "DiscoveryStopScanResponseParams"
	structFullIdentifier_DiscoveryStopScanResponseParams   = "discovery.DiscoveryStopScanResponseParams"
	structFieldName_DiscoveryStopScanResponseParams_OutErr = "OutErr"
)

func discovery_Discovery_StopScan_ResponseParams__() mojom_types.MojomStruct {
	return mojom_types.MojomStruct{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &structName_DiscoveryStopScanResponseParams,
			FullIdentifier: &structFullIdentifier_DiscoveryStopScanResponseParams,
		}, Fields: []mojom_types.StructField{mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_DiscoveryStopScanResponseParams_OutErr,
			},
			Type: &mojom_types.TypeTypeReference{
				Value: mojom_types.TypeReference{Nullable: true, Identifier: &ID_discovery_Error__,
					TypeKey: &ID_discovery_Error__},
			},
		}},
	}
}

func (p *Discovery_Proxy) StopScan(inScanId uint32) (outErr *Error, err error) {
	payload := &discovery_StopScan_Params{
		inScanId,
	}
	header := bindings.MessageHeader{
		Type:      discovery_StopScan_Name,
		Flags:     bindings.MessageExpectsResponseFlag,
		RequestId: p.ids.Count(),
	}
	var message *bindings.Message
	if message, err = bindings.EncodeMessage(header, payload); err != nil {
		err = fmt.Errorf("can't encode request: %v", err.Error())
		p.Close_Proxy()
		return
	}
	readResult := <-p.router.AcceptWithResponse(message)
	if err = readResult.Error; err != nil {
		p.Close_Proxy()
		return
	}
	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
		}
		return
	}
	if got, want := readResult.Message.Header.Type, discovery_StopScan_Name; got != want {
		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
		}
		return
	}
	var response discovery_StopScan_ResponseParams
	if err = readResult.Message.DecodePayload(&response); err != nil {
		p.Close_Proxy()
		return
	}
	outErr = response.outErr
	return
}

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

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

var (
	interfaceName_Discovery                        = "Discovery"
	interfaceFullIdentifier_Discovery              = "discovery.Discovery"
	interfaceMethodName_Discovery_StartAdvertising = "StartAdvertising"
	interfaceMethodName_Discovery_StopAdvertising  = "StopAdvertising"
	interfaceMethodName_Discovery_StartScan        = "StartScan"
	interfaceMethodName_Discovery_StopScan         = "StopScan"
)

func discovery_Discovery__() mojom_types.MojomInterface {
	responseParamsMap := make(map[string]*mojom_types.MojomStruct)
	_ = responseParamsMap // To avoid the declared but unused compiler error
	mstruct_StartAdvertising := discovery_Discovery_StartAdvertising_ResponseParams__()
	responseParamsMap[interfaceMethodName_Discovery_StartAdvertising] = &mstruct_StartAdvertising
	mstruct_StopAdvertising := discovery_Discovery_StopAdvertising_ResponseParams__()
	responseParamsMap[interfaceMethodName_Discovery_StopAdvertising] = &mstruct_StopAdvertising
	mstruct_StartScan := discovery_Discovery_StartScan_ResponseParams__()
	responseParamsMap[interfaceMethodName_Discovery_StartScan] = &mstruct_StartScan
	mstruct_StopScan := discovery_Discovery_StopScan_ResponseParams__()
	responseParamsMap[interfaceMethodName_Discovery_StopScan] = &mstruct_StopScan
	return mojom_types.MojomInterface{
		DeclData: &mojom_types.DeclarationData{
			ShortName:      &interfaceName_Discovery,
			FullIdentifier: &interfaceFullIdentifier_Discovery,
		},
		Methods: map[uint32]mojom_types.MojomMethod{discovery_StartAdvertising_Name: mojom_types.MojomMethod{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &interfaceMethodName_Discovery_StartAdvertising,
			},
			Parameters:     discovery_Discovery_StartAdvertising_Params__(),
			ResponseParams: responseParamsMap[interfaceMethodName_Discovery_StartAdvertising],
		}, discovery_StopAdvertising_Name: mojom_types.MojomMethod{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &interfaceMethodName_Discovery_StopAdvertising,
			},
			Parameters:     discovery_Discovery_StopAdvertising_Params__(),
			ResponseParams: responseParamsMap[interfaceMethodName_Discovery_StopAdvertising],
		}, discovery_StartScan_Name: mojom_types.MojomMethod{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &interfaceMethodName_Discovery_StartScan,
			},
			Parameters:     discovery_Discovery_StartScan_Params__(),
			ResponseParams: responseParamsMap[interfaceMethodName_Discovery_StartScan],
		}, discovery_StopScan_Name: mojom_types.MojomMethod{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &interfaceMethodName_Discovery_StopScan,
			},
			Parameters:     discovery_Discovery_StopScan_Params__(),
			ResponseParams: responseParamsMap[interfaceMethodName_Discovery_StopScan],
		}},
	}
}

func (f *Discovery_Request) ServiceDescription() service_describer.ServiceDescription {
	return &Discovery_ServiceDescription{}
}

type Discovery_ServiceDescription struct{}

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

func (sd *Discovery_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", "Discovery", inTypeKey)
}

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

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

func (s *discovery_Stub) Accept(message *bindings.Message) (err error) {
	switch message.Header.Type {
	case discovery_StartAdvertising_Name:
		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
			}
		}
		var request discovery_StartAdvertising_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		var response discovery_StartAdvertising_ResponseParams
		response.outInstanceId, response.outErr, err = s.impl.StartAdvertising(request.inService, request.inVisibility)
		if err != nil {
			return
		}
		header := bindings.MessageHeader{
			Type:      discovery_StartAdvertising_Name,
			Flags:     bindings.MessageIsResponseFlag,
			RequestId: message.Header.RequestId,
		}
		message, err = bindings.EncodeMessage(header, &response)
		if err != nil {
			return err
		}
		return s.connector.WriteMessage(message)
	case discovery_StopAdvertising_Name:
		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
			}
		}
		var request discovery_StopAdvertising_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		var response discovery_StopAdvertising_ResponseParams
		response.outErr, err = s.impl.StopAdvertising(request.inInstanceId)
		if err != nil {
			return
		}
		header := bindings.MessageHeader{
			Type:      discovery_StopAdvertising_Name,
			Flags:     bindings.MessageIsResponseFlag,
			RequestId: message.Header.RequestId,
		}
		message, err = bindings.EncodeMessage(header, &response)
		if err != nil {
			return err
		}
		return s.connector.WriteMessage(message)
	case discovery_StartScan_Name:
		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
			}
		}
		var request discovery_StartScan_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		var response discovery_StartScan_ResponseParams
		response.outScanId, response.outErr, err = s.impl.StartScan(request.inQuery, request.inHandler)
		if err != nil {
			return
		}
		header := bindings.MessageHeader{
			Type:      discovery_StartScan_Name,
			Flags:     bindings.MessageIsResponseFlag,
			RequestId: message.Header.RequestId,
		}
		message, err = bindings.EncodeMessage(header, &response)
		if err != nil {
			return err
		}
		return s.connector.WriteMessage(message)
	case discovery_StopScan_Name:
		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
			}
		}
		var request discovery_StopScan_Params
		if err := message.DecodePayload(&request); err != nil {
			return err
		}
		var response discovery_StopScan_ResponseParams
		response.outErr, err = s.impl.StopScan(request.inScanId)
		if err != nil {
			return
		}
		header := bindings.MessageHeader{
			Type:      discovery_StopScan_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
	Attachments   *map[string][]uint8
}

func (s *Service) Encode(encoder *bindings.Encoder) error {
	encoder.StartStruct(48, 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 s.Attachments == nil {
		encoder.WriteNullPointer()
	} else {
		if err := encoder.WritePointer(); err != nil {
			return err
		}
		encoder.StartMap()
		{
			var keys0 []string
			var values0 [][]uint8
			for key0, value0 := range *s.Attachments {
				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
				}
				encoder.StartArray(uint32(len(elem1)), 8)
				for _, elem2 := range elem1 {
					if err := encoder.WriteUint8(elem2); err != nil {
						return err
					}
				}
				if err := encoder.Finish(); err != nil {
					return err
				}
			}
			if err := encoder.Finish(); 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{56, 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 header.ElementsOrVersion >= 0 {
		pointer0, err := decoder.ReadPointer()
		if err != nil {
			return err
		}
		if pointer0 == 0 {
			s.Attachments = nil
		} else {
			s.Attachments = new(map[string][]uint8)
			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 [][]uint8
			{
				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([][]uint8, 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 {
							len2, err := decoder.StartArray(8)
							if err != nil {
								return err
							}
							values0[i1] = make([]uint8, len2)
							for i2 := uint32(0); i2 < len2; i2++ {
								value3, err := decoder.ReadUint8()
								if err != nil {
									return err
								}
								values0[i1][i2] = value3
							}
							if err := decoder.Finish(); err != nil {
								return err
							}
						}
					}
					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][]uint8)
			for i0 := 0; i0 < len0; i0++ {
				map0[keys0[i0]] = values0[i0]
			}
			(*s.Attachments) = map0
		}
	}
	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"
	structFieldName_Service_Attachments   = "Attachments"
)

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}}},
			},
		}, mojom_types.StructField{
			DeclData: &mojom_types.DeclarationData{
				ShortName: &structFieldName_Service_Attachments,
			},
			Type: &mojom_types.TypeMapType{
				Value: mojom_types.MapType{Nullable: true, KeyType: &mojom_types.TypeStringType{mojom_types.StringType{false}},
					ValueType: &mojom_types.TypeArrayType{
						Value: mojom_types.ArrayType{ElementType: &mojom_types.TypeSimpleType{mojom_types.SimpleType_UinT8}},
					},
				},
			},
		}},
	}
}

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}},
		}},
	}
}
