-
Notifications
You must be signed in to change notification settings - Fork 0
/
registry.go
102 lines (79 loc) · 3.13 KB
/
registry.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package markers
import (
"errors"
"fmt"
"sync"
)
type DefinitionMap map[string]*Definition
// Registry keeps the registered marker definitions.
type Registry struct {
packageMap map[string]DefinitionMap
mu sync.RWMutex
}
// NewRegistry returns a new registry to register the markers.
func NewRegistry() *Registry {
registry := &Registry{}
registry.initialize()
return registry
}
// initialize initializes the registry when needed.
func (registry *Registry) initialize() {
if registry.packageMap == nil {
registry.packageMap = make(map[string]DefinitionMap)
registry.packageMap[""] = make(DefinitionMap)
}
registry.packageMap[""][ImportMarkerName], _ = MakeDefinition(ImportMarkerName, "", PackageLevel, &ImportMarker{})
overrideMarker, _ := MakeDefinition(OverrideMarkerName, "", StructMethodLevel, &OverrideMarker{})
overrideMarker.Output.SyntaxFree = true
registry.packageMap[""][OverrideMarkerName] = overrideMarker
deprecatedDefinitionMarker, _ := MakeDefinition(DeprecatedMarkerName, "", TypeLevel|MethodLevel|FieldLevel|FunctionLevel, &DeprecatedMarker{})
deprecatedDefinitionMarker.Output.SyntaxFree = true
registry.packageMap[""][DeprecatedMarkerName] = deprecatedDefinitionMarker
registry.packageMap[""][DefinitionMarkerName], _ = MakeDefinition(DefinitionMarkerName, "", StructTypeLevel, &DefinitionMarker{})
registry.packageMap[""][DefinitionParameterMarkerName], _ = MakeDefinition(DefinitionParameterMarkerName, "", FieldLevel, &DefinitionParameterMarker{})
registry.packageMap[""][DefinitionEnumMarkerName], _ = MakeDefinition(DefinitionEnumMarkerName, "", FieldLevel, &DefinitionEnumMarker{})
}
// Register registers a new marker with the given name, target level, and output type.
func (registry *Registry) Register(name, pkg string, level TargetLevel, output any) error {
def, err := MakeDefinition(name, pkg, level, output)
if err != nil {
return err
}
return registry.RegisterWithDefinition(def)
}
// RegisterWithDefinition registers a new marker with the given definition.
func (registry *Registry) RegisterWithDefinition(definition *Definition) error {
registry.mu.Lock()
defer registry.mu.Unlock()
if definition == nil {
return errors.New("definition cannot be nil")
}
err := definition.validate()
if err != nil {
return err
}
definitionMap, exists := registry.packageMap[definition.Package]
if !exists {
definitionMap = make(DefinitionMap)
registry.packageMap[definition.Package] = definitionMap
}
if _, ok := definitionMap[definition.Name]; ok {
return fmt.Errorf("there is already registered definition : %v", definition.Name)
}
registry.packageMap[definition.Package][definition.Name] = definition
return nil
}
// Lookup fetches the definition corresponding to the given name and pkgId.
func (registry *Registry) Lookup(name, pkg string, targetLevel TargetLevel) (*Definition, bool) {
registry.initialize()
registry.mu.RLock()
defer registry.mu.RUnlock()
definitionMap, exists := registry.packageMap[pkg]
if !exists {
return nil, false
}
if definition, ok := definitionMap[name]; ok && definition.TargetLevel&targetLevel == targetLevel {
return definition, true
}
return nil, false
}