annotation

package
v1.6.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 19, 2026 License: MIT Imports: 14 Imported by: 0

README

Annotation

The Annotation package reads annotations from Go doc comments and returns the annotated declarations, so code generators (such as inject) can build on them.

Format

An annotation is a doc comment line that starts with // @:

// FooFunc handles the request.
// It is called by the router.
// @RestRouter(path=/foo, method=GET)
// @RestQueryParam(name=tags, type=string, description="comma, separated")
// @Invoke
func FooFunc(ctx context.Context) error { ... }
  • // @Name or // @Name(key=value, ...). A space between the name and the parentheses is allowed; //@Name (no space after //) is not an annotation.
  • Every value is a key=value pair or a bare name (a letter or _, then letters, digits, _, . or -), as in // @Middleware(log, hystrix). Bare names stay in Value/RawValue() and are left out of Map. Words after the name without parentheses (// @Param query foo bool) or with spaces inside a value without = are not a valid annotation and are ignored with a warning.
  • Values are split on top-level commas. Commas inside double quotes or brackets belong to the value, and only the first = separates the key (filter=a=b is filter: "a=b").
  • Unquoted values become int, float64 or bool (true/false) when they parse as such; quoted values are always strings.

Usage

collector, err := annotation.Collect(
	annotation.WithPath("."),                          // required: a directory inside a Go module
	annotation.WithFilters("Rest", "Inject"),          // optional: annotation name prefixes
	annotation.WithPackages("github.com/acme/service"), // optional: import paths to scan
)
if err != nil {
	return err
}

for _, entry := range collector.EntriesWith("RestRouter") {
	for _, ann := range entry.Annotations {
		var router struct {
			Path   string `attr:"path"`
			Method string `attr:"method"`
		}
		if err := ann.Decode(&router); err != nil {
			return err
		}
	}
}
Options
Option Behavior
WithPath(dir) Scans the packages under dir as go list ./... sees them from there: hidden (.), _, testdata and vendor directories are skipped. The packages they import are scanned too.
WithFilters(names...) Keeps only annotations whose name starts with one of the filters: Rest keeps @Rest, @RestRouter and @RestResponse. Without it, every annotation is kept.
WithPackages(paths...) Scans only these import paths and the packages below them, both under the path and among their imports. The imports of a package that is not scanned are not followed. Without it, every non-standard-library package reached is scanned.

Standard library packages are never scanned.

Entries

Each Entry is an annotated struct type, method or function:

  • IsStruct(): a struct type. Interfaces and other non-struct types are not reported. Fields lists its fields in order, one per name (A, B string is two), with the type as written and the tag without the backquotes; an embedded field has an empty Name.
  • IsMethod(): a method, with Struct set to its receiver type (T, *T or a generic T[K]), wherever in the package the type is declared.
  • IsFunc(): a package-level function.

Path is the import path, Package the package name, Module the module path and File the base name of the file that declares it. Header.Title is the first doc line without the leading declaration name and Header.Description the doc lines after it; annotation lines are not part of the header. Annotation.Value (RawValue()) keeps the text between the parentheses as written. Imports maps the name the declaring file uses for each import (its alias, or the imported package's name, so github.com/labstack/echo/v4 is echo) to the import path, which resolves a type such as echo.Context written in the file; blank and dot imports are left out.

Entries are returned per package (sorted by import path), in source order.

Examples

Run from this directory:

go run ./examples/func
  • examples/func: a function with several @Rest* annotations.
  • examples/method: struct types and methods.
  • examples/decode: decoding an annotation into a struct with attr tags.
  • examples/simple: annotations found through an imported package.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Annotation

type Annotation struct {
	Name  string                 // Name of the annotation, without the "@"
	Value string                 // Text between the parentheses, as written in the source
	Map   map[string]interface{} // Parsed key=value pairs
}

Annotation is a single `// @Name(key=value, ...)` line found in a doc comment.

func NewAnnotation

func NewAnnotation(name string, value string) Annotation

NewAnnotation builds an annotation from its name and the text between its parentheses. Values are split on top-level commas: commas inside double quotes or brackets belong to the value, and only the first "=" separates the key. Unquoted values become int, float64 or bool (true/false) when they parse as such; quoted values are always strings.

func (*Annotation) Decode

func (m *Annotation) Decode(a interface{}) error

Decode copies the parsed values into a, matching keys with `attr` tags.

func (*Annotation) RawValue

func (m *Annotation) RawValue() string

RawValue returns the text between the parentheses, as written in the source.

type Collector

type Collector struct {
	// contains filtered or unexported fields
}

func Collect

func Collect(options ...Option) (*Collector, error)

Collect loads every package under the base path (as `go list ./...` sees it from there: hidden, underscore, testdata and vendor directories are skipped) plus the packages they import, and returns the annotated declarations. Standard library packages are never scanned; WithPackages restricts the scan to the given import paths and the packages below them.

func (*Collector) Entries

func (c *Collector) Entries() []Entry

func (*Collector) EntriesWith

func (c *Collector) EntriesWith(annotation string) []Entry

func (*Collector) EntriesWithArgType

func (c *Collector) EntriesWithArgType(annotationName string, argumentType string) []Entry

func (*Collector) EntriesWithPrefix

func (c *Collector) EntriesWithPrefix(prefix string) []Entry

func (*Collector) EntriesWithResultType

func (c *Collector) EntriesWithResultType(annotation string, result string) []Entry

type Entry

type Entry struct {
	Header      EntryHeader // Metadata for the entry
	Comments    []string
	Module      string       // Name of the module where the entry is located
	File        string       // Name of the file where the entry is located
	Path        string       // Path to the file where the entry is located
	Package     string       // Name of the package where the entry is located
	Func        EntryFunc    // Details about the function in the entry
	Struct      string       // Name of the struct in the entry
	Fields      []EntryField // Fields of the struct, for a struct entry
	Annotations []Annotation // Annotations for the entry
	// Imports maps the name the file uses for each import (its alias, or the
	// imported package's name) to the import path. Blank and dot imports are
	// left out. Entries of the same file share the map.
	Imports map[string]string
}

Entry represents a single entry parsed from the *ast.File.

func (*Entry) IsFunc

func (b *Entry) IsFunc() bool

func (*Entry) IsMethod

func (b *Entry) IsMethod() bool

func (*Entry) IsStruct

func (b *Entry) IsStruct() bool

type EntryField

type EntryField struct {
	Name string // Name of the field, "" for an embedded field
	Type string // Type of the field, as written
	Tag  string // Tag of the field, without the backquotes
}

EntryField is a field of a struct entry.

type EntryFunc

type EntryFunc struct {
	Name       string          // Name of the function
	Parameters []EntryFuncType // Parameters of the function
	Results    []EntryFuncType // Results of the function
}

EntryFunc represents a function and its details.

type EntryFuncType

type EntryFuncType struct {
	Name string // Name of the parameter/result
	Type string // Type of the parameter/result
}

EntryFuncType represents a parameter or a result type of a function.

type EntryHeader

type EntryHeader struct {
	Title       string // Title of the entry
	Description string // Description of the entry
}

EntryHeader represents the metadata for an entry.

type Option

type Option func(*Collector) error

func WithFilters

func WithFilters(filters ...string) Option

WithFilters keeps only the annotations whose name starts with one of the filters: "Rest" keeps @Rest, @RestRouter and @RestResponse.

func WithPackages

func WithPackages(pkgs ...string) Option

WithPackages restricts the scan to the given import paths and the packages below them, both under the base path and among their imports.

func WithPath

func WithPath(path string) Option

WithPath sets the directory to scan. It must be inside a Go module.

Directories

Path Synopsis
examples
decode command
func command
method command
simple command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL