// Package diag exposes error types used throughout River and a method to1// pretty-print them to the screen.2package diag34import (5"fmt"67"github.com/grafana/agent/pkg/river/token"8)910// Severity denotes the severity level of a diagnostic. The zero value of11// severity is invalid.12type Severity int1314// Supported severity levels.15const (16SeverityLevelWarn Severity = iota + 117SeverityLevelError18)1920// Diagnostic is an individual diagnostic message. Diagnostic messages can have21// different levels of severities.22type Diagnostic struct {23// Severity holds the severity level of this Diagnostic.24Severity Severity2526// StartPos refers to a position in a file where this Diagnostic starts.27StartPos token.Position2829// EndPos refers to an optional position in a file where this Diagnostic30// ends. If EndPos is the zero value, the Diagnostic should be treated as31// only covering a single character (i.e., StartPos == EndPos).32//33// When defined, EndPos must have the same Filename value as the StartPos.34EndPos token.Position3536Message string37Value string38}3940// As allows d to be interpreted as a list of Diagnostics.41func (d Diagnostic) As(v interface{}) bool {42switch v := v.(type) {43case *Diagnostics:44*v = Diagnostics{d}45return true46}4748return false49}5051// Error implements error.52func (d Diagnostic) Error() string {53return fmt.Sprintf("%s: %s", d.StartPos, d.Message)54}5556// Diagnostics is a collection of diagnostic messages.57type Diagnostics []Diagnostic5859// Add adds an individual Diagnostic to the diagnostics list.60func (ds *Diagnostics) Add(d Diagnostic) {61*ds = append(*ds, d)62}6364// Error implements error.65func (ds Diagnostics) Error() string {66switch len(ds) {67case 0:68return "no errors"69case 1:70return ds[0].Error()71default:72return fmt.Sprintf("%s (and %d more diagnostics)", ds[0], len(ds)-1)73}74}7576// ErrorOrNil returns an error interface if the list diagnostics is non-empty,77// nil otherwise.78func (ds Diagnostics) ErrorOrNil() error {79if len(ds) == 0 {80return nil81}82return ds83}8485// HasErrors reports whether the list of Diagnostics contain any error-level86// diagnostic.87func (ds Diagnostics) HasErrors() bool {88for _, d := range ds {89if d.Severity == SeverityLevelError {90return true91}92}93return false94}959697