forked from sirkon/protoast
-
Notifications
You must be signed in to change notification settings - Fork 0
/
file.go
129 lines (106 loc) · 2.53 KB
/
file.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package ast
import (
"io"
"github.com/ricdeau/protoast/ast/internal/liner"
"github.com/ricdeau/protoast/internal/errors"
)
var _ Node = (*File)(nil)
var _ OptionsBearer = (*File)(nil)
// File представление для файла
type File struct {
unique
Name string
Package string
Syntax string
Imports []*Import
Types []Type
Extensions []*Extension
Services []*Service
Options []*Option
GoPath string
GoPkg string
}
func (f *File) GetOptions() []*Option {
return f.Options
}
// Type поиск типа по имени.
func (f *File) Type(name string) Type {
for _, typ := range f.Types {
switch v := typ.(type) {
case *Message:
if v.Name == name {
return v
}
case *Enum:
if v.Name == name {
return v
}
}
}
return nil
}
// Message поиск структуры по имени.
// Возвращает ошибку ErrorTypeNotFound если такой тип с таким именем не найден.
func (f *File) Message(name string) (*Message, error) {
typ := f.Type(name)
if typ == nil {
return nil, ErrorTypeNotFound(name)
}
switch v := typ.(type) {
case *Message:
return v, nil
default:
return nil, unexpectedType(typ, &Message{})
}
}
// Enum поиск перечисления по имени
// Возвращает ошибку ErrorTypeNotFound если такой тип с таким именем не найден.
func (f *File) Enum(name string) (*Enum, error) {
typ := f.Type(name)
if typ == nil {
return nil, ErrorTypeNotFound(name)
}
switch v := typ.(type) {
case *Enum:
return v, nil
default:
return nil, unexpectedType(typ, &Enum{})
}
}
// ScanTypes пробежка по типам данного пакета
func (f *File) ScanTypes(inspector func(typ Type) bool) {
for _, typ := range f.Types {
switch v := typ.(type) {
case *Message:
v.ScanTypes(inspector)
default:
inspector(typ)
}
}
}
// Service поиск сервиса по имени
func (f *File) Service(name string) *Service {
for _, service := range f.Services {
if service.Name == name {
return service
}
}
return nil
}
func (*File) node() {}
func (f *File) print(dest io.Writer, printer *Printer) error {
l := liner.New(dest)
l.Line(`syntax = "$"`, f.Syntax)
l.Newl()
l.Line("package $", f.Package)
l.Newl()
for _, imp := range f.Imports {
printer.Plan(imp.File)
l.Line(`import "$";`, imp.Path)
}
l.Newl()
return nil
}
func unexpectedType(typ Type, expected Type) error {
return errors.Newf("type is %T, not %T", typ, expected)
}