Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / internal / event / export / trace.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/internal/event/export/trace.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/internal/event/export/trace.go
new file mode 100644 (file)
index 0000000..1a99482
--- /dev/null
@@ -0,0 +1,117 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package export
+
+import (
+       "context"
+       "fmt"
+       "sync"
+
+       "golang.org/x/tools/internal/event"
+       "golang.org/x/tools/internal/event/core"
+       "golang.org/x/tools/internal/event/keys"
+       "golang.org/x/tools/internal/event/label"
+)
+
+type SpanContext struct {
+       TraceID TraceID
+       SpanID  SpanID
+}
+
+type Span struct {
+       Name     string
+       ID       SpanContext
+       ParentID SpanID
+       mu       sync.Mutex
+       start    core.Event
+       finish   core.Event
+       events   []core.Event
+}
+
+type contextKeyType int
+
+const (
+       spanContextKey = contextKeyType(iota)
+       labelContextKey
+)
+
+func GetSpan(ctx context.Context) *Span {
+       v := ctx.Value(spanContextKey)
+       if v == nil {
+               return nil
+       }
+       return v.(*Span)
+}
+
+// Spans creates an exporter that maintains hierarchical span structure in the
+// context.
+// It creates new spans on start events, adds events to the current span on
+// log or label, and closes the span on end events.
+// The span structure can then be used by other exporters.
+func Spans(output event.Exporter) event.Exporter {
+       return func(ctx context.Context, ev core.Event, lm label.Map) context.Context {
+               switch {
+               case event.IsLog(ev), event.IsLabel(ev):
+                       if span := GetSpan(ctx); span != nil {
+                               span.mu.Lock()
+                               span.events = append(span.events, ev)
+                               span.mu.Unlock()
+                       }
+               case event.IsStart(ev):
+                       span := &Span{
+                               Name:  keys.Start.Get(lm),
+                               start: ev,
+                       }
+                       if parent := GetSpan(ctx); parent != nil {
+                               span.ID.TraceID = parent.ID.TraceID
+                               span.ParentID = parent.ID.SpanID
+                       } else {
+                               span.ID.TraceID = newTraceID()
+                       }
+                       span.ID.SpanID = newSpanID()
+                       ctx = context.WithValue(ctx, spanContextKey, span)
+               case event.IsEnd(ev):
+                       if span := GetSpan(ctx); span != nil {
+                               span.mu.Lock()
+                               span.finish = ev
+                               span.mu.Unlock()
+                       }
+               case event.IsDetach(ev):
+                       ctx = context.WithValue(ctx, spanContextKey, nil)
+               }
+               return output(ctx, ev, lm)
+       }
+}
+
+func (s *SpanContext) Format(f fmt.State, r rune) {
+       fmt.Fprintf(f, "%v:%v", s.TraceID, s.SpanID)
+}
+
+func (s *Span) Start() core.Event {
+       // start never changes after construction, so we dont need to hold the mutex
+       return s.start
+}
+
+func (s *Span) Finish() core.Event {
+       s.mu.Lock()
+       defer s.mu.Unlock()
+       return s.finish
+}
+
+func (s *Span) Events() []core.Event {
+       s.mu.Lock()
+       defer s.mu.Unlock()
+       return s.events
+}
+
+func (s *Span) Format(f fmt.State, r rune) {
+       s.mu.Lock()
+       defer s.mu.Unlock()
+       fmt.Fprintf(f, "%v %v", s.Name, s.ID)
+       if s.ParentID.IsValid() {
+               fmt.Fprintf(f, "[%v]", s.ParentID)
+       }
+       fmt.Fprintf(f, " %v->%v", s.start, s.finish)
+}