// 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: sbmodel

// Syncbase data model for Sensor Log.
//
// Every type <T> stored in Syncbase is defined as a pair of types, K<T> and
// V<T>, representing data stored in the key and value, respectively, in a
// single collection. K<T> types satisfy the PersistentDataKey interface,
// supporting conversion to and from the row key.
package sbmodel

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

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

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

// devicecfg : <DevId>
// Measuring device handle. Master only.
type VDeviceCfg struct {
	// Human-readable, not necessarily unique description of the device.
	Desc string
	// Syncbase instance publishing the syncgroup created by the device.
	SgPublishSb string
}

func (VDeviceCfg) __VDLReflect(struct {
	Name string `vdl:"v.io/x/sensorlog/internal/sbmodel.VDeviceCfg"`
}) {
}

func (m *VDeviceCfg) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Desc == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Desc"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Desc")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.Desc), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.SgPublishSb == "")
	if var7 {
		if err := fieldsTarget1.ZeroField("SgPublishSb"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("SgPublishSb")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromString(string(m.SgPublishSb), 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 *VDeviceCfg) MakeVDLTarget() vdl.Target {
	return &VDeviceCfgTarget{Value: m}
}

type VDeviceCfgTarget struct {
	Value             *VDeviceCfg
	descTarget        vdl.StringTarget
	sgPublishSbTarget vdl.StringTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*VDeviceCfg)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *VDeviceCfgTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Desc":
		t.descTarget.Value = &t.Value.Desc
		target, err := &t.descTarget, error(nil)
		return nil, target, err
	case "SgPublishSb":
		t.sgPublishSbTarget.Value = &t.Value.SgPublishSb
		target, err := &t.sgPublishSbTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, fmt.Errorf("field %s not in struct v.io/x/sensorlog/internal/sbmodel.VDeviceCfg", name)
	}
}
func (t *VDeviceCfgTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *VDeviceCfgTarget) ZeroField(name string) error {
	switch name {
	case "Desc":
		t.Value.Desc = ""
		return nil
	case "SgPublishSb":
		t.Value.SgPublishSb = ""
		return nil
	default:
		return fmt.Errorf("field %s not in struct v.io/x/sensorlog/internal/sbmodel.VDeviceCfg", name)
	}
}
func (t *VDeviceCfgTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x VDeviceCfg) VDLIsZero() (bool, error) {
	return x == VDeviceCfg{}, nil
}

func (x VDeviceCfg) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*VDeviceCfg)(nil)).Elem()); err != nil {
		return err
	}
	if x.Desc != "" {
		if err := enc.NextField("Desc"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Desc); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.SgPublishSb != "" {
		if err := enc.NextField("SgPublishSb"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeString(x.SgPublishSb); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *VDeviceCfg) VDLRead(dec vdl.Decoder) error {
	*x = VDeviceCfg{}
	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 "Desc":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Desc, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "SgPublishSb":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.SgPublishSb, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

type KDeviceCfg struct {
	DevId string
}

func (KDeviceCfg) __VDLReflect(struct {
	Name string `vdl:"v.io/x/sensorlog/internal/sbmodel.KDeviceCfg"`
}) {
}

func (m *KDeviceCfg) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.DevId == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("DevId"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("DevId")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.DevId), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *KDeviceCfg) MakeVDLTarget() vdl.Target {
	return &KDeviceCfgTarget{Value: m}
}

type KDeviceCfgTarget struct {
	Value       *KDeviceCfg
	devIdTarget vdl.StringTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*KDeviceCfg)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *KDeviceCfgTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "DevId":
		t.devIdTarget.Value = &t.Value.DevId
		target, err := &t.devIdTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, fmt.Errorf("field %s not in struct v.io/x/sensorlog/internal/sbmodel.KDeviceCfg", name)
	}
}
func (t *KDeviceCfgTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *KDeviceCfgTarget) ZeroField(name string) error {
	switch name {
	case "DevId":
		t.Value.DevId = ""
		return nil
	default:
		return fmt.Errorf("field %s not in struct v.io/x/sensorlog/internal/sbmodel.KDeviceCfg", name)
	}
}
func (t *KDeviceCfgTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x KDeviceCfg) VDLIsZero() (bool, error) {
	return x == KDeviceCfg{}, nil
}

func (x KDeviceCfg) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*KDeviceCfg)(nil)).Elem()); err != nil {
		return err
	}
	if x.DevId != "" {
		if err := enc.NextField("DevId"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeString(x.DevId); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *KDeviceCfg) VDLRead(dec vdl.Decoder) error {
	*x = KDeviceCfg{}
	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 "DevId":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.DevId, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// Sampling script and polling frequency.
type SamplerDef struct {
	// Shell script executed after every Interval, starting from Start.
	// It should output a single data point, if available. A non-zero exit
	// status or failure to parse the value will produce an error instead.
	Script   string
	Start    time.Time
	Interval time.Duration
}

func (SamplerDef) __VDLReflect(struct {
	Name string `vdl:"v.io/x/sensorlog/internal/sbmodel.SamplerDef"`
}) {
}

func (m *SamplerDef) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.Script == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("Script"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Script")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.Script), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var wireValue5 time_2.Time
	if err := time_2.TimeFromNative(&wireValue5, m.Start); err != nil {
		return err
	}

	var8 := (wireValue5 == time_2.Time{})
	if var8 {
		if err := fieldsTarget1.ZeroField("Start"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget6, fieldTarget7, err := fieldsTarget1.StartField("Start")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := wireValue5.FillVDLTarget(fieldTarget7, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget6, fieldTarget7); err != nil {
				return err
			}
		}
	}
	var wireValue9 time_2.Duration
	if err := time_2.DurationFromNative(&wireValue9, m.Interval); err != nil {
		return err
	}

	var12 := (wireValue9 == time_2.Duration{})
	if var12 {
		if err := fieldsTarget1.ZeroField("Interval"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget10, fieldTarget11, err := fieldsTarget1.StartField("Interval")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := wireValue9.FillVDLTarget(fieldTarget11, tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget10, fieldTarget11); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *SamplerDef) MakeVDLTarget() vdl.Target {
	return &SamplerDefTarget{Value: m}
}

type SamplerDefTarget struct {
	Value          *SamplerDef
	scriptTarget   vdl.StringTarget
	startTarget    time_2.TimeTarget
	intervalTarget time_2.DurationTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*SamplerDef)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *SamplerDefTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Script":
		t.scriptTarget.Value = &t.Value.Script
		target, err := &t.scriptTarget, error(nil)
		return nil, target, err
	case "Start":
		t.startTarget.Value = &t.Value.Start
		target, err := &t.startTarget, error(nil)
		return nil, target, err
	case "Interval":
		t.intervalTarget.Value = &t.Value.Interval
		target, err := &t.intervalTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, fmt.Errorf("field %s not in struct v.io/x/sensorlog/internal/sbmodel.SamplerDef", name)
	}
}
func (t *SamplerDefTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *SamplerDefTarget) ZeroField(name string) error {
	switch name {
	case "Script":
		t.Value.Script = ""
		return nil
	case "Start":
		t.Value.Start = func() time.Time {
			var native time.Time
			if err := vdl.Convert(&native, time_2.Time{}); err != nil {
				panic(err)
			}
			return native
		}()
		return nil
	case "Interval":
		t.Value.Interval = 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/x/sensorlog/internal/sbmodel.SamplerDef", name)
	}
}
func (t *SamplerDefTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x SamplerDef) VDLIsZero() (bool, error) {
	if x.Script != "" {
		return false, nil
	}
	var wireStart time_2.Time
	if err := time_2.TimeFromNative(&wireStart, x.Start); err != nil {
		return false, err
	}
	if wireStart != (time_2.Time{}) {
		return false, nil
	}
	var wireInterval time_2.Duration
	if err := time_2.DurationFromNative(&wireInterval, x.Interval); err != nil {
		return false, err
	}
	if wireInterval != (time_2.Duration{}) {
		return false, nil
	}
	return true, nil
}

func (x SamplerDef) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*SamplerDef)(nil)).Elem()); err != nil {
		return err
	}
	if x.Script != "" {
		if err := enc.NextField("Script"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Script); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	var wireStart time_2.Time
	if err := time_2.TimeFromNative(&wireStart, x.Start); err != nil {
		return err
	}
	if wireStart != (time_2.Time{}) {
		if err := enc.NextField("Start"); err != nil {
			return err
		}
		if err := wireStart.VDLWrite(enc); err != nil {
			return err
		}
	}
	var wireInterval time_2.Duration
	if err := time_2.DurationFromNative(&wireInterval, x.Interval); err != nil {
		return err
	}
	if wireInterval != (time_2.Duration{}) {
		if err := enc.NextField("Interval"); err != nil {
			return err
		}
		if err := wireInterval.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *SamplerDef) VDLRead(dec vdl.Decoder) error {
	*x = SamplerDef{}
	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 "Script":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Script, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Start":
			var wire time_2.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := time_2.TimeToNative(wire, &x.Start); err != nil {
				return err
			}
		case "Interval":
			var wire time_2.Duration
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := time_2.DurationToNative(wire, &x.Interval); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// streamdef : <DevId>/<StreamId>
// Configures a stream of data to be measured.
type VStreamDef struct {
	// Human-readable, not necessarily unique description of the stream.
	Desc string
	// Sampling configuration.
	Sampler SamplerDef
	// Flag to start and stop sampling.
	Enabled bool
}

func (VStreamDef) __VDLReflect(struct {
	Name string `vdl:"v.io/x/sensorlog/internal/sbmodel.VStreamDef"`
}) {
}

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

			if err := m.Sampler.FillVDLTarget(fieldTarget6, tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var10 := (m.Enabled == false)
	if var10 {
		if err := fieldsTarget1.ZeroField("Enabled"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget8, fieldTarget9, err := fieldsTarget1.StartField("Enabled")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget9.FromBool(bool(m.Enabled), tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget8, fieldTarget9); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *VStreamDef) MakeVDLTarget() vdl.Target {
	return &VStreamDefTarget{Value: m}
}

type VStreamDefTarget struct {
	Value         *VStreamDef
	descTarget    vdl.StringTarget
	samplerTarget SamplerDefTarget
	enabledTarget vdl.BoolTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*VStreamDef)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *VStreamDefTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "Desc":
		t.descTarget.Value = &t.Value.Desc
		target, err := &t.descTarget, error(nil)
		return nil, target, err
	case "Sampler":
		t.samplerTarget.Value = &t.Value.Sampler
		target, err := &t.samplerTarget, error(nil)
		return nil, target, err
	case "Enabled":
		t.enabledTarget.Value = &t.Value.Enabled
		target, err := &t.enabledTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, fmt.Errorf("field %s not in struct v.io/x/sensorlog/internal/sbmodel.VStreamDef", name)
	}
}
func (t *VStreamDefTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *VStreamDefTarget) ZeroField(name string) error {
	switch name {
	case "Desc":
		t.Value.Desc = ""
		return nil
	case "Sampler":
		t.Value.Sampler = SamplerDef{}
		return nil
	case "Enabled":
		t.Value.Enabled = false
		return nil
	default:
		return fmt.Errorf("field %s not in struct v.io/x/sensorlog/internal/sbmodel.VStreamDef", name)
	}
}
func (t *VStreamDefTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x VStreamDef) VDLIsZero() (bool, error) {
	if x.Desc != "" {
		return false, nil
	}
	isZeroSampler, err := x.Sampler.VDLIsZero()
	if err != nil {
		return false, err
	}
	if !isZeroSampler {
		return false, nil
	}
	if x.Enabled {
		return false, nil
	}
	return true, nil
}

func (x VStreamDef) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*VStreamDef)(nil)).Elem()); err != nil {
		return err
	}
	if x.Desc != "" {
		if err := enc.NextField("Desc"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeString(x.Desc); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	isZeroSampler, err := x.Sampler.VDLIsZero()
	if err != nil {
		return err
	}
	if !isZeroSampler {
		if err := enc.NextField("Sampler"); err != nil {
			return err
		}
		if err := x.Sampler.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.Enabled {
		if err := enc.NextField("Enabled"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*bool)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeBool(x.Enabled); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *VStreamDef) VDLRead(dec vdl.Decoder) error {
	*x = VStreamDef{}
	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 "Desc":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Desc, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Sampler":
			if err := x.Sampler.VDLRead(dec); err != nil {
				return err
			}
		case "Enabled":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.Enabled, err = dec.DecodeBool(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

type KStreamDef struct {
	DevId    string
	StreamId string
}

func (KStreamDef) __VDLReflect(struct {
	Name string `vdl:"v.io/x/sensorlog/internal/sbmodel.KStreamDef"`
}) {
}

func (m *KStreamDef) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.DevId == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("DevId"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("DevId")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.DevId), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.StreamId == "")
	if var7 {
		if err := fieldsTarget1.ZeroField("StreamId"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("StreamId")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromString(string(m.StreamId), 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 *KStreamDef) MakeVDLTarget() vdl.Target {
	return &KStreamDefTarget{Value: m}
}

type KStreamDefTarget struct {
	Value          *KStreamDef
	devIdTarget    vdl.StringTarget
	streamIdTarget vdl.StringTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*KStreamDef)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *KStreamDefTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "DevId":
		t.devIdTarget.Value = &t.Value.DevId
		target, err := &t.devIdTarget, error(nil)
		return nil, target, err
	case "StreamId":
		t.streamIdTarget.Value = &t.Value.StreamId
		target, err := &t.streamIdTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, fmt.Errorf("field %s not in struct v.io/x/sensorlog/internal/sbmodel.KStreamDef", name)
	}
}
func (t *KStreamDefTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *KStreamDefTarget) ZeroField(name string) error {
	switch name {
	case "DevId":
		t.Value.DevId = ""
		return nil
	case "StreamId":
		t.Value.StreamId = ""
		return nil
	default:
		return fmt.Errorf("field %s not in struct v.io/x/sensorlog/internal/sbmodel.KStreamDef", name)
	}
}
func (t *KStreamDefTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x KStreamDef) VDLIsZero() (bool, error) {
	return x == KStreamDef{}, nil
}

func (x KStreamDef) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*KStreamDef)(nil)).Elem()); err != nil {
		return err
	}
	if x.DevId != "" {
		if err := enc.NextField("DevId"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeString(x.DevId); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.StreamId != "" {
		if err := enc.NextField("StreamId"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeString(x.StreamId); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *KStreamDef) VDLRead(dec vdl.Decoder) error {
	*x = KStreamDef{}
	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 "DevId":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.DevId, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "StreamId":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.StreamId, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

// sdata : <DevId>/<StreamId>/<Timestamp>
// Measured data value or error.
type KDataPoint struct {
	DevId     string
	StreamId  string
	Timestamp time.Time
}

func (KDataPoint) __VDLReflect(struct {
	Name string `vdl:"v.io/x/sensorlog/internal/sbmodel.KDataPoint"`
}) {
}

func (m *KDataPoint) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	var4 := (m.DevId == "")
	if var4 {
		if err := fieldsTarget1.ZeroField("DevId"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("DevId")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget3.FromString(string(m.DevId), tt.NonOptional().Field(0).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
				return err
			}
		}
	}
	var7 := (m.StreamId == "")
	if var7 {
		if err := fieldsTarget1.ZeroField("StreamId"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget5, fieldTarget6, err := fieldsTarget1.StartField("StreamId")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}
			if err := fieldTarget6.FromString(string(m.StreamId), tt.NonOptional().Field(1).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget5, fieldTarget6); err != nil {
				return err
			}
		}
	}
	var wireValue8 time_2.Time
	if err := time_2.TimeFromNative(&wireValue8, m.Timestamp); err != nil {
		return err
	}

	var11 := (wireValue8 == time_2.Time{})
	if var11 {
		if err := fieldsTarget1.ZeroField("Timestamp"); err != nil && err != vdl.ErrFieldNoExist {
			return err
		}
	} else {
		keyTarget9, fieldTarget10, err := fieldsTarget1.StartField("Timestamp")
		if err != vdl.ErrFieldNoExist {
			if err != nil {
				return err
			}

			if err := wireValue8.FillVDLTarget(fieldTarget10, tt.NonOptional().Field(2).Type); err != nil {
				return err
			}
			if err := fieldsTarget1.FinishField(keyTarget9, fieldTarget10); err != nil {
				return err
			}
		}
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}
	return nil
}

func (m *KDataPoint) MakeVDLTarget() vdl.Target {
	return &KDataPointTarget{Value: m}
}

type KDataPointTarget struct {
	Value           *KDataPoint
	devIdTarget     vdl.StringTarget
	streamIdTarget  vdl.StringTarget
	timestampTarget time_2.TimeTarget
	vdl.TargetBase
	vdl.FieldsTargetBase
}

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

	if ttWant := vdl.TypeOf((*KDataPoint)(nil)).Elem(); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}
	return t, nil
}
func (t *KDataPointTarget) StartField(name string) (key, field vdl.Target, _ error) {
	switch name {
	case "DevId":
		t.devIdTarget.Value = &t.Value.DevId
		target, err := &t.devIdTarget, error(nil)
		return nil, target, err
	case "StreamId":
		t.streamIdTarget.Value = &t.Value.StreamId
		target, err := &t.streamIdTarget, error(nil)
		return nil, target, err
	case "Timestamp":
		t.timestampTarget.Value = &t.Value.Timestamp
		target, err := &t.timestampTarget, error(nil)
		return nil, target, err
	default:
		return nil, nil, fmt.Errorf("field %s not in struct v.io/x/sensorlog/internal/sbmodel.KDataPoint", name)
	}
}
func (t *KDataPointTarget) FinishField(_, _ vdl.Target) error {
	return nil
}
func (t *KDataPointTarget) ZeroField(name string) error {
	switch name {
	case "DevId":
		t.Value.DevId = ""
		return nil
	case "StreamId":
		t.Value.StreamId = ""
		return nil
	case "Timestamp":
		t.Value.Timestamp = func() time.Time {
			var native time.Time
			if err := vdl.Convert(&native, time_2.Time{}); err != nil {
				panic(err)
			}
			return native
		}()
		return nil
	default:
		return fmt.Errorf("field %s not in struct v.io/x/sensorlog/internal/sbmodel.KDataPoint", name)
	}
}
func (t *KDataPointTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

func (x KDataPoint) VDLIsZero() (bool, error) {
	if x.DevId != "" {
		return false, nil
	}
	if x.StreamId != "" {
		return false, nil
	}
	var wireTimestamp time_2.Time
	if err := time_2.TimeFromNative(&wireTimestamp, x.Timestamp); err != nil {
		return false, err
	}
	if wireTimestamp != (time_2.Time{}) {
		return false, nil
	}
	return true, nil
}

func (x KDataPoint) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*KDataPoint)(nil)).Elem()); err != nil {
		return err
	}
	if x.DevId != "" {
		if err := enc.NextField("DevId"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeString(x.DevId); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	if x.StreamId != "" {
		if err := enc.NextField("StreamId"); err != nil {
			return err
		}
		if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
			return err
		}
		if err := enc.EncodeString(x.StreamId); err != nil {
			return err
		}
		if err := enc.FinishValue(); err != nil {
			return err
		}
	}
	var wireTimestamp time_2.Time
	if err := time_2.TimeFromNative(&wireTimestamp, x.Timestamp); err != nil {
		return err
	}
	if wireTimestamp != (time_2.Time{}) {
		if err := enc.NextField("Timestamp"); err != nil {
			return err
		}
		if err := wireTimestamp.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *KDataPoint) VDLRead(dec vdl.Decoder) error {
	*x = KDataPoint{}
	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 "DevId":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.DevId, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "StreamId":
			if err := dec.StartValue(); err != nil {
				return err
			}
			var err error
			if x.StreamId, err = dec.DecodeString(); err != nil {
				return err
			}
			if err := dec.FinishValue(); err != nil {
				return err
			}
		case "Timestamp":
			var wire time_2.Time
			if err := wire.VDLRead(dec); err != nil {
				return err
			}
			if err := time_2.TimeToNative(wire, &x.Timestamp); err != nil {
				return err
			}
		default:
			if err := dec.SkipValue(); err != nil {
				return err
			}
		}
	}
}

type (
	// VDataPoint represents any single field of the VDataPoint union type.
	VDataPoint interface {
		// Index returns the field index.
		Index() int
		// Interface returns the field value as an interface.
		Interface() interface{}
		// Name returns the field name.
		Name() string
		// __VDLReflect describes the VDataPoint union type.
		__VDLReflect(__VDataPointReflect)
		FillVDLTarget(vdl.Target, *vdl.Type) error
		VDLIsZero() (bool, error)
		VDLWrite(vdl.Encoder) error
	}
	// VDataPointValue represents field Value of the VDataPoint union type.
	VDataPointValue struct{ Value float64 }
	// VDataPointError represents field Error of the VDataPoint union type.
	VDataPointError struct{ Value string }
	// __VDataPointReflect describes the VDataPoint union type.
	__VDataPointReflect struct {
		Name               string `vdl:"v.io/x/sensorlog/internal/sbmodel.VDataPoint"`
		Type               VDataPoint
		UnionTargetFactory vDataPointTargetFactory
		Union              struct {
			Value VDataPointValue
			Error VDataPointError
		}
	}
)

func (x VDataPointValue) Index() int                       { return 0 }
func (x VDataPointValue) Interface() interface{}           { return x.Value }
func (x VDataPointValue) Name() string                     { return "Value" }
func (x VDataPointValue) __VDLReflect(__VDataPointReflect) {}

func (m VDataPointValue) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Value")
	if err != nil {
		return err
	}
	if err := fieldTarget3.FromFloat(float64(m.Value), tt.NonOptional().Field(0).Type); err != nil {
		return err
	}
	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
		return err
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}

	return nil
}

func (m VDataPointValue) MakeVDLTarget() vdl.Target {
	return nil
}

func (x VDataPointError) Index() int                       { return 1 }
func (x VDataPointError) Interface() interface{}           { return x.Value }
func (x VDataPointError) Name() string                     { return "Error" }
func (x VDataPointError) __VDLReflect(__VDataPointReflect) {}

func (m VDataPointError) FillVDLTarget(t vdl.Target, tt *vdl.Type) error {
	fieldsTarget1, err := t.StartFields(tt)
	if err != nil {
		return err
	}
	keyTarget2, fieldTarget3, err := fieldsTarget1.StartField("Error")
	if err != nil {
		return err
	}
	if err := fieldTarget3.FromString(string(m.Value), tt.NonOptional().Field(1).Type); err != nil {
		return err
	}
	if err := fieldsTarget1.FinishField(keyTarget2, fieldTarget3); err != nil {
		return err
	}
	if err := t.FinishFields(fieldsTarget1); err != nil {
		return err
	}

	return nil
}

func (m VDataPointError) MakeVDLTarget() vdl.Target {
	return nil
}

type VDataPointTarget struct {
	Value     *VDataPoint
	fieldName string

	vdl.TargetBase
	vdl.FieldsTargetBase
}

func (t *VDataPointTarget) StartFields(tt *vdl.Type) (vdl.FieldsTarget, error) {
	if ttWant := vdl.TypeOf((*VDataPoint)(nil)); !vdl.Compatible(tt, ttWant) {
		return nil, fmt.Errorf("type %v incompatible with %v", tt, ttWant)
	}

	return t, nil
}
func (t *VDataPointTarget) StartField(name string) (key, field vdl.Target, _ error) {
	t.fieldName = name
	switch name {
	case "Value":
		val := float64(0)
		return nil, &vdl.Float64Target{Value: &val}, nil
	case "Error":
		val := ""
		return nil, &vdl.StringTarget{Value: &val}, nil
	default:
		return nil, nil, fmt.Errorf("field %s not in union v.io/x/sensorlog/internal/sbmodel.VDataPoint", name)
	}
}
func (t *VDataPointTarget) FinishField(_, fieldTarget vdl.Target) error {
	switch t.fieldName {
	case "Value":
		*t.Value = VDataPointValue{*(fieldTarget.(*vdl.Float64Target)).Value}
	case "Error":
		*t.Value = VDataPointError{*(fieldTarget.(*vdl.StringTarget)).Value}
	}
	return nil
}
func (t *VDataPointTarget) FinishFields(_ vdl.FieldsTarget) error {

	return nil
}

type vDataPointTargetFactory struct{}

func (t vDataPointTargetFactory) VDLMakeUnionTarget(union interface{}) (vdl.Target, error) {
	if typedUnion, ok := union.(*VDataPoint); ok {
		return &VDataPointTarget{Value: typedUnion}, nil
	}
	return nil, fmt.Errorf("got %T, want *VDataPoint", union)
}

func (x VDataPointValue) VDLIsZero() (bool, error) {
	return x.Value == 0, nil
}

func (x VDataPointError) VDLIsZero() (bool, error) {
	return false, nil
}

func (x VDataPointValue) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*VDataPoint)(nil))); err != nil {
		return err
	}
	if err := enc.NextField("Value"); err != nil {
		return err
	}
	if err := enc.StartValue(vdl.TypeOf((*float64)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeFloat(x.Value); err != nil {
		return err
	}
	if err := enc.FinishValue(); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x VDataPointError) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(vdl.TypeOf((*VDataPoint)(nil))); err != nil {
		return err
	}
	if err := enc.NextField("Error"); err != nil {
		return err
	}
	if err := enc.StartValue(vdl.TypeOf((*string)(nil))); err != nil {
		return err
	}
	if err := enc.EncodeString(x.Value); err != nil {
		return err
	}
	if err := enc.FinishValue(); err != nil {
		return err
	}
	if err := enc.NextField(""); err != nil {
		return err
	}
	return enc.FinishValue()
}

func VDLReadVDataPoint(dec vdl.Decoder, x *VDataPoint) 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 union %T, from %v", x, dec.Type())
	}
	f, err := dec.NextField()
	if err != nil {
		return err
	}
	switch f {
	case "Value":
		var field VDataPointValue
		if err := dec.StartValue(); err != nil {
			return err
		}
		var err error
		if field.Value, err = dec.DecodeFloat(64); err != nil {
			return err
		}
		if err := dec.FinishValue(); err != nil {
			return err
		}
		*x = field
	case "Error":
		var field VDataPointError
		if err := dec.StartValue(); err != nil {
			return err
		}
		var err error
		if field.Value, err = dec.DecodeString(); err != nil {
			return err
		}
		if err := dec.FinishValue(); err != nil {
			return err
		}
		*x = field
	case "":
		return fmt.Errorf("missing field in union %T, from %v", x, dec.Type())
	default:
		return fmt.Errorf("field %q not in union %T, from %v", f, x, dec.Type())
	}
	switch f, err := dec.NextField(); {
	case err != nil:
		return err
	case f != "":
		return fmt.Errorf("extra field %q in union %T, from %v", f, x, dec.Type())
	}
	return dec.FinishValue()
}

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((*VDeviceCfg)(nil))
	vdl.Register((*KDeviceCfg)(nil))
	vdl.Register((*SamplerDef)(nil))
	vdl.Register((*VStreamDef)(nil))
	vdl.Register((*KStreamDef)(nil))
	vdl.Register((*KDataPoint)(nil))
	vdl.Register((*VDataPoint)(nil))

	return struct{}{}
}
