1// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package keys
6
7import (
8	"fmt"
9	"io"
10	"math"
11	"strconv"
12
13	"golang.org/x/tools/internal/event/label"
14)
15
16// Value represents a key for untyped values.
17type Value struct {
18	name        string
19	description string
20}
21
22// New creates a new Key for untyped values.
23func New(name, description string) *Value {
24	return &Value{name: name, description: description}
25}
26
27func (k *Value) Name() string        { return k.name }
28func (k *Value) Description() string { return k.description }
29
30func (k *Value) Format(w io.Writer, buf []byte, l label.Label) {
31	fmt.Fprint(w, k.From(l))
32}
33
34// Get can be used to get a label for the key from a label.Map.
35func (k *Value) Get(lm label.Map) interface{} {
36	if t := lm.Find(k); t.Valid() {
37		return k.From(t)
38	}
39	return nil
40}
41
42// From can be used to get a value from a Label.
43func (k *Value) From(t label.Label) interface{} { return t.UnpackValue() }
44
45// Of creates a new Label with this key and the supplied value.
46func (k *Value) Of(value interface{}) label.Label { return label.OfValue(k, value) }
47
48// Tag represents a key for tagging labels that have no value.
49// These are used when the existence of the label is the entire information it
50// carries, such as marking events to be of a specific kind, or from a specific
51// package.
52type Tag struct {
53	name        string
54	description string
55}
56
57// NewTag creates a new Key for tagging labels.
58func NewTag(name, description string) *Tag {
59	return &Tag{name: name, description: description}
60}
61
62func (k *Tag) Name() string        { return k.name }
63func (k *Tag) Description() string { return k.description }
64
65func (k *Tag) Format(w io.Writer, buf []byte, l label.Label) {}
66
67// New creates a new Label with this key.
68func (k *Tag) New() label.Label { return label.OfValue(k, nil) }
69
70// Int represents a key
71type Int struct {
72	name        string
73	description string
74}
75
76// NewInt creates a new Key for int values.
77func NewInt(name, description string) *Int {
78	return &Int{name: name, description: description}
79}
80
81func (k *Int) Name() string        { return k.name }
82func (k *Int) Description() string { return k.description }
83
84func (k *Int) Format(w io.Writer, buf []byte, l label.Label) {
85	w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
86}
87
88// Of creates a new Label with this key and the supplied value.
89func (k *Int) Of(v int) label.Label { return label.Of64(k, uint64(v)) }
90
91// Get can be used to get a label for the key from a label.Map.
92func (k *Int) Get(lm label.Map) int {
93	if t := lm.Find(k); t.Valid() {
94		return k.From(t)
95	}
96	return 0
97}
98
99// From can be used to get a value from a Label.
100func (k *Int) From(t label.Label) int { return int(t.Unpack64()) }
101
102// Int8 represents a key
103type Int8 struct {
104	name        string
105	description string
106}
107
108// NewInt8 creates a new Key for int8 values.
109func NewInt8(name, description string) *Int8 {
110	return &Int8{name: name, description: description}
111}
112
113func (k *Int8) Name() string        { return k.name }
114func (k *Int8) Description() string { return k.description }
115
116func (k *Int8) Format(w io.Writer, buf []byte, l label.Label) {
117	w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
118}
119
120// Of creates a new Label with this key and the supplied value.
121func (k *Int8) Of(v int8) label.Label { return label.Of64(k, uint64(v)) }
122
123// Get can be used to get a label for the key from a label.Map.
124func (k *Int8) Get(lm label.Map) int8 {
125	if t := lm.Find(k); t.Valid() {
126		return k.From(t)
127	}
128	return 0
129}
130
131// From can be used to get a value from a Label.
132func (k *Int8) From(t label.Label) int8 { return int8(t.Unpack64()) }
133
134// Int16 represents a key
135type Int16 struct {
136	name        string
137	description string
138}
139
140// NewInt16 creates a new Key for int16 values.
141func NewInt16(name, description string) *Int16 {
142	return &Int16{name: name, description: description}
143}
144
145func (k *Int16) Name() string        { return k.name }
146func (k *Int16) Description() string { return k.description }
147
148func (k *Int16) Format(w io.Writer, buf []byte, l label.Label) {
149	w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
150}
151
152// Of creates a new Label with this key and the supplied value.
153func (k *Int16) Of(v int16) label.Label { return label.Of64(k, uint64(v)) }
154
155// Get can be used to get a label for the key from a label.Map.
156func (k *Int16) Get(lm label.Map) int16 {
157	if t := lm.Find(k); t.Valid() {
158		return k.From(t)
159	}
160	return 0
161}
162
163// From can be used to get a value from a Label.
164func (k *Int16) From(t label.Label) int16 { return int16(t.Unpack64()) }
165
166// Int32 represents a key
167type Int32 struct {
168	name        string
169	description string
170}
171
172// NewInt32 creates a new Key for int32 values.
173func NewInt32(name, description string) *Int32 {
174	return &Int32{name: name, description: description}
175}
176
177func (k *Int32) Name() string        { return k.name }
178func (k *Int32) Description() string { return k.description }
179
180func (k *Int32) Format(w io.Writer, buf []byte, l label.Label) {
181	w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
182}
183
184// Of creates a new Label with this key and the supplied value.
185func (k *Int32) Of(v int32) label.Label { return label.Of64(k, uint64(v)) }
186
187// Get can be used to get a label for the key from a label.Map.
188func (k *Int32) Get(lm label.Map) int32 {
189	if t := lm.Find(k); t.Valid() {
190		return k.From(t)
191	}
192	return 0
193}
194
195// From can be used to get a value from a Label.
196func (k *Int32) From(t label.Label) int32 { return int32(t.Unpack64()) }
197
198// Int64 represents a key
199type Int64 struct {
200	name        string
201	description string
202}
203
204// NewInt64 creates a new Key for int64 values.
205func NewInt64(name, description string) *Int64 {
206	return &Int64{name: name, description: description}
207}
208
209func (k *Int64) Name() string        { return k.name }
210func (k *Int64) Description() string { return k.description }
211
212func (k *Int64) Format(w io.Writer, buf []byte, l label.Label) {
213	w.Write(strconv.AppendInt(buf, k.From(l), 10))
214}
215
216// Of creates a new Label with this key and the supplied value.
217func (k *Int64) Of(v int64) label.Label { return label.Of64(k, uint64(v)) }
218
219// Get can be used to get a label for the key from a label.Map.
220func (k *Int64) Get(lm label.Map) int64 {
221	if t := lm.Find(k); t.Valid() {
222		return k.From(t)
223	}
224	return 0
225}
226
227// From can be used to get a value from a Label.
228func (k *Int64) From(t label.Label) int64 { return int64(t.Unpack64()) }
229
230// UInt represents a key
231type UInt struct {
232	name        string
233	description string
234}
235
236// NewUInt creates a new Key for uint values.
237func NewUInt(name, description string) *UInt {
238	return &UInt{name: name, description: description}
239}
240
241func (k *UInt) Name() string        { return k.name }
242func (k *UInt) Description() string { return k.description }
243
244func (k *UInt) Format(w io.Writer, buf []byte, l label.Label) {
245	w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
246}
247
248// Of creates a new Label with this key and the supplied value.
249func (k *UInt) Of(v uint) label.Label { return label.Of64(k, uint64(v)) }
250
251// Get can be used to get a label for the key from a label.Map.
252func (k *UInt) Get(lm label.Map) uint {
253	if t := lm.Find(k); t.Valid() {
254		return k.From(t)
255	}
256	return 0
257}
258
259// From can be used to get a value from a Label.
260func (k *UInt) From(t label.Label) uint { return uint(t.Unpack64()) }
261
262// UInt8 represents a key
263type UInt8 struct {
264	name        string
265	description string
266}
267
268// NewUInt8 creates a new Key for uint8 values.
269func NewUInt8(name, description string) *UInt8 {
270	return &UInt8{name: name, description: description}
271}
272
273func (k *UInt8) Name() string        { return k.name }
274func (k *UInt8) Description() string { return k.description }
275
276func (k *UInt8) Format(w io.Writer, buf []byte, l label.Label) {
277	w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
278}
279
280// Of creates a new Label with this key and the supplied value.
281func (k *UInt8) Of(v uint8) label.Label { return label.Of64(k, uint64(v)) }
282
283// Get can be used to get a label for the key from a label.Map.
284func (k *UInt8) Get(lm label.Map) uint8 {
285	if t := lm.Find(k); t.Valid() {
286		return k.From(t)
287	}
288	return 0
289}
290
291// From can be used to get a value from a Label.
292func (k *UInt8) From(t label.Label) uint8 { return uint8(t.Unpack64()) }
293
294// UInt16 represents a key
295type UInt16 struct {
296	name        string
297	description string
298}
299
300// NewUInt16 creates a new Key for uint16 values.
301func NewUInt16(name, description string) *UInt16 {
302	return &UInt16{name: name, description: description}
303}
304
305func (k *UInt16) Name() string        { return k.name }
306func (k *UInt16) Description() string { return k.description }
307
308func (k *UInt16) Format(w io.Writer, buf []byte, l label.Label) {
309	w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
310}
311
312// Of creates a new Label with this key and the supplied value.
313func (k *UInt16) Of(v uint16) label.Label { return label.Of64(k, uint64(v)) }
314
315// Get can be used to get a label for the key from a label.Map.
316func (k *UInt16) Get(lm label.Map) uint16 {
317	if t := lm.Find(k); t.Valid() {
318		return k.From(t)
319	}
320	return 0
321}
322
323// From can be used to get a value from a Label.
324func (k *UInt16) From(t label.Label) uint16 { return uint16(t.Unpack64()) }
325
326// UInt32 represents a key
327type UInt32 struct {
328	name        string
329	description string
330}
331
332// NewUInt32 creates a new Key for uint32 values.
333func NewUInt32(name, description string) *UInt32 {
334	return &UInt32{name: name, description: description}
335}
336
337func (k *UInt32) Name() string        { return k.name }
338func (k *UInt32) Description() string { return k.description }
339
340func (k *UInt32) Format(w io.Writer, buf []byte, l label.Label) {
341	w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
342}
343
344// Of creates a new Label with this key and the supplied value.
345func (k *UInt32) Of(v uint32) label.Label { return label.Of64(k, uint64(v)) }
346
347// Get can be used to get a label for the key from a label.Map.
348func (k *UInt32) Get(lm label.Map) uint32 {
349	if t := lm.Find(k); t.Valid() {
350		return k.From(t)
351	}
352	return 0
353}
354
355// From can be used to get a value from a Label.
356func (k *UInt32) From(t label.Label) uint32 { return uint32(t.Unpack64()) }
357
358// UInt64 represents a key
359type UInt64 struct {
360	name        string
361	description string
362}
363
364// NewUInt64 creates a new Key for uint64 values.
365func NewUInt64(name, description string) *UInt64 {
366	return &UInt64{name: name, description: description}
367}
368
369func (k *UInt64) Name() string        { return k.name }
370func (k *UInt64) Description() string { return k.description }
371
372func (k *UInt64) Format(w io.Writer, buf []byte, l label.Label) {
373	w.Write(strconv.AppendUint(buf, k.From(l), 10))
374}
375
376// Of creates a new Label with this key and the supplied value.
377func (k *UInt64) Of(v uint64) label.Label { return label.Of64(k, v) }
378
379// Get can be used to get a label for the key from a label.Map.
380func (k *UInt64) Get(lm label.Map) uint64 {
381	if t := lm.Find(k); t.Valid() {
382		return k.From(t)
383	}
384	return 0
385}
386
387// From can be used to get a value from a Label.
388func (k *UInt64) From(t label.Label) uint64 { return t.Unpack64() }
389
390// Float32 represents a key
391type Float32 struct {
392	name        string
393	description string
394}
395
396// NewFloat32 creates a new Key for float32 values.
397func NewFloat32(name, description string) *Float32 {
398	return &Float32{name: name, description: description}
399}
400
401func (k *Float32) Name() string        { return k.name }
402func (k *Float32) Description() string { return k.description }
403
404func (k *Float32) Format(w io.Writer, buf []byte, l label.Label) {
405	w.Write(strconv.AppendFloat(buf, float64(k.From(l)), 'E', -1, 32))
406}
407
408// Of creates a new Label with this key and the supplied value.
409func (k *Float32) Of(v float32) label.Label {
410	return label.Of64(k, uint64(math.Float32bits(v)))
411}
412
413// Get can be used to get a label for the key from a label.Map.
414func (k *Float32) Get(lm label.Map) float32 {
415	if t := lm.Find(k); t.Valid() {
416		return k.From(t)
417	}
418	return 0
419}
420
421// From can be used to get a value from a Label.
422func (k *Float32) From(t label.Label) float32 {
423	return math.Float32frombits(uint32(t.Unpack64()))
424}
425
426// Float64 represents a key
427type Float64 struct {
428	name        string
429	description string
430}
431
432// NewFloat64 creates a new Key for int64 values.
433func NewFloat64(name, description string) *Float64 {
434	return &Float64{name: name, description: description}
435}
436
437func (k *Float64) Name() string        { return k.name }
438func (k *Float64) Description() string { return k.description }
439
440func (k *Float64) Format(w io.Writer, buf []byte, l label.Label) {
441	w.Write(strconv.AppendFloat(buf, k.From(l), 'E', -1, 64))
442}
443
444// Of creates a new Label with this key and the supplied value.
445func (k *Float64) Of(v float64) label.Label {
446	return label.Of64(k, math.Float64bits(v))
447}
448
449// Get can be used to get a label for the key from a label.Map.
450func (k *Float64) Get(lm label.Map) float64 {
451	if t := lm.Find(k); t.Valid() {
452		return k.From(t)
453	}
454	return 0
455}
456
457// From can be used to get a value from a Label.
458func (k *Float64) From(t label.Label) float64 {
459	return math.Float64frombits(t.Unpack64())
460}
461
462// String represents a key
463type String struct {
464	name        string
465	description string
466}
467
468// NewString creates a new Key for int64 values.
469func NewString(name, description string) *String {
470	return &String{name: name, description: description}
471}
472
473func (k *String) Name() string        { return k.name }
474func (k *String) Description() string { return k.description }
475
476func (k *String) Format(w io.Writer, buf []byte, l label.Label) {
477	w.Write(strconv.AppendQuote(buf, k.From(l)))
478}
479
480// Of creates a new Label with this key and the supplied value.
481func (k *String) Of(v string) label.Label { return label.OfString(k, v) }
482
483// Get can be used to get a label for the key from a label.Map.
484func (k *String) Get(lm label.Map) string {
485	if t := lm.Find(k); t.Valid() {
486		return k.From(t)
487	}
488	return ""
489}
490
491// From can be used to get a value from a Label.
492func (k *String) From(t label.Label) string { return t.UnpackString() }
493
494// Boolean represents a key
495type Boolean struct {
496	name        string
497	description string
498}
499
500// NewBoolean creates a new Key for bool values.
501func NewBoolean(name, description string) *Boolean {
502	return &Boolean{name: name, description: description}
503}
504
505func (k *Boolean) Name() string        { return k.name }
506func (k *Boolean) Description() string { return k.description }
507
508func (k *Boolean) Format(w io.Writer, buf []byte, l label.Label) {
509	w.Write(strconv.AppendBool(buf, k.From(l)))
510}
511
512// Of creates a new Label with this key and the supplied value.
513func (k *Boolean) Of(v bool) label.Label {
514	if v {
515		return label.Of64(k, 1)
516	}
517	return label.Of64(k, 0)
518}
519
520// Get can be used to get a label for the key from a label.Map.
521func (k *Boolean) Get(lm label.Map) bool {
522	if t := lm.Find(k); t.Valid() {
523		return k.From(t)
524	}
525	return false
526}
527
528// From can be used to get a value from a Label.
529func (k *Boolean) From(t label.Label) bool { return t.Unpack64() > 0 }
530
531// Error represents a key
532type Error struct {
533	name        string
534	description string
535}
536
537// NewError creates a new Key for int64 values.
538func NewError(name, description string) *Error {
539	return &Error{name: name, description: description}
540}
541
542func (k *Error) Name() string        { return k.name }
543func (k *Error) Description() string { return k.description }
544
545func (k *Error) Format(w io.Writer, buf []byte, l label.Label) {
546	io.WriteString(w, k.From(l).Error())
547}
548
549// Of creates a new Label with this key and the supplied value.
550func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) }
551
552// Get can be used to get a label for the key from a label.Map.
553func (k *Error) Get(lm label.Map) error {
554	if t := lm.Find(k); t.Valid() {
555		return k.From(t)
556	}
557	return nil
558}
559
560// From can be used to get a value from a Label.
561func (k *Error) From(t label.Label) error {
562	err, _ := t.UnpackValue().(error)
563	return err
564}
565