diff --git a/go/src/v.io/x/sensorlog/internal/sbmodel/sbmodel.vdl.go b/go/src/v.io/x/sensorlog/internal/sbmodel/sbmodel.vdl.go
index 53ebf0a..3cfd1a7 100644
--- a/go/src/v.io/x/sensorlog/internal/sbmodel/sbmodel.vdl.go
+++ b/go/src/v.io/x/sensorlog/internal/sbmodel/sbmodel.vdl.go
@@ -39,108 +39,6 @@
 }) {
 }
 
-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, vdl.ErrFieldNoExist
-	}
-}
-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 vdl.ErrFieldNoExist
-	}
-}
-func (t *VDeviceCfgTarget) FinishFields(_ vdl.FieldsTarget) error {
-
-	return nil
-}
-
 func (x VDeviceCfg) VDLIsZero() bool {
 	return x == VDeviceCfg{}
 }
@@ -238,81 +136,6 @@
 }) {
 }
 
-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, vdl.ErrFieldNoExist
-	}
-}
-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 vdl.ErrFieldNoExist
-	}
-}
-func (t *KDeviceCfgTarget) FinishFields(_ vdl.FieldsTarget) error {
-
-	return nil
-}
-
 func (x KDeviceCfg) VDLIsZero() bool {
 	return x == KDeviceCfg{}
 }
@@ -391,147 +214,6 @@
 }) {
 }
 
-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 vdltime.Time
-	if err := vdltime.TimeFromNative(&wireValue5, m.Start); err != nil {
-		return err
-	}
-
-	var8 := (wireValue5 == vdltime.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 vdltime.Duration
-	if err := vdltime.DurationFromNative(&wireValue9, m.Interval); err != nil {
-		return err
-	}
-
-	var12 := (wireValue9 == vdltime.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    vdltime.TimeTarget
-	intervalTarget vdltime.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, vdl.ErrFieldNoExist
-	}
-}
-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 = time.Time{}
-		return nil
-	case "Interval":
-		t.Value.Interval = time.Duration(0)
-		return nil
-	default:
-		return vdl.ErrFieldNoExist
-	}
-}
-func (t *SamplerDefTarget) FinishFields(_ vdl.FieldsTarget) error {
-
-	return nil
-}
-
 func (x SamplerDef) VDLIsZero() bool {
 	if x.Script != "" {
 		return false
@@ -660,136 +342,6 @@
 }) {
 }
 
-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, vdl.ErrFieldNoExist
-	}
-}
-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 vdl.ErrFieldNoExist
-	}
-}
-func (t *VStreamDefTarget) FinishFields(_ vdl.FieldsTarget) error {
-
-	return nil
-}
-
 func (x VStreamDef) VDLIsZero() bool {
 	if x.Desc != "" {
 		return false
@@ -909,108 +461,6 @@
 }) {
 }
 
-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, vdl.ErrFieldNoExist
-	}
-}
-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 vdl.ErrFieldNoExist
-	}
-}
-func (t *KStreamDefTarget) FinishFields(_ vdl.FieldsTarget) error {
-
-	return nil
-}
-
 func (x KStreamDef) VDLIsZero() bool {
 	return x == KStreamDef{}
 }
@@ -1112,141 +562,6 @@
 }) {
 }
 
-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 vdltime.Time
-	if err := vdltime.TimeFromNative(&wireValue8, m.Timestamp); err != nil {
-		return err
-	}
-
-	var11 := (wireValue8 == vdltime.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 vdltime.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, vdl.ErrFieldNoExist
-	}
-}
-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 = time.Time{}
-		return nil
-	default:
-		return vdl.ErrFieldNoExist
-	}
-}
-func (t *KDataPointTarget) FinishFields(_ vdl.FieldsTarget) error {
-
-	return nil
-}
-
 func (x KDataPoint) VDLIsZero() bool {
 	if x.DevId != "" {
 		return false
@@ -1375,7 +690,6 @@
 		Name() string
 		// __VDLReflect describes the VDataPoint union type.
 		__VDLReflect(__VDataPointReflect)
-		FillVDLTarget(vdl.Target, *vdl.Type) error
 		VDLIsZero() bool
 		VDLWrite(vdl.Encoder) error
 	}
@@ -1385,10 +699,9 @@
 	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 {
+		Name  string `vdl:"v.io/x/sensorlog/internal/sbmodel.VDataPoint"`
+		Type  VDataPoint
+		Union struct {
 			Value VDataPointValue
 			Error VDataPointError
 		}
@@ -1400,114 +713,11 @@
 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 {
 	return x.Value == 0
 }
