// Copyright 2015 The Vanadium 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 was auto-generated by the vanadium vdl tool.
// Package: application

// Package application defines types for describing applications.
package application

import (
	"fmt"
	"time"
	"v.io/v23/security"
	"v.io/v23/vdl"
	time_2 "v.io/v23/vdlroot/time"
)

var _ = __VDLInit() // Must be first; see __VDLInit comments for details.

//////////////////////////////////////////////////
// Type definitions

// SignedFile represents a file accompanied by a signature of its contents.
type SignedFile struct {
	//  File is the object name of the file.
	File string
	// Signature represents a signature on the sha256 hash of the file
	// contents by the publisher principal.
	Signature security.Signature
}

func (SignedFile) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/application.SignedFile"`
}) {
}

func (m *SignedFile) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.File == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("File"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("File")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.File), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := true
	var var8 bool
	if len(m.Signature.Purpose) == 0 {
		var8 = true
	}
	var7 = var7 && var8
	var9 := (m.Signature.Hash == security.Hash(""))
	var7 = var7 && var9
	var var10 bool
	if len(m.Signature.R) == 0 {
		var10 = true
	}
	var7 = var7 && var10
	var var11 bool
	if len(m.Signature.S) == 0 {
		var11 = true
	}
	var7 = var7 && var11
	if var7 {
		if err := fieldsTarget1.ZeroField("Signature"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Signature")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Signature.FillVDLTarget(fieldTarget6, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *SignedFile) MakeVDLTarget() vdl.Target {
	return &SignedFileTarget{Value: m}
}

type SignedFileTarget struct {
	Value           *SignedFile
	fileTarget      vdl.StringTarget
	signatureTarget security.SignatureTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *SignedFileTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*SignedFile)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *SignedFileTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "File":
		t.fileTarget.Value = &t.Value.File
		target, err := &t.fileTarget, error(nil)
		return nil, target, err
	case "Signature":
		t.signatureTarget.Value = &t.Value.Signature
		target, err := &t.signatureTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, fmt.Errorf("field %s not in struct v.io/v23/services/application.SignedFile", name)
	}
}
func (t *SignedFileTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *SignedFileTarget) ZeroField(name string) error {
	switch name {
	case "File":
		t.Value.File = ""
		return nil
	case "Signature":
		t.Value.Signature = security.Signature{}
		return nil
	default:
		return fmt.Errorf("field %s not in struct v.io/v23/services/application.SignedFile", name)
	}
}
func (t *SignedFileTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x *SignedFile) VDLRead(dec vdl.Decoder) error {
	*x = SignedFile{}
	var err error
	if err = dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "File":
			if err = dec.StartValue(); err != nil {
				return err
			}
			if x.File, err = dec.DecodeString(); err != nil {
				return err
			}
			if err = dec.FinishValue(); err != nil {
				return err
			}
		case "Signature":
			if err = x.Signature.VDLRead(dec); err != nil {
				return err
			}
		default:
			if err = dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func (x SignedFile) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*SignedFile)(nil)).Elem()); err != nil {
		return err
	}
	var1 := (x.File == "")
	if !(var1) {
		if err := enc.NextField("File"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeString(x.File); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	var2 := true
	var var3 bool
	if len(x.Signature.Purpose) == 0 {
		var3 = true
	}
	var2 = var2 && var3
	var4 := (x.Signature.Hash == security.Hash(""))
	var2 = var2 && var4
	var var5 bool
	if len(x.Signature.R) == 0 {
		var5 = true
	}
	var2 = var2 && var5
	var var6 bool
	if len(x.Signature.S) == 0 {
		var6 = true
	}
	var2 = var2 && var6
	if !(var2) {
		if err := enc.NextField("Signature"); err != nil {
			return err
		}
		if err := x.Signature.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

// Packages represents a set of packages. The map key is the local
// file/directory name, relative to the instance's packages directory, where the
// package should be installed. For archives, this name represents a directory
// into which the archive is to be extracted, and for regular files it
// represents the name for the file.  The map value is the package
// specification.
//
// Each object's media type determines how to install it.
//
// For example, with key=pkg1,value=SignedFile{File:binaryrepo/configfiles} (an
// archive), the "configfiles" package will be installed under the "pkg1"
// directory. With key=pkg2,value=SignedFile{File:binaryrepo/binfile} (a
// binary), the "binfile" file will be installed as the "pkg2" file.
//
// The keys must be valid file/directory names, without path separators.
//
// Any number of packages may be specified.
type Packages map[string]SignedFile

func (Packages) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/application.Packages"`
}) {
}

func (m *Packages) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	mapTarget1, err := t.StartMap(tt, len((*m)))
	if err != nil {
		return err
	}
	for key3, value5 := range *m {
		keyTarget2, err := mapTarget1.StartKey()
		if err != nil {
			return err
		}
		if err := keyTarget2.FromString(string(key3), tt.NonOptional().Key()); err != nil {
			return err
		}
		valueTarget4, err := mapTarget1.FinishKeyStartField(keyTarget2)
		if err != nil {
			return err
		}

		if err := value5.FillVDLTarget(valueTarget4, tt.NonOptional().Elem()); err != nil {
			return err
		}
		if err := mapTarget1.FinishField(keyTarget2, valueTarget4); err != nil {
			return err
		}
	}
	if err := t.FinishMap(mapTarget1); err != nil {
		return err
	}
	return nil
}

func (m *Packages) MakeVDLTarget() vdl.Target {
	return &PackagesTarget{Value: m}
}

type PackagesTarget struct {
	Value      *Packages
	currKey    string
	currElem   SignedFile
	keyTarget  vdl.StringTarget
	elemTarget SignedFileTarget
	vdl.TargetBase
	vdl.MapTargetBase
}

func (t *PackagesTarget) StartMap(tt *vdl.Type, len int) (vdl.MapTarget, error) {

	if ttWant := vdl.TypeOf((*Packages)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	*t.Value = make(Packages)
	return t, nil
}
func (t *PackagesTarget) StartKey() (key vdl.Target, _ error) {
	t.currKey = ""
	t.keyTarget.Value = &t.currKey
	target, err := &t.keyTarget, error(nil)
	return target, err
}
func (t *PackagesTarget) FinishKeyStartField(key vdl.Target) (field vdl.Target, _ error) {
	t.currElem = SignedFile{}
	t.elemTarget.Value = &t.currElem
	target, err := &t.elemTarget, error(nil)
	return target, err
}
func (t *PackagesTarget) FinishField(key, field vdl.Target) error {
	(*t.Value)[t.currKey] = t.currElem
	return nil
}
func (t *PackagesTarget) FinishMap(elem vdl.MapTarget) error {
	if len(*t.Value) == 0 {
		*t.Value = nil
	}

	return nil
}

func (x *Packages) VDLRead(dec vdl.Decoder) error {
	var err error
	if err = dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible map %T, from %v", *x, dec.Type())
	}
	var tmpMap Packages
	if len := dec.LenHint(); len > 0 {
		tmpMap = make(Packages, len)
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			*x = tmpMap
			return dec.FinishValue()
		}
		var key string
		{
			if err = dec.StartValue(); err != nil {
				return err
			}
			if key, err = dec.DecodeString(); err != nil {
				return err
			}
			if err = dec.FinishValue(); err != nil {
				return err
			}
		}
		var elem SignedFile
		{
			if err = elem.VDLRead(dec); err != nil {
				return err
			}
		}
		if tmpMap == nil {
			tmpMap = make(Packages)
		}
		tmpMap[key] = elem
	}
}

func (x Packages) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*Packages)(nil))); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for key, elem := range x {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeString(key); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
		if err := elem.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

// Envelope is a collection of metadata that describes an application.
type Envelope struct {
	// Title is the publisher-assigned application title.  Application
	// installations with the same title are considered as belonging to the
	// same application by the application management system.
	//
	// A change in the title signals a new application.
	Title string
	// Args is an array of command-line arguments to be used when executing
	// the binary.
	Args []string
	// Binary identifies the application binary.
	Binary SignedFile
	// Publisher represents the set of blessings that have been bound to
	// the principal who published this binary.
	Publisher security.Blessings
	// Env is an array that stores the environment variable values to be
	// used when executing the binary.
	Env []string
	// Packages is the set of packages to install on the local filesystem
	// before executing the binary
	Packages Packages
	// Restarts specifies how many times the device manager will attempt
	// to automatically restart an application that has crashed before
	// giving up and marking the application as NotRunning.
	Restarts int32
	// RestartTimeWindow is the time window within which an
	// application exit is considered a crash that counts against the
	// Restarts budget. If the application crashes after less than
	// RestartTimeWindow time for Restarts consecutive times, the
	// application is marked NotRunning and no more restart attempts
	// are made. If the application has run continuously for more
	// than RestartTimeWindow, subsequent crashes will again benefit
	// from up to Restarts restarts (that is, the Restarts budget is
	// reset by a successful run of at least RestartTimeWindow
	// duration).
	RestartTimeWindow time.Duration
}

func (Envelope) __VDLReflect(struct {
	Name string `vdl:"v.io/v23/services/application.Envelope"`
}) {
}

func (m *Envelope) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Title == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Title"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Title")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.Title), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var var7 bool
	if len(m.Args) == 0 {
		var7 = true
	}
	if var7 {
		if err := fieldsTarget1.ZeroField("Args"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("Args")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget8, err := fieldTarget6.StartList(tt.NonOptional().Field(1).Type, len(m.Args))
			if err != nil {
				return err
			}
			for i, elem10 := range m.Args {
				elemTarget9, err := listTarget8.StartElem(i)
				if err != nil {
					return err
				}
				if err := elemTarget9.FromString(string(elem10), tt.NonOptional().Field(1).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget8.FinishElem(elemTarget9); err != nil {
					return err
				}
			}
			if err := fieldTarget6.FinishList(listTarget8); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var13 := true
	var14 := (m.Binary.File == "")
	var13 = var13 && var14
	var15 := true
	var var16 bool
	if len(m.Binary.Signature.Purpose) == 0 {
		var16 = true
	}
	var15 = var15 && var16
	var17 := (m.Binary.Signature.Hash == security.Hash(""))
	var15 = var15 && var17
	var var18 bool
	if len(m.Binary.Signature.R) == 0 {
		var18 = true
	}
	var15 = var15 && var18
	var var19 bool
	if len(m.Binary.Signature.S) == 0 {
		var19 = true
	}
	var15 = var15 && var19
	var13 = var13 && var15
	if var13 {
		if err := fieldsTarget1.ZeroField("Binary"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget11, fieldTarget12, err := fieldsTarget1.StartField("Binary")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Binary.FillVDLTarget(fieldTarget12, tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget11, fieldTarget12); err != nil {
				return err
			}
		}
	}
	var wireValue20 security.WireBlessings
	if err := security.WireBlessingsFromNative(&wireValue20, m.Publisher); err != nil {
		return err
	}

	var23 := true
	var var24 bool
	if len(wireValue20.CertificateChains) == 0 {
		var24 = true
	}
	var23 = var23 && var24
	if var23 {
		if err := fieldsTarget1.ZeroField("Publisher"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget21, fieldTarget22, err := fieldsTarget1.StartField("Publisher")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := wireValue20.FillVDLTarget(fieldTarget22, tt.NonOptional().Field(3).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget21, fieldTarget22); err != nil {
				return err
			}
		}
	}
	var var27 bool
	if len(m.Env) == 0 {
		var27 = true
	}
	if var27 {
		if err := fieldsTarget1.ZeroField("Env"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget25, fieldTarget26, err := fieldsTarget1.StartField("Env")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			listTarget28, err := fieldTarget26.StartList(tt.NonOptional().Field(4).Type, len(m.Env))
			if err != nil {
				return err
			}
			for i, elem30 := range m.Env {
				elemTarget29, err := listTarget28.StartElem(i)
				if err != nil {
					return err
				}
				if err := elemTarget29.FromString(string(elem30), tt.NonOptional().Field(4).Type.Elem()); err != nil {
					return err
				}
				if err := listTarget28.FinishElem(elemTarget29); err != nil {
					return err
				}
			}
			if err := fieldTarget26.FinishList(listTarget28); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget25, fieldTarget26); err != nil {
				return err
			}
		}
	}
	var var33 bool
	if len(m.Packages) == 0 {
		var33 = true
	}
	if var33 {
		if err := fieldsTarget1.ZeroField("Packages"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget31, fieldTarget32, err := fieldsTarget1.StartField("Packages")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := m.Packages.FillVDLTarget(fieldTarget32, tt.NonOptional().Field(5).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget31, fieldTarget32); err != nil {
				return err
			}
		}
	}
	var36 := (m.Restarts == int32(0))
	if var36 {
		if err := fieldsTarget1.ZeroField("Restarts"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget34, fieldTarget35, err := fieldsTarget1.StartField("Restarts")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget35.FromInt(int64(m.Restarts), tt.NonOptional().Field(6).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget34, fieldTarget35); err != nil {
				return err
			}
		}
	}
	var wireValue37 time_2.Duration
	if err := time_2.DurationFromNative(&wireValue37, m.RestartTimeWindow); err != nil {
		return err
	}

	var40 := (wireValue37 == time_2.Duration{})
	if var40 {
		if err := fieldsTarget1.ZeroField("RestartTimeWindow"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget38, fieldTarget39, err := fieldsTarget1.StartField("RestartTimeWindow")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := wireValue37.FillVDLTarget(fieldTarget39, tt.NonOptional().Field(7).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget38, fieldTarget39); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *Envelope) MakeVDLTarget() vdl.Target {
	return &EnvelopeTarget{Value: m}
}

type EnvelopeTarget struct {
	Value                   *Envelope
	titleTarget             vdl.StringTarget
	argsTarget              vdl.StringSliceTarget
	binaryTarget            SignedFileTarget
	publisherTarget         security.WireBlessingsTarget
	envTarget               vdl.StringSliceTarget
	packagesTarget          PackagesTarget
	restartsTarget          vdl.Int32Target
	restartTimeWindowTarget time_2.DurationTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *EnvelopeTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {

	if ttWant := vdl.TypeOf((*Envelope)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *EnvelopeTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Title":
		t.titleTarget.Value = &t.Value.Title
		target, err := &t.titleTarget, error(nil)
		return nil, target, err
	case "Args":
		t.argsTarget.Value = &t.Value.Args
		target, err := &t.argsTarget, error(nil)
		return nil, target, err
	case "Binary":
		t.binaryTarget.Value = &t.Value.Binary
		target, err := &t.binaryTarget, error(nil)
		return nil, target, err
	case "Publisher":
		t.publisherTarget.Value = &t.Value.Publisher
		target, err := &t.publisherTarget, error(nil)
		return nil, target, err
	case "Env":
		t.envTarget.Value = &t.Value.Env
		target, err := &t.envTarget, error(nil)
		return nil, target, err
	case "Packages":
		t.packagesTarget.Value = &t.Value.Packages
		target, err := &t.packagesTarget, error(nil)
		return nil, target, err
	case "Restarts":
		t.restartsTarget.Value = &t.Value.Restarts
		target, err := &t.restartsTarget, error(nil)
		return nil, target, err
	case "RestartTimeWindow":
		t.restartTimeWindowTarget.Value = &t.Value.RestartTimeWindow
		target, err := &t.restartTimeWindowTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, fmt.Errorf("field %s not in struct v.io/v23/services/application.Envelope", name)
	}
}
func (t *EnvelopeTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *EnvelopeTarget) ZeroField(name string) error {
	switch name {
	case "Title":
		t.Value.Title = ""
		return nil
	case "Args":
		t.Value.Args = []string(nil)
		return nil
	case "Binary":
		t.Value.Binary = SignedFile{}
		return nil
	case "Publisher":
		t.Value.Publisher = func() security.Blessings {
			var native security.Blessings
			if err := vdl.Convert(&native, security.WireBlessings{}); err != nil {
				panic(err)
			}
			return native
		}()
		return nil
	case "Env":
		t.Value.Env = []string(nil)
		return nil
	case "Packages":
		t.Value.Packages = Packages(nil)
		return nil
	case "Restarts":
		t.Value.Restarts = int32(0)
		return nil
	case "RestartTimeWindow":
		t.Value.RestartTimeWindow = func() time.Duration {
			var native time.Duration
			if err := vdl.Convert(&native, time_2.Duration{}); err != nil {
				panic(err)
			}
			return native
		}()
		return nil
	default:
		return fmt.Errorf("field %s not in struct v.io/v23/services/application.Envelope", name)
	}
}
func (t *EnvelopeTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x *Envelope) VDLRead(dec vdl.Decoder) error {
	*x = Envelope{}
	var err error
	if err = dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
	}
	for {
		f, err := dec.NextField()
		if err != nil {
			return err
		}
		switch f {
		case "":
			return dec.FinishValue()
		case "Title":
			if err = dec.StartValue(); err != nil {
				return err
			}
			if x.Title, err = dec.DecodeString(); err != nil {
				return err
			}
			if err = dec.FinishValue(); err != nil {
				return err
			}
		case "Args":
			if err = __VDLRead1_list(dec, &x.Args); err != nil {
				return err
			}
		case "Binary":
			if err = x.Binary.VDLRead(dec); err != nil {
				return err
			}
		case "Publisher":
			var wire security.WireBlessings
			if err = wire.VDLRead(dec); err != nil {
				return err
			}
			if err = security.WireBlessingsToNative(wire, &x.Publisher); err != nil {
				return err
			}
		case "Env":
			if err = __VDLRead1_list(dec, &x.Env); err != nil {
				return err
			}
		case "Packages":
			if err = x.Packages.VDLRead(dec); err != nil {
				return err
			}
		case "Restarts":
			if err = dec.StartValue(); err != nil {
				return err
			}
			tmp, err := dec.DecodeInt(32)
			if err != nil {
				return err
			}
			x.Restarts = int32(tmp)
			if err = dec.FinishValue(); err != nil {
				return err
			}
		case "RestartTimeWindow":
			var wire time_2.Duration
			if err = wire.VDLRead(dec); err != nil {
				return err
			}
			if err = time_2.DurationToNative(wire, &x.RestartTimeWindow); err != nil {
				return err
			}
		default:
			if err = dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

func __VDLRead1_list(dec vdl.Decoder, x *[]string) error {
	var err error
	if err = dec.StartValue(); err != nil {
		return err
	}
	if (dec.StackDepth() == 1 || dec.IsAny()) && !vdl.Compatible(vdl.TypeOf(*x), dec.Type()) {
		return fmt.Errorf("incompatible list %T, from %v", *x, dec.Type())
	}
	switch len := dec.LenHint(); {
	case len > 0:
		*x = make([]string, 0, len)
	default:
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		}
		var elem string
		if err = dec.StartValue(); err != nil {
			return err
		}
		if elem, err = dec.DecodeString(); err != nil {
			return err
		}
		if err = dec.FinishValue(); err != nil {
			return err
		}
		*x = append(*x, elem)
	}
}

func (x Envelope) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*Envelope)(nil)).Elem()); err != nil {
		return err
	}
	var1 := (x.Title == "")
	if !(var1) {
		if err := enc.NextField("Title"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Title); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	var var2 bool
	if len(x.Args) == 0 {
		var2 = true
	}
	if !(var2) {
		if err := enc.NextField("Args"); err != nil {
			return err
		}
		if err := __VDLWrite1_list(enc, &x.Args); err != nil {
			return err
		}
	}
	var3 := true
	var4 := (x.Binary.File == "")
	var3 = var3 && var4
	var5 := true
	var var6 bool
	if len(x.Binary.Signature.Purpose) == 0 {
		var6 = true
	}
	var5 = var5 && var6
	var7 := (x.Binary.Signature.Hash == security.Hash(""))
	var5 = var5 && var7
	var var8 bool
	if len(x.Binary.Signature.R) == 0 {
		var8 = true
	}
	var5 = var5 && var8
	var var9 bool
	if len(x.Binary.Signature.S) == 0 {
		var9 = true
	}
	var5 = var5 && var9
	var3 = var3 && var5
	if !(var3) {
		if err := enc.NextField("Binary"); err != nil {
			return err
		}
		if err := x.Binary.VDLWrite(enc); err != nil {
			return err
		}
	}
	var wireValue10 security.WireBlessings
	if err := security.WireBlessingsFromNative(&wireValue10, x.Publisher); err != nil {
		return fmt.Errorf("error converting x.Publisher to wiretype")
	}

	var11 := true
	var var12 bool
	if len(wireValue10.CertificateChains) == 0 {
		var12 = true
	}
	var11 = var11 && var12
	if !(var11) {
		if err := enc.NextField("Publisher"); err != nil {
			return err
		}
		var wire security.WireBlessings
		if err := security.WireBlessingsFromNative(&wire, x.Publisher); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	var var13 bool
	if len(x.Env) == 0 {
		var13 = true
	}
	if !(var13) {
		if err := enc.NextField("Env"); err != nil {
			return err
		}
		if err := __VDLWrite1_list(enc, &x.Env); err != nil {
			return err
		}
	}
	var var14 bool
	if len(x.Packages) == 0 {
		var14 = true
	}
	if !(var14) {
		if err := enc.NextField("Packages"); err != nil {
			return err
		}
		if err := x.Packages.VDLWrite(enc); err != nil {
			return err
		}
	}
	var15 := (x.Restarts == int32(0))
	if !(var15) {
		if err := enc.NextField("Restarts"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*int32)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeInt(int64(x.Restarts)); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	var wireValue16 time_2.Duration
	if err := time_2.DurationFromNative(&wireValue16, x.RestartTimeWindow); err != nil {
		return fmt.Errorf("error converting x.RestartTimeWindow to wiretype")
	}

	var17 := (wireValue16 == time_2.Duration{})
	if !(var17) {
		if err := enc.NextField("RestartTimeWindow"); err != nil {
			return err
		}
		var wire time_2.Duration
		if err := time_2.DurationFromNative(&wire, x.RestartTimeWindow); err != nil {
			return err
		}
		if err := wire.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWrite1_list(enc vdl.Encoder, x *[]string) error {
	if err := enc.StartValue(vdl.TypeOf((*[]string)(nil))); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(*x)); err != nil {
		return err
	}
	for i := 0; i < len(*x); i++ {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeString((*x)[i]); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

//////////////////////////////////////////////////
// Const definitions

// Device manager application envelopes must present this title.
const DeviceManagerTitle = "device manager"

var __VDLInitCalled bool

// __VDLInit performs vdl initialization.  It is safe to call multiple times.
// If you have an init ordering issue, just insert the following line verbatim
// into your source files in this package, right after the "package foo" clause:
//
//    var _ = __VDLInit()
//
// The purpose of this function is to ensure that vdl initialization occurs in
// the right order, and very early in the init sequence.  In particular, vdl
// registration and package variable initialization needs to occur before
// functions like vdl.TypeOf will work properly.
//
// This function returns a dummy value, so that it can be used to initialize the
// first var in the file, to take advantage of Go's defined init order.
func __VDLInit() struct{} {
	if __VDLInitCalled {
		return struct{}{}
	}
	__VDLInitCalled = true

	// Register types.
	vdl.Register((*SignedFile)(nil))
	vdl.Register((*Packages)(nil))
	vdl.Register((*Envelope)(nil))

	return struct{}{}
}
