internal/telemetry: convert attributes using the key type

This uses the strongly typed key to get the value rather than
type switching on the value itself.

Change-Id: I8f72d1d9cac0191b0565c14d8a1108459ee6df36
Reviewed-on: https://go-review.googlesource.com/c/tools/+/225379
Run-TryBot: Ian Cottrell <iancottrell@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/internal/telemetry/export/ocagent/ocagent.go b/internal/telemetry/export/ocagent/ocagent.go
index 96134b1..86c2e8b 100644
--- a/internal/telemetry/export/ocagent/ocagent.go
+++ b/internal/telemetry/export/ocagent/ocagent.go
@@ -234,43 +234,47 @@
 	attributes := make(map[string]wire.Attribute)
 	for ; it.Valid(); it.Advance() {
 		tag := it.Tag()
-		attributes[tag.Key.Name()] = convertAttribute(tag.Value)
+		attributes[tag.Key.Name()] = convertAttribute(tag)
 	}
 	return &wire.Attributes{AttributeMap: attributes}
 }
 
-func convertAttribute(v interface{}) wire.Attribute {
-	switch v := v.(type) {
-	case int8:
-		return wire.IntAttribute{IntValue: int64(v)}
-	case int16:
-		return wire.IntAttribute{IntValue: int64(v)}
-	case int32:
-		return wire.IntAttribute{IntValue: int64(v)}
-	case int64:
-		return wire.IntAttribute{IntValue: v}
-	case int:
-		return wire.IntAttribute{IntValue: int64(v)}
-	case uint8:
-		return wire.IntAttribute{IntValue: int64(v)}
-	case uint16:
-		return wire.IntAttribute{IntValue: int64(v)}
-	case uint32:
-		return wire.IntAttribute{IntValue: int64(v)}
-	case uint64:
-		return wire.IntAttribute{IntValue: int64(v)}
-	case uint:
-		return wire.IntAttribute{IntValue: int64(v)}
-	case float32:
-		return wire.DoubleAttribute{DoubleValue: float64(v)}
-	case float64:
-		return wire.DoubleAttribute{DoubleValue: v}
-	case bool:
-		return wire.BoolAttribute{BoolValue: v}
-	case string:
-		return wire.StringAttribute{StringValue: toTruncatableString(v)}
+func convertAttribute(tag event.Tag) wire.Attribute {
+	switch key := tag.Key.(type) {
+	case *event.IntKey:
+		return wire.IntAttribute{IntValue: int64(key.From(tag))}
+	case *event.Int8Key:
+		return wire.IntAttribute{IntValue: int64(key.From(tag))}
+	case *event.Int16Key:
+		return wire.IntAttribute{IntValue: int64(key.From(tag))}
+	case *event.Int32Key:
+		return wire.IntAttribute{IntValue: int64(key.From(tag))}
+	case *event.Int64Key:
+		return wire.IntAttribute{IntValue: int64(key.From(tag))}
+	case *event.UIntKey:
+		return wire.IntAttribute{IntValue: int64(key.From(tag))}
+	case *event.UInt8Key:
+		return wire.IntAttribute{IntValue: int64(key.From(tag))}
+	case *event.UInt16Key:
+		return wire.IntAttribute{IntValue: int64(key.From(tag))}
+	case *event.UInt32Key:
+		return wire.IntAttribute{IntValue: int64(key.From(tag))}
+	case *event.UInt64Key:
+		return wire.IntAttribute{IntValue: int64(key.From(tag))}
+	case *event.Float32Key:
+		return wire.DoubleAttribute{DoubleValue: float64(key.From(tag))}
+	case *event.Float64Key:
+		return wire.DoubleAttribute{DoubleValue: key.From(tag)}
+	case *event.BooleanKey:
+		return wire.BoolAttribute{BoolValue: key.From(tag)}
+	case *event.StringKey:
+		return wire.StringAttribute{StringValue: toTruncatableString(key.From(tag))}
+	case *event.ErrorKey:
+		return wire.StringAttribute{StringValue: toTruncatableString(key.From(tag).Error())}
+	case *event.ValueKey:
+		return wire.StringAttribute{StringValue: toTruncatableString(fmt.Sprint(key.From(tag)))}
 	default:
-		return wire.StringAttribute{StringValue: toTruncatableString(fmt.Sprint(v))}
+		return wire.StringAttribute{StringValue: toTruncatableString(fmt.Sprintf("%T", key))}
 	}
 }