sensorlog: Add VDL codegen for VDLRead(vdl.Decoder) method of each type

This CL adds codegen support to the vdl compiler for the VDLRead
method, which is used for fast decoding via the vom.XDecoder.
The VDLRead approach is simpler and much faster than the old
vdl.Target interface approach, since it doesn't require any
reflection, and doesn't need to allocate new Targets.  Eventually
vdl.Target and all of its associated codegen will be removed.

The only feature missing from this CL is support for the Any
type, which needs both vdl.Value and vom.RawBytes support for
VDLRead.  Those features will be added in a later CL.

MultiPart: 5/5

Change-Id: I509c6f11130f0a29133d9a0158bc65d2e8ddf987
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 d32b5d8..25ef054 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
@@ -141,6 +141,57 @@
 	return nil
 }
 
+func (x *VDeviceCfg) VDLRead(dec vdl.Decoder) error {
+	*x = VDeviceCfg{}
+	var err error
+	if err = dec.StartValue(); err != nil {
+		return err
+	}
+	if dec.Type().Kind() != vdl.Struct {
+		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
+	}
+	match := 0
+	for {
+		f, err := dec.NextField()
+		if err != nil {
+			return err
+		}
+		switch f {
+		case "":
+			if match == 0 && dec.Type().NumField() > 0 {
+				return fmt.Errorf("no matching fields in struct %T, from %v", *x, dec.Type())
+			}
+			return dec.FinishValue()
+		case "Desc":
+			match++
+			if err = dec.StartValue(); err != nil {
+				return err
+			}
+			if x.Desc, err = dec.DecodeString(); err != nil {
+				return err
+			}
+			if err = dec.FinishValue(); err != nil {
+				return err
+			}
+		case "SgPublishSb":
+			match++
+			if err = dec.StartValue(); err != nil {
+				return err
+			}
+			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
 }
@@ -225,6 +276,46 @@
 	return nil
 }
 
+func (x *KDeviceCfg) VDLRead(dec vdl.Decoder) error {
+	*x = KDeviceCfg{}
+	var err error
+	if err = dec.StartValue(); err != nil {
+		return err
+	}
+	if dec.Type().Kind() != vdl.Struct {
+		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
+	}
+	match := 0
+	for {
+		f, err := dec.NextField()
+		if err != nil {
+			return err
+		}
+		switch f {
+		case "":
+			if match == 0 && dec.Type().NumField() > 0 {
+				return fmt.Errorf("no matching fields in struct %T, from %v", *x, dec.Type())
+			}
+			return dec.FinishValue()
+		case "DevId":
+			match++
+			if err = dec.StartValue(); err != nil {
+				return err
+			}
+			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.
@@ -393,6 +484,64 @@
 	return nil
 }
 
+func (x *SamplerDef) VDLRead(dec vdl.Decoder) error {
+	*x = SamplerDef{}
+	var err error
+	if err = dec.StartValue(); err != nil {
+		return err
+	}
+	if dec.Type().Kind() != vdl.Struct {
+		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
+	}
+	match := 0
+	for {
+		f, err := dec.NextField()
+		if err != nil {
+			return err
+		}
+		switch f {
+		case "":
+			if match == 0 && dec.Type().NumField() > 0 {
+				return fmt.Errorf("no matching fields in struct %T, from %v", *x, dec.Type())
+			}
+			return dec.FinishValue()
+		case "Script":
+			match++
+			if err = dec.StartValue(); err != nil {
+				return err
+			}
+			if x.Script, err = dec.DecodeString(); err != nil {
+				return err
+			}
+			if err = dec.FinishValue(); err != nil {
+				return err
+			}
+		case "Start":
+			match++
+			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":
+			match++
+			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 {
@@ -539,6 +688,62 @@
 	return nil
 }
 
+func (x *VStreamDef) VDLRead(dec vdl.Decoder) error {
+	*x = VStreamDef{}
+	var err error
+	if err = dec.StartValue(); err != nil {
+		return err
+	}
+	if dec.Type().Kind() != vdl.Struct {
+		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
+	}
+	match := 0
+	for {
+		f, err := dec.NextField()
+		if err != nil {
+			return err
+		}
+		switch f {
+		case "":
+			if match == 0 && dec.Type().NumField() > 0 {
+				return fmt.Errorf("no matching fields in struct %T, from %v", *x, dec.Type())
+			}
+			return dec.FinishValue()
+		case "Desc":
+			match++
+			if err = dec.StartValue(); err != nil {
+				return err
+			}
+			if x.Desc, err = dec.DecodeString(); err != nil {
+				return err
+			}
+			if err = dec.FinishValue(); err != nil {
+				return err
+			}
+		case "Sampler":
+			match++
+			if err = x.Sampler.VDLRead(dec); err != nil {
+				return err
+			}
+		case "Enabled":
+			match++
+			if err = dec.StartValue(); err != nil {
+				return err
+			}
+			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
@@ -651,6 +856,57 @@
 	return nil
 }
 
+func (x *KStreamDef) VDLRead(dec vdl.Decoder) error {
+	*x = KStreamDef{}
+	var err error
+	if err = dec.StartValue(); err != nil {
+		return err
+	}
+	if dec.Type().Kind() != vdl.Struct {
+		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
+	}
+	match := 0
+	for {
+		f, err := dec.NextField()
+		if err != nil {
+			return err
+		}
+		switch f {
+		case "":
+			if match == 0 && dec.Type().NumField() > 0 {
+				return fmt.Errorf("no matching fields in struct %T, from %v", *x, dec.Type())
+			}
+			return dec.FinishValue()
+		case "DevId":
+			match++
+			if err = dec.StartValue(); err != nil {
+				return err
+			}
+			if x.DevId, err = dec.DecodeString(); err != nil {
+				return err
+			}
+			if err = dec.FinishValue(); err != nil {
+				return err
+			}
+		case "StreamId":
+			match++
+			if err = dec.StartValue(); err != nil {
+				return err
+			}
+			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 {
@@ -805,6 +1061,66 @@
 	return nil
 }
 
+func (x *KDataPoint) VDLRead(dec vdl.Decoder) error {
+	*x = KDataPoint{}
+	var err error
+	if err = dec.StartValue(); err != nil {
+		return err
+	}
+	if dec.Type().Kind() != vdl.Struct {
+		return fmt.Errorf("incompatible struct %T, from %v", *x, dec.Type())
+	}
+	match := 0
+	for {
+		f, err := dec.NextField()
+		if err != nil {
+			return err
+		}
+		switch f {
+		case "":
+			if match == 0 && dec.Type().NumField() > 0 {
+				return fmt.Errorf("no matching fields in struct %T, from %v", *x, dec.Type())
+			}
+			return dec.FinishValue()
+		case "DevId":
+			match++
+			if err = dec.StartValue(); err != nil {
+				return err
+			}
+			if x.DevId, err = dec.DecodeString(); err != nil {
+				return err
+			}
+			if err = dec.FinishValue(); err != nil {
+				return err
+			}
+		case "StreamId":
+			match++
+			if err = dec.StartValue(); err != nil {
+				return err
+			}
+			if x.StreamId, err = dec.DecodeString(); err != nil {
+				return err
+			}
+			if err = dec.FinishValue(); err != nil {
+				return err
+			}
+		case "Timestamp":
+			match++
+			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 {
@@ -947,6 +1263,57 @@
 	return nil, fmt.Errorf("got %T, want *VDataPoint", union)
 }
 
+func VDLReadVDataPoint(dec vdl.Decoder, x *VDataPoint) error {
+	var err error
+	if err = dec.StartValue(); err != nil {
+		return err
+	}
+	if dec.Type().Kind() != vdl.Union {
+		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
+		}
+		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
+		}
+		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.