...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package proto
25
26
27 type Proto struct {
28 Filename string
29 Elements []Visitee
30 }
31
32
33 func (proto *Proto) Accept(v Visitor) {
34
35
36 for _, each := range proto.Elements {
37 each.Accept(v)
38 }
39 }
40
41
42 func (proto *Proto) addElement(v Visitee) {
43 v.parent(proto)
44 proto.Elements = append(proto.Elements, v)
45 }
46
47
48 func (proto *Proto) elements() []Visitee {
49 return proto.Elements
50 }
51
52
53
54 func (proto *Proto) takeLastComment(expectedOnLine int) (last *Comment) {
55 last, proto.Elements = takeLastCommentIfEndsOnLine(proto.Elements, expectedOnLine)
56 return
57 }
58
59
60 func (proto *Proto) parse(p *Parser) error {
61 for {
62 pos, tok, lit := p.next()
63 switch {
64 case isComment(lit):
65 if com := mergeOrReturnComment(proto.Elements, lit, pos); com != nil {
66 proto.Elements = append(proto.Elements, com)
67 }
68 case tOPTION == tok:
69 o := new(Option)
70 o.Position = pos
71 o.Comment, proto.Elements = takeLastCommentIfEndsOnLine(proto.Elements, pos.Line-1)
72 if err := o.parse(p); err != nil {
73 return err
74 }
75 proto.addElement(o)
76 case tSYNTAX == tok:
77 s := new(Syntax)
78 s.Position = pos
79 s.Comment, proto.Elements = takeLastCommentIfEndsOnLine(proto.Elements, pos.Line-1)
80 if err := s.parse(p); err != nil {
81 return err
82 }
83 proto.addElement(s)
84 case tIMPORT == tok:
85 im := new(Import)
86 im.Position = pos
87 im.Comment, proto.Elements = takeLastCommentIfEndsOnLine(proto.Elements, pos.Line-1)
88 if err := im.parse(p); err != nil {
89 return err
90 }
91 proto.addElement(im)
92 case tENUM == tok:
93 enum := new(Enum)
94 enum.Position = pos
95 enum.Comment, proto.Elements = takeLastCommentIfEndsOnLine(proto.Elements, pos.Line-1)
96 if err := enum.parse(p); err != nil {
97 return err
98 }
99 proto.addElement(enum)
100 case tSERVICE == tok:
101 service := new(Service)
102 service.Position = pos
103 service.Comment, proto.Elements = takeLastCommentIfEndsOnLine(proto.Elements, pos.Line-1)
104 err := service.parse(p)
105 if err != nil {
106 return err
107 }
108 proto.addElement(service)
109 case tPACKAGE == tok:
110 pkg := new(Package)
111 pkg.Position = pos
112 pkg.Comment, proto.Elements = takeLastCommentIfEndsOnLine(proto.Elements, pos.Line-1)
113 if err := pkg.parse(p); err != nil {
114 return err
115 }
116 proto.addElement(pkg)
117 case tMESSAGE == tok:
118 msg := new(Message)
119 msg.Position = pos
120 msg.Comment, proto.Elements = takeLastCommentIfEndsOnLine(proto.Elements, pos.Line-1)
121 if err := msg.parse(p); err != nil {
122 return err
123 }
124 proto.addElement(msg)
125
126 case tEXTEND == tok:
127 msg := new(Message)
128 msg.Position = pos
129 msg.Comment, proto.Elements = takeLastCommentIfEndsOnLine(proto.Elements, pos.Line-1)
130 msg.IsExtend = true
131 if err := msg.parse(p); err != nil {
132 return err
133 }
134 proto.addElement(msg)
135
136 case tSEMICOLON == tok:
137 maybeScanInlineComment(p, proto)
138
139 case tEOF == tok:
140 goto done
141 default:
142 return p.unexpected(lit, ".proto element {comment|option|import|syntax|enum|service|package|message}", p)
143 }
144 }
145 done:
146 return nil
147 }
148
149 func (proto *Proto) parent(v Visitee) {}
150
151
152 type elementContainer interface {
153 addElement(v Visitee)
154 elements() []Visitee
155 takeLastComment(expectedOnLine int) *Comment
156 }
157
View as plain text