// This file was auto-generated by the veyron vdl tool.
// Source: repository.vdl

// Package repository contains implementation of the interface for
// storing and serving various veyron management objects.
package repository

import (
	"veyron.io/veyron/veyron/services/mgmt/profile"

	"veyron.io/veyron/veyron2/security"

	"veyron.io/veyron/veyron2/services/mgmt/application"

	"veyron.io/veyron/veyron2/services/mgmt/repository"

	// The non-user imports are prefixed with "__" to prevent collisions.
	__veyron2 "veyron.io/veyron/veyron2"
	__context "veyron.io/veyron/veyron2/context"
	__ipc "veyron.io/veyron/veyron2/ipc"
	__vdlutil "veyron.io/veyron/veyron2/vdl/vdlutil"
	__wiretype "veyron.io/veyron/veyron2/wiretype"
)

// TODO(toddw): Remove this line once the new signature support is done.
// It corrects a bug where __wiretype is unused in VDL pacakges where only
// bootstrap types are used on interfaces.
const _ = __wiretype.TypeIDInvalid

// ApplicationClientMethods is the client interface
// containing Application methods.
//
// Application describes an application repository internally. Besides
// the public Application interface, it allows to add and remove
// application envelopes.
type ApplicationClientMethods interface {
	// Application provides access to application envelopes. An
	// application envelope is identified by an application name and an
	// application version, which are specified through the object name,
	// and a profile name, which is specified using a method argument.
	//
	// Example:
	// /apps/search/v1.Match([]string{"base", "media"})
	//   returns an application envelope that can be used for downloading
	//   and executing the "search" application, version "v1", runnable
	//   on either the "base" or "media" profile.
	repository.ApplicationClientMethods
	// Put adds the given tuple of application version (specified
	// through the object name suffix) and application envelope to all
	// of the given application profiles.
	Put(ctx __context.T, Profiles []string, Envelope application.Envelope, opts ...__ipc.CallOpt) error
	// Remove removes the application envelope for the given profile
	// name and application version (specified through the object name
	// suffix). If no version is specified as part of the suffix, the
	// method removes all versions for the given profile.
	//
	// TODO(jsimsa): Add support for using "*" to specify all profiles
	// when Matt implements Globing (or Ken implements querying).
	Remove(ctx __context.T, Profile string, opts ...__ipc.CallOpt) error
}

// ApplicationClientStub adds universal methods to ApplicationClientMethods.
type ApplicationClientStub interface {
	ApplicationClientMethods
	__ipc.UniversalServiceMethods
}

// ApplicationClient returns a client stub for Application.
func ApplicationClient(name string, opts ...__ipc.BindOpt) ApplicationClientStub {
	var client __ipc.Client
	for _, opt := range opts {
		if clientOpt, ok := opt.(__ipc.Client); ok {
			client = clientOpt
		}
	}
	return implApplicationClientStub{name, client, repository.ApplicationClient(name, client)}
}

type implApplicationClientStub struct {
	name   string
	client __ipc.Client

	repository.ApplicationClientStub
}

func (c implApplicationClientStub) c(ctx __context.T) __ipc.Client {
	if c.client != nil {
		return c.client
	}
	return __veyron2.RuntimeFromContext(ctx).Client()
}

func (c implApplicationClientStub) Put(ctx __context.T, i0 []string, i1 application.Envelope, opts ...__ipc.CallOpt) (err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "Put", []interface{}{i0, i1}, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&err); ierr != nil {
		err = ierr
	}
	return
}

func (c implApplicationClientStub) Remove(ctx __context.T, i0 string, opts ...__ipc.CallOpt) (err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "Remove", []interface{}{i0}, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&err); ierr != nil {
		err = ierr
	}
	return
}

func (c implApplicationClientStub) Signature(ctx __context.T, opts ...__ipc.CallOpt) (o0 __ipc.ServiceSignature, err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "Signature", nil, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&o0, &err); ierr != nil {
		err = ierr
	}
	return
}

func (c implApplicationClientStub) GetMethodTags(ctx __context.T, method string, opts ...__ipc.CallOpt) (o0 []interface{}, err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&o0, &err); ierr != nil {
		err = ierr
	}
	return
}

// ApplicationServerMethods is the interface a server writer
// implements for Application.
//
// Application describes an application repository internally. Besides
// the public Application interface, it allows to add and remove
// application envelopes.
type ApplicationServerMethods interface {
	// Application provides access to application envelopes. An
	// application envelope is identified by an application name and an
	// application version, which are specified through the object name,
	// and a profile name, which is specified using a method argument.
	//
	// Example:
	// /apps/search/v1.Match([]string{"base", "media"})
	//   returns an application envelope that can be used for downloading
	//   and executing the "search" application, version "v1", runnable
	//   on either the "base" or "media" profile.
	repository.ApplicationServerMethods
	// Put adds the given tuple of application version (specified
	// through the object name suffix) and application envelope to all
	// of the given application profiles.
	Put(ctx __ipc.ServerContext, Profiles []string, Envelope application.Envelope) error
	// Remove removes the application envelope for the given profile
	// name and application version (specified through the object name
	// suffix). If no version is specified as part of the suffix, the
	// method removes all versions for the given profile.
	//
	// TODO(jsimsa): Add support for using "*" to specify all profiles
	// when Matt implements Globing (or Ken implements querying).
	Remove(ctx __ipc.ServerContext, Profile string) error
}

// ApplicationServerStubMethods is the server interface containing
// Application methods, as expected by ipc.Server.  The difference between
// this interface and ApplicationServerMethods is that the first context
// argument for each method is always ipc.ServerCall here, while it is either
// ipc.ServerContext or a typed streaming context there.
type ApplicationServerStubMethods interface {
	// Application provides access to application envelopes. An
	// application envelope is identified by an application name and an
	// application version, which are specified through the object name,
	// and a profile name, which is specified using a method argument.
	//
	// Example:
	// /apps/search/v1.Match([]string{"base", "media"})
	//   returns an application envelope that can be used for downloading
	//   and executing the "search" application, version "v1", runnable
	//   on either the "base" or "media" profile.
	repository.ApplicationServerStubMethods
	// Put adds the given tuple of application version (specified
	// through the object name suffix) and application envelope to all
	// of the given application profiles.
	Put(call __ipc.ServerCall, Profiles []string, Envelope application.Envelope) error
	// Remove removes the application envelope for the given profile
	// name and application version (specified through the object name
	// suffix). If no version is specified as part of the suffix, the
	// method removes all versions for the given profile.
	//
	// TODO(jsimsa): Add support for using "*" to specify all profiles
	// when Matt implements Globing (or Ken implements querying).
	Remove(call __ipc.ServerCall, Profile string) error
}

// ApplicationServerStub adds universal methods to ApplicationServerStubMethods.
type ApplicationServerStub interface {
	ApplicationServerStubMethods
	// GetMethodTags will be replaced with DescribeInterfaces.
	GetMethodTags(call __ipc.ServerCall, method string) ([]interface{}, error)
	// Signature will be replaced with DescribeInterfaces.
	Signature(call __ipc.ServerCall) (__ipc.ServiceSignature, error)
}

// ApplicationServer returns a server stub for Application.
// It converts an implementation of ApplicationServerMethods into
// an object that may be used by ipc.Server.
func ApplicationServer(impl ApplicationServerMethods) ApplicationServerStub {
	stub := implApplicationServerStub{
		impl: impl,
		ApplicationServerStub: repository.ApplicationServer(impl),
	}
	// Initialize GlobState; always check the stub itself first, to handle the
	// case where the user has the Glob method defined in their VDL source.
	if gs := __ipc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := __ipc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type implApplicationServerStub struct {
	impl ApplicationServerMethods
	gs   *__ipc.GlobState

	repository.ApplicationServerStub
}

func (s implApplicationServerStub) Put(call __ipc.ServerCall, i0 []string, i1 application.Envelope) error {
	return s.impl.Put(call, i0, i1)
}

func (s implApplicationServerStub) Remove(call __ipc.ServerCall, i0 string) error {
	return s.impl.Remove(call, i0)
}

func (s implApplicationServerStub) VGlob() *__ipc.GlobState {
	return s.gs
}

func (s implApplicationServerStub) GetMethodTags(call __ipc.ServerCall, method string) ([]interface{}, error) {
	// TODO(toddw): Replace with new DescribeInterfaces implementation.
	if resp, err := s.ApplicationServerStub.GetMethodTags(call, method); resp != nil || err != nil {
		return resp, err
	}
	switch method {
	case "Put":
		return []interface{}{security.Label(4)}, nil
	case "Remove":
		return []interface{}{security.Label(4)}, nil
	default:
		return nil, nil
	}
}

func (s implApplicationServerStub) Signature(call __ipc.ServerCall) (__ipc.ServiceSignature, error) {
	// TODO(toddw) Replace with new DescribeInterfaces implementation.
	result := __ipc.ServiceSignature{Methods: make(map[string]__ipc.MethodSignature)}
	result.Methods["Put"] = __ipc.MethodSignature{
		InArgs: []__ipc.MethodArgument{
			{Name: "Profiles", Type: 61},
			{Name: "Envelope", Type: 65},
		},
		OutArgs: []__ipc.MethodArgument{
			{Name: "", Type: 66},
		},
	}
	result.Methods["Remove"] = __ipc.MethodSignature{
		InArgs: []__ipc.MethodArgument{
			{Name: "Profile", Type: 3},
		},
		OutArgs: []__ipc.MethodArgument{
			{Name: "", Type: 66},
		},
	}

	result.TypeDefs = []__vdlutil.Any{
		__wiretype.StructType{
			[]__wiretype.FieldType{
				__wiretype.FieldType{Type: 0x3, Name: "Title"},
				__wiretype.FieldType{Type: 0x3d, Name: "Args"},
				__wiretype.FieldType{Type: 0x3, Name: "Binary"},
				__wiretype.FieldType{Type: 0x3d, Name: "Env"},
			},
			"veyron.io/veyron/veyron2/services/mgmt/application.Envelope", []string(nil)},
		__wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
	var ss __ipc.ServiceSignature
	var firstAdded int
	ss, _ = s.ApplicationServerStub.Signature(call)
	firstAdded = len(result.TypeDefs)
	for k, v := range ss.Methods {
		for i, _ := range v.InArgs {
			if v.InArgs[i].Type >= __wiretype.TypeIDFirst {
				v.InArgs[i].Type += __wiretype.TypeID(firstAdded)
			}
		}
		for i, _ := range v.OutArgs {
			if v.OutArgs[i].Type >= __wiretype.TypeIDFirst {
				v.OutArgs[i].Type += __wiretype.TypeID(firstAdded)
			}
		}
		if v.InStream >= __wiretype.TypeIDFirst {
			v.InStream += __wiretype.TypeID(firstAdded)
		}
		if v.OutStream >= __wiretype.TypeIDFirst {
			v.OutStream += __wiretype.TypeID(firstAdded)
		}
		result.Methods[k] = v
	}
	//TODO(bprosnitz) combine type definitions from embeded interfaces in a way that doesn't cause duplication.
	for _, d := range ss.TypeDefs {
		switch wt := d.(type) {
		case __wiretype.SliceType:
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.ArrayType:
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.MapType:
			if wt.Key >= __wiretype.TypeIDFirst {
				wt.Key += __wiretype.TypeID(firstAdded)
			}
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.StructType:
			for i, fld := range wt.Fields {
				if fld.Type >= __wiretype.TypeIDFirst {
					wt.Fields[i].Type += __wiretype.TypeID(firstAdded)
				}
			}
			d = wt
			// NOTE: other types are missing, but we are upgrading anyways.
		}
		result.TypeDefs = append(result.TypeDefs, d)
	}

	return result, nil
}

// ProfileClientMethods is the client interface
// containing Profile methods.
//
// Profile describes a profile internally. Besides the public Profile
// interface, it allows to add and remove profile specifications.
type ProfileClientMethods interface {
	// Profile abstracts a device's ability to run binaries, and hides
	// specifics such as the operating system, hardware architecture, and
	// the set of installed libraries. Profiles describe binaries and
	// devices, and are used to match them.
	repository.ProfileClientMethods
	// Specification returns the profile specification for the profile
	// identified through the object name suffix.
	Specification(__context.T, ...__ipc.CallOpt) (profile.Specification, error)
	// Put sets the profile specification for the profile identified
	// through the object name suffix.
	Put(ctx __context.T, Specification profile.Specification, opts ...__ipc.CallOpt) error
	// Remove removes the profile specification for the profile
	// identified through the object name suffix.
	Remove(__context.T, ...__ipc.CallOpt) error
}

// ProfileClientStub adds universal methods to ProfileClientMethods.
type ProfileClientStub interface {
	ProfileClientMethods
	__ipc.UniversalServiceMethods
}

// ProfileClient returns a client stub for Profile.
func ProfileClient(name string, opts ...__ipc.BindOpt) ProfileClientStub {
	var client __ipc.Client
	for _, opt := range opts {
		if clientOpt, ok := opt.(__ipc.Client); ok {
			client = clientOpt
		}
	}
	return implProfileClientStub{name, client, repository.ProfileClient(name, client)}
}

type implProfileClientStub struct {
	name   string
	client __ipc.Client

	repository.ProfileClientStub
}

func (c implProfileClientStub) c(ctx __context.T) __ipc.Client {
	if c.client != nil {
		return c.client
	}
	return __veyron2.RuntimeFromContext(ctx).Client()
}

func (c implProfileClientStub) Specification(ctx __context.T, opts ...__ipc.CallOpt) (o0 profile.Specification, err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "Specification", nil, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&o0, &err); ierr != nil {
		err = ierr
	}
	return
}

func (c implProfileClientStub) Put(ctx __context.T, i0 profile.Specification, opts ...__ipc.CallOpt) (err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "Put", []interface{}{i0}, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&err); ierr != nil {
		err = ierr
	}
	return
}

func (c implProfileClientStub) Remove(ctx __context.T, opts ...__ipc.CallOpt) (err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "Remove", nil, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&err); ierr != nil {
		err = ierr
	}
	return
}

func (c implProfileClientStub) Signature(ctx __context.T, opts ...__ipc.CallOpt) (o0 __ipc.ServiceSignature, err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "Signature", nil, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&o0, &err); ierr != nil {
		err = ierr
	}
	return
}

func (c implProfileClientStub) GetMethodTags(ctx __context.T, method string, opts ...__ipc.CallOpt) (o0 []interface{}, err error) {
	var call __ipc.Call
	if call, err = c.c(ctx).StartCall(ctx, c.name, "GetMethodTags", []interface{}{method}, opts...); err != nil {
		return
	}
	if ierr := call.Finish(&o0, &err); ierr != nil {
		err = ierr
	}
	return
}

// ProfileServerMethods is the interface a server writer
// implements for Profile.
//
// Profile describes a profile internally. Besides the public Profile
// interface, it allows to add and remove profile specifications.
type ProfileServerMethods interface {
	// Profile abstracts a device's ability to run binaries, and hides
	// specifics such as the operating system, hardware architecture, and
	// the set of installed libraries. Profiles describe binaries and
	// devices, and are used to match them.
	repository.ProfileServerMethods
	// Specification returns the profile specification for the profile
	// identified through the object name suffix.
	Specification(__ipc.ServerContext) (profile.Specification, error)
	// Put sets the profile specification for the profile identified
	// through the object name suffix.
	Put(ctx __ipc.ServerContext, Specification profile.Specification) error
	// Remove removes the profile specification for the profile
	// identified through the object name suffix.
	Remove(__ipc.ServerContext) error
}

// ProfileServerStubMethods is the server interface containing
// Profile methods, as expected by ipc.Server.  The difference between
// this interface and ProfileServerMethods is that the first context
// argument for each method is always ipc.ServerCall here, while it is either
// ipc.ServerContext or a typed streaming context there.
type ProfileServerStubMethods interface {
	// Profile abstracts a device's ability to run binaries, and hides
	// specifics such as the operating system, hardware architecture, and
	// the set of installed libraries. Profiles describe binaries and
	// devices, and are used to match them.
	repository.ProfileServerStubMethods
	// Specification returns the profile specification for the profile
	// identified through the object name suffix.
	Specification(__ipc.ServerCall) (profile.Specification, error)
	// Put sets the profile specification for the profile identified
	// through the object name suffix.
	Put(call __ipc.ServerCall, Specification profile.Specification) error
	// Remove removes the profile specification for the profile
	// identified through the object name suffix.
	Remove(__ipc.ServerCall) error
}

// ProfileServerStub adds universal methods to ProfileServerStubMethods.
type ProfileServerStub interface {
	ProfileServerStubMethods
	// GetMethodTags will be replaced with DescribeInterfaces.
	GetMethodTags(call __ipc.ServerCall, method string) ([]interface{}, error)
	// Signature will be replaced with DescribeInterfaces.
	Signature(call __ipc.ServerCall) (__ipc.ServiceSignature, error)
}

// ProfileServer returns a server stub for Profile.
// It converts an implementation of ProfileServerMethods into
// an object that may be used by ipc.Server.
func ProfileServer(impl ProfileServerMethods) ProfileServerStub {
	stub := implProfileServerStub{
		impl:              impl,
		ProfileServerStub: repository.ProfileServer(impl),
	}
	// Initialize GlobState; always check the stub itself first, to handle the
	// case where the user has the Glob method defined in their VDL source.
	if gs := __ipc.NewGlobState(stub); gs != nil {
		stub.gs = gs
	} else if gs := __ipc.NewGlobState(impl); gs != nil {
		stub.gs = gs
	}
	return stub
}

type implProfileServerStub struct {
	impl ProfileServerMethods
	gs   *__ipc.GlobState

	repository.ProfileServerStub
}

func (s implProfileServerStub) Specification(call __ipc.ServerCall) (profile.Specification, error) {
	return s.impl.Specification(call)
}

func (s implProfileServerStub) Put(call __ipc.ServerCall, i0 profile.Specification) error {
	return s.impl.Put(call, i0)
}

func (s implProfileServerStub) Remove(call __ipc.ServerCall) error {
	return s.impl.Remove(call)
}

func (s implProfileServerStub) VGlob() *__ipc.GlobState {
	return s.gs
}

func (s implProfileServerStub) GetMethodTags(call __ipc.ServerCall, method string) ([]interface{}, error) {
	// TODO(toddw): Replace with new DescribeInterfaces implementation.
	if resp, err := s.ProfileServerStub.GetMethodTags(call, method); resp != nil || err != nil {
		return resp, err
	}
	switch method {
	case "Specification":
		return []interface{}{security.Label(2)}, nil
	case "Put":
		return []interface{}{security.Label(4)}, nil
	case "Remove":
		return []interface{}{security.Label(4)}, nil
	default:
		return nil, nil
	}
}

func (s implProfileServerStub) Signature(call __ipc.ServerCall) (__ipc.ServiceSignature, error) {
	// TODO(toddw) Replace with new DescribeInterfaces implementation.
	result := __ipc.ServiceSignature{Methods: make(map[string]__ipc.MethodSignature)}
	result.Methods["Put"] = __ipc.MethodSignature{
		InArgs: []__ipc.MethodArgument{
			{Name: "Specification", Type: 70},
		},
		OutArgs: []__ipc.MethodArgument{
			{Name: "", Type: 71},
		},
	}
	result.Methods["Remove"] = __ipc.MethodSignature{
		InArgs: []__ipc.MethodArgument{},
		OutArgs: []__ipc.MethodArgument{
			{Name: "", Type: 71},
		},
	}
	result.Methods["Specification"] = __ipc.MethodSignature{
		InArgs: []__ipc.MethodArgument{},
		OutArgs: []__ipc.MethodArgument{
			{Name: "", Type: 70},
			{Name: "", Type: 71},
		},
	}

	result.TypeDefs = []__vdlutil.Any{
		__wiretype.NamedPrimitiveType{Type: 0x3, Name: "veyron.io/veyron/veyron2/services/mgmt/build.Architecture", Tags: []string(nil)}, __wiretype.NamedPrimitiveType{Type: 0x3, Name: "veyron.io/veyron/veyron2/services/mgmt/build.Format", Tags: []string(nil)}, __wiretype.StructType{
			[]__wiretype.FieldType{
				__wiretype.FieldType{Type: 0x3, Name: "Name"},
				__wiretype.FieldType{Type: 0x3, Name: "MajorVersion"},
				__wiretype.FieldType{Type: 0x3, Name: "MinorVersion"},
			},
			"veyron.io/veyron/veyron/services/mgmt/profile.Library", []string(nil)},
		__wiretype.MapType{Key: 0x43, Elem: 0x2, Name: "", Tags: []string(nil)}, __wiretype.NamedPrimitiveType{Type: 0x3, Name: "veyron.io/veyron/veyron2/services/mgmt/build.OperatingSystem", Tags: []string(nil)}, __wiretype.StructType{
			[]__wiretype.FieldType{
				__wiretype.FieldType{Type: 0x41, Name: "Arch"},
				__wiretype.FieldType{Type: 0x3, Name: "Description"},
				__wiretype.FieldType{Type: 0x42, Name: "Format"},
				__wiretype.FieldType{Type: 0x44, Name: "Libraries"},
				__wiretype.FieldType{Type: 0x3, Name: "Label"},
				__wiretype.FieldType{Type: 0x45, Name: "OS"},
			},
			"veyron.io/veyron/veyron/services/mgmt/profile.Specification", []string(nil)},
		__wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
	var ss __ipc.ServiceSignature
	var firstAdded int
	ss, _ = s.ProfileServerStub.Signature(call)
	firstAdded = len(result.TypeDefs)
	for k, v := range ss.Methods {
		for i, _ := range v.InArgs {
			if v.InArgs[i].Type >= __wiretype.TypeIDFirst {
				v.InArgs[i].Type += __wiretype.TypeID(firstAdded)
			}
		}
		for i, _ := range v.OutArgs {
			if v.OutArgs[i].Type >= __wiretype.TypeIDFirst {
				v.OutArgs[i].Type += __wiretype.TypeID(firstAdded)
			}
		}
		if v.InStream >= __wiretype.TypeIDFirst {
			v.InStream += __wiretype.TypeID(firstAdded)
		}
		if v.OutStream >= __wiretype.TypeIDFirst {
			v.OutStream += __wiretype.TypeID(firstAdded)
		}
		result.Methods[k] = v
	}
	//TODO(bprosnitz) combine type definitions from embeded interfaces in a way that doesn't cause duplication.
	for _, d := range ss.TypeDefs {
		switch wt := d.(type) {
		case __wiretype.SliceType:
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.ArrayType:
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.MapType:
			if wt.Key >= __wiretype.TypeIDFirst {
				wt.Key += __wiretype.TypeID(firstAdded)
			}
			if wt.Elem >= __wiretype.TypeIDFirst {
				wt.Elem += __wiretype.TypeID(firstAdded)
			}
			d = wt
		case __wiretype.StructType:
			for i, fld := range wt.Fields {
				if fld.Type >= __wiretype.TypeIDFirst {
					wt.Fields[i].Type += __wiretype.TypeID(firstAdded)
				}
			}
			d = wt
			// NOTE: other types are missing, but we are upgrading anyways.
		}
		result.TypeDefs = append(result.TypeDefs, d)
	}

	return result, nil
}
