-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathparser.go
113 lines (92 loc) · 2.13 KB
/
parser.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
103
104
105
106
107
108
109
110
111
112
113
package dyncapnp
//go:generate go run ./gen/
import (
"fmt"
"runtime"
"unsafe"
"github.com/devsisters/go-dyncapnp/schema"
)
var ErrSchemaNotFound = fmt.Errorf("schema not found")
type noCopy struct{}
func (*noCopy) Lock() {}
func (*noCopy) Unlock() {}
// ParsedSchema of a Cap'n'proto type. Should not be copied.
type ParsedSchema struct {
parser *schemaParser
ptr unsafe.Pointer
*schema.Schema
noCopy noCopy
}
// FindNested finds nested schema with given name. Returns ErrSchemaNotFound if nothing was found.
func (s *ParsedSchema) Nested(name string) (*ParsedSchema, error) {
ptr, err := findNested(s.ptr, name)
if err != nil {
return nil, err
}
if ptr == nil {
return nil, ErrSchemaNotFound
}
s.parser.incRef()
sc := &ParsedSchema{
parser: s.parser,
ptr: ptr,
Schema: schema.NewWithFreer(ptr, nil),
}
runtime.SetFinalizer(sc, (*ParsedSchema).release)
return sc, nil
}
func (s *ParsedSchema) release() {
releaseParsedSchema(s.ptr)
s.parser.decRef()
}
func ParseFromFiles(files map[string][]byte, imports map[string][]byte, paths []string) (map[string]*ParsedSchema, error) {
// no need to parse if paths is empty
if len(paths) == 0 {
return nil, nil
}
// prepend standard imports
importsWithStd := make(map[string][]byte, len(stdImports)+len(imports))
for p, b := range stdImports {
importsWithStd[p] = b
}
for p, b := range imports {
importsWithStd[p] = b
}
parserPtr, schemaPtrs, err := parseSchemaFromFiles(files, importsWithStd, paths)
if err != nil {
return nil, err
}
parser := &schemaParser{
ptr: parserPtr,
refCount: len(schemaPtrs),
}
pathSchemas := make(map[string]*ParsedSchema, len(paths))
for i, path := range paths {
pathSchemas[path] = &ParsedSchema{
parser: parser,
ptr: schemaPtrs[i],
Schema: schema.NewWithFreer(schemaPtrs[i], nil),
}
}
return pathSchemas, nil
}
type schemaParser struct {
ptr unsafe.Pointer
refCount int
noCopy noCopy
}
func (p *schemaParser) incRef() {
if p == nil {
return
}
p.refCount++
}
func (p *schemaParser) decRef() {
if p == nil {
return
}
p.refCount--
if p.refCount < 0 {
releaseParser(p.ptr)
}
}