blob: e1eb4dfe08e17ef09b8ca15d2448c83f8d240b0c [file] [log] [blame]
Scott Baker1fe72732019-10-21 10:58:51 -07001package protoparse
2
3// This file defines all of the nodes in the proto AST.
4
5// SourcePos identifies a location in a proto source file.
6type SourcePos struct {
7 Filename string
8 Line, Col int
9 Offset int
10}
11
12func unknownPos(filename string) *SourcePos {
13 return &SourcePos{Filename: filename}
14}
15
16// node is the interface implemented by all nodes in the AST
17type node interface {
18 start() *SourcePos
19 end() *SourcePos
20 leadingComments() []comment
21 trailingComments() []comment
22}
23
24type terminalNode interface {
25 node
26 popLeadingComment() comment
27 pushTrailingComment(comment)
28}
29
30var _ terminalNode = (*basicNode)(nil)
31var _ terminalNode = (*stringLiteralNode)(nil)
32var _ terminalNode = (*intLiteralNode)(nil)
33var _ terminalNode = (*floatLiteralNode)(nil)
34var _ terminalNode = (*identNode)(nil)
35
36type fileDecl interface {
37 node
38 getSyntax() node
39}
40
41var _ fileDecl = (*fileNode)(nil)
42var _ fileDecl = (*noSourceNode)(nil)
43
44type optionDecl interface {
45 node
46 getName() node
47 getValue() valueNode
48}
49
50var _ optionDecl = (*optionNode)(nil)
51var _ optionDecl = (*noSourceNode)(nil)
52
53type fieldDecl interface {
54 node
55 fieldLabel() node
56 fieldName() node
57 fieldType() node
58 fieldTag() node
59 fieldExtendee() node
60 getGroupKeyword() node
61}
62
63var _ fieldDecl = (*fieldNode)(nil)
64var _ fieldDecl = (*groupNode)(nil)
65var _ fieldDecl = (*mapFieldNode)(nil)
66var _ fieldDecl = (*syntheticMapField)(nil)
67var _ fieldDecl = (*noSourceNode)(nil)
68
69type rangeDecl interface {
70 node
71 rangeStart() node
72 rangeEnd() node
73}
74
75var _ rangeDecl = (*rangeNode)(nil)
76var _ rangeDecl = (*noSourceNode)(nil)
77
78type enumValueDecl interface {
79 node
80 getName() node
81 getNumber() node
82}
83
84var _ enumValueDecl = (*enumValueNode)(nil)
85var _ enumValueDecl = (*noSourceNode)(nil)
86
87type msgDecl interface {
88 node
89 messageName() node
90}
91
92var _ msgDecl = (*messageNode)(nil)
93var _ msgDecl = (*groupNode)(nil)
94var _ msgDecl = (*mapFieldNode)(nil)
95var _ msgDecl = (*noSourceNode)(nil)
96
97type methodDecl interface {
98 node
99 getInputType() node
100 getOutputType() node
101}
102
103var _ methodDecl = (*methodNode)(nil)
104var _ methodDecl = (*noSourceNode)(nil)
105
106type posRange struct {
107 start, end SourcePos
108}
109
110type basicNode struct {
111 posRange
112 leading []comment
113 trailing []comment
114}
115
116func (n *basicNode) start() *SourcePos {
117 return &n.posRange.start
118}
119
120func (n *basicNode) end() *SourcePos {
121 return &n.posRange.end
122}
123
124func (n *basicNode) leadingComments() []comment {
125 return n.leading
126}
127
128func (n *basicNode) trailingComments() []comment {
129 return n.trailing
130}
131
132func (n *basicNode) popLeadingComment() comment {
133 c := n.leading[0]
134 n.leading = n.leading[1:]
135 return c
136}
137
138func (n *basicNode) pushTrailingComment(c comment) {
139 n.trailing = append(n.trailing, c)
140}
141
142type comment struct {
143 posRange
144 text string
145}
146
147type basicCompositeNode struct {
148 first node
149 last node
150}
151
152func (n *basicCompositeNode) start() *SourcePos {
153 return n.first.start()
154}
155
156func (n *basicCompositeNode) end() *SourcePos {
157 return n.last.end()
158}
159
160func (n *basicCompositeNode) leadingComments() []comment {
161 return n.first.leadingComments()
162}
163
164func (n *basicCompositeNode) trailingComments() []comment {
165 return n.last.trailingComments()
166}
167
168func (n *basicCompositeNode) setRange(first, last node) {
169 n.first = first
170 n.last = last
171}
172
173type fileNode struct {
174 basicCompositeNode
175 syntax *syntaxNode
176 decls []*fileElement
177
178 // This field is populated after parsing, to make it easier to find
179 // source locations by import name for constructing link errors.
180 imports []*importNode
181}
182
183func (n *fileNode) getSyntax() node {
184 return n.syntax
185}
186
187type fileElement struct {
188 // a discriminated union: only one field will be set
189 imp *importNode
190 pkg *packageNode
191 option *optionNode
192 message *messageNode
193 enum *enumNode
194 extend *extendNode
195 service *serviceNode
196 empty *basicNode
197}
198
199func (n *fileElement) start() *SourcePos {
200 return n.get().start()
201}
202
203func (n *fileElement) end() *SourcePos {
204 return n.get().end()
205}
206
207func (n *fileElement) leadingComments() []comment {
208 return n.get().leadingComments()
209}
210
211func (n *fileElement) trailingComments() []comment {
212 return n.get().trailingComments()
213}
214
215func (n *fileElement) get() node {
216 switch {
217 case n.imp != nil:
218 return n.imp
219 case n.pkg != nil:
220 return n.pkg
221 case n.option != nil:
222 return n.option
223 case n.message != nil:
224 return n.message
225 case n.enum != nil:
226 return n.enum
227 case n.extend != nil:
228 return n.extend
229 case n.service != nil:
230 return n.service
231 default:
232 return n.empty
233 }
234}
235
236type syntaxNode struct {
237 basicCompositeNode
238 syntax *compoundStringNode
239}
240
241type importNode struct {
242 basicCompositeNode
243 name *compoundStringNode
244 public bool
245 weak bool
246}
247
248type packageNode struct {
249 basicCompositeNode
250 name *compoundIdentNode
251}
252
253type identifier string
254
255type identNode struct {
256 basicNode
257 val string
258}
259
260func (n *identNode) value() interface{} {
261 return identifier(n.val)
262}
263
264type compoundIdentNode struct {
265 basicCompositeNode
266 val string
267}
268
269func (n *compoundIdentNode) value() interface{} {
270 return identifier(n.val)
271}
272
273type compactOptionsNode struct {
274 basicCompositeNode
275 decls []*optionNode
276}
277
278func (n *compactOptionsNode) Elements() []*optionNode {
279 if n == nil {
280 return nil
281 }
282 return n.decls
283}
284
285type optionNode struct {
286 basicCompositeNode
287 name *optionNameNode
288 val valueNode
289}
290
291func (n *optionNode) getName() node {
292 return n.name
293}
294
295func (n *optionNode) getValue() valueNode {
296 return n.val
297}
298
299type optionNameNode struct {
300 basicCompositeNode
301 parts []*optionNamePartNode
302}
303
304type optionNamePartNode struct {
305 basicCompositeNode
306 text *compoundIdentNode
307 offset int
308 length int
309 isExtension bool
310 st, en *SourcePos
311}
312
313func (n *optionNamePartNode) start() *SourcePos {
314 if n.isExtension {
315 return n.basicCompositeNode.start()
316 }
317 return n.st
318}
319
320func (n *optionNamePartNode) end() *SourcePos {
321 if n.isExtension {
322 return n.basicCompositeNode.end()
323 }
324 return n.en
325}
326
327func (n *optionNamePartNode) setRange(first, last node) {
328 n.basicCompositeNode.setRange(first, last)
329 if !n.isExtension {
330 st := *first.start()
331 st.Col += n.offset
332 n.st = &st
333 en := st
334 en.Col += n.length
335 n.en = &en
336 }
337}
338
339type valueNode interface {
340 node
341 value() interface{}
342}
343
344var _ valueNode = (*identNode)(nil)
345var _ valueNode = (*compoundIdentNode)(nil)
346var _ valueNode = (*stringLiteralNode)(nil)
347var _ valueNode = (*compoundStringNode)(nil)
348var _ valueNode = (*intLiteralNode)(nil)
349var _ valueNode = (*compoundIntNode)(nil)
350var _ valueNode = (*compoundUintNode)(nil)
351var _ valueNode = (*floatLiteralNode)(nil)
352var _ valueNode = (*compoundFloatNode)(nil)
353var _ valueNode = (*boolLiteralNode)(nil)
354var _ valueNode = (*sliceLiteralNode)(nil)
355var _ valueNode = (*aggregateLiteralNode)(nil)
356var _ valueNode = (*noSourceNode)(nil)
357
358type stringLiteralNode struct {
359 basicNode
360 val string
361}
362
363func (n *stringLiteralNode) value() interface{} {
364 return n.val
365}
366
367type compoundStringNode struct {
368 basicCompositeNode
369 val string
370}
371
372func (n *compoundStringNode) value() interface{} {
373 return n.val
374}
375
376type intLiteralNode struct {
377 basicNode
378 val uint64
379}
380
381func (n *intLiteralNode) value() interface{} {
382 return n.val
383}
384
385type compoundUintNode struct {
386 basicCompositeNode
387 val uint64
388}
389
390func (n *compoundUintNode) value() interface{} {
391 return n.val
392}
393
394type compoundIntNode struct {
395 basicCompositeNode
396 val int64
397}
398
399func (n *compoundIntNode) value() interface{} {
400 return n.val
401}
402
403type floatLiteralNode struct {
404 basicNode
405 val float64
406}
407
408func (n *floatLiteralNode) value() interface{} {
409 return n.val
410}
411
412type compoundFloatNode struct {
413 basicCompositeNode
414 val float64
415}
416
417func (n *compoundFloatNode) value() interface{} {
418 return n.val
419}
420
421type boolLiteralNode struct {
422 *identNode
423 val bool
424}
425
426func (n *boolLiteralNode) value() interface{} {
427 return n.val
428}
429
430type sliceLiteralNode struct {
431 basicCompositeNode
432 elements []valueNode
433}
434
435func (n *sliceLiteralNode) value() interface{} {
436 return n.elements
437}
438
439type aggregateLiteralNode struct {
440 basicCompositeNode
441 elements []*aggregateEntryNode
442}
443
444func (n *aggregateLiteralNode) value() interface{} {
445 return n.elements
446}
447
448type aggregateEntryNode struct {
449 basicCompositeNode
450 name *aggregateNameNode
451 val valueNode
452}
453
454type aggregateNameNode struct {
455 basicCompositeNode
456 name *compoundIdentNode
457 isExtension bool
458}
459
460func (a *aggregateNameNode) value() string {
461 if a.isExtension {
462 return "[" + a.name.val + "]"
463 } else {
464 return a.name.val
465 }
466}
467
468type fieldNode struct {
469 basicCompositeNode
470 label fieldLabel
471 fldType *compoundIdentNode
472 name *identNode
473 tag *intLiteralNode
474 options *compactOptionsNode
475
476 // This field is populated after parsing, to allow lookup of extendee source
477 // locations when field extendees cannot be linked. (Otherwise, this is just
478 // stored as a string in the field descriptors defined inside the extend
479 // block).
480 extendee *extendNode
481}
482
483func (n *fieldNode) fieldLabel() node {
484 // proto3 fields and fields inside one-ofs will not have a label and we need
485 // this check in order to return a nil node -- otherwise we'd return a
486 // non-nil node that has a nil pointer value in it :/
487 if n.label.identNode == nil {
488 return nil
489 }
490 return n.label.identNode
491}
492
493func (n *fieldNode) fieldName() node {
494 return n.name
495}
496
497func (n *fieldNode) fieldType() node {
498 return n.fldType
499}
500
501func (n *fieldNode) fieldTag() node {
502 return n.tag
503}
504
505func (n *fieldNode) fieldExtendee() node {
506 if n.extendee != nil {
507 return n.extendee.extendee
508 }
509 return nil
510}
511
512func (n *fieldNode) getGroupKeyword() node {
513 return nil
514}
515
516type fieldLabel struct {
517 *identNode
518 repeated bool
519 required bool
520}
521
522type groupNode struct {
523 basicCompositeNode
524 groupKeyword *identNode
525 label fieldLabel
526 name *identNode
527 tag *intLiteralNode
528 decls []*messageElement
529
530 // This field is populated after parsing, to allow lookup of extendee source
531 // locations when field extendees cannot be linked. (Otherwise, this is just
532 // stored as a string in the field descriptors defined inside the extend
533 // block).
534 extendee *extendNode
535}
536
537func (n *groupNode) fieldLabel() node {
538 if n.label.identNode == nil {
539 // return nil interface to indicate absence, not a typed nil
540 return nil
541 }
542 return n.label.identNode
543}
544
545func (n *groupNode) fieldName() node {
546 return n.name
547}
548
549func (n *groupNode) fieldType() node {
550 return n.groupKeyword
551}
552
553func (n *groupNode) fieldTag() node {
554 return n.tag
555}
556
557func (n *groupNode) fieldExtendee() node {
558 if n.extendee != nil {
559 return n.extendee.extendee
560 }
561 return nil
562}
563
564func (n *groupNode) getGroupKeyword() node {
565 return n.groupKeyword
566}
567
568func (n *groupNode) messageName() node {
569 return n.name
570}
571
572type oneOfNode struct {
573 basicCompositeNode
574 name *identNode
575 decls []*oneOfElement
576}
577
578type oneOfElement struct {
579 // a discriminated union: only one field will be set
580 option *optionNode
581 field *fieldNode
582 group *groupNode
583 empty *basicNode
584}
585
586func (n *oneOfElement) start() *SourcePos {
587 return n.get().start()
588}
589
590func (n *oneOfElement) end() *SourcePos {
591 return n.get().end()
592}
593
594func (n *oneOfElement) leadingComments() []comment {
595 return n.get().leadingComments()
596}
597
598func (n *oneOfElement) trailingComments() []comment {
599 return n.get().trailingComments()
600}
601
602func (n *oneOfElement) get() node {
603 switch {
604 case n.option != nil:
605 return n.option
606 case n.field != nil:
607 return n.field
608 default:
609 return n.empty
610 }
611}
612
613type mapTypeNode struct {
614 basicCompositeNode
615 mapKeyword *identNode
616 keyType *identNode
617 valueType *compoundIdentNode
618}
619
620type mapFieldNode struct {
621 basicCompositeNode
622 mapType *mapTypeNode
623 name *identNode
624 tag *intLiteralNode
625 options *compactOptionsNode
626}
627
628func (n *mapFieldNode) fieldLabel() node {
629 return nil
630}
631
632func (n *mapFieldNode) fieldName() node {
633 return n.name
634}
635
636func (n *mapFieldNode) fieldType() node {
637 return n.mapType
638}
639
640func (n *mapFieldNode) fieldTag() node {
641 return n.tag
642}
643
644func (n *mapFieldNode) fieldExtendee() node {
645 return nil
646}
647
648func (n *mapFieldNode) getGroupKeyword() node {
649 return nil
650}
651
652func (n *mapFieldNode) messageName() node {
653 return n.name
654}
655
656func (n *mapFieldNode) keyField() *syntheticMapField {
657 k := n.mapType.keyType
658 t := &compoundIdentNode{val: k.val}
659 t.setRange(k, k)
660 return newSyntheticMapField(t, 1)
661}
662
663func (n *mapFieldNode) valueField() *syntheticMapField {
664 return newSyntheticMapField(n.mapType.valueType, 2)
665}
666
667func newSyntheticMapField(ident *compoundIdentNode, tagNum uint64) *syntheticMapField {
668 tag := &intLiteralNode{
669 basicNode: basicNode{
670 posRange: posRange{start: *ident.start(), end: *ident.end()},
671 },
672 val: tagNum,
673 }
674 return &syntheticMapField{ident: ident, tag: tag}
675}
676
677type syntheticMapField struct {
678 ident *compoundIdentNode
679 tag *intLiteralNode
680}
681
682func (n *syntheticMapField) start() *SourcePos {
683 return n.ident.start()
684}
685
686func (n *syntheticMapField) end() *SourcePos {
687 return n.ident.end()
688}
689
690func (n *syntheticMapField) leadingComments() []comment {
691 return nil
692}
693
694func (n *syntheticMapField) trailingComments() []comment {
695 return nil
696}
697
698func (n *syntheticMapField) fieldLabel() node {
699 return n.ident
700}
701
702func (n *syntheticMapField) fieldName() node {
703 return n.ident
704}
705
706func (n *syntheticMapField) fieldType() node {
707 return n.ident
708}
709
710func (n *syntheticMapField) fieldTag() node {
711 return n.tag
712}
713
714func (n *syntheticMapField) fieldExtendee() node {
715 return nil
716}
717
718func (n *syntheticMapField) getGroupKeyword() node {
719 return nil
720}
721
722type extensionRangeNode struct {
723 basicCompositeNode
724 ranges []*rangeNode
725 options *compactOptionsNode
726}
727
728type rangeNode struct {
729 basicCompositeNode
730 stNode, enNode node
731 st, en int32
732}
733
734func (n *rangeNode) rangeStart() node {
735 return n.stNode
736}
737
738func (n *rangeNode) rangeEnd() node {
739 return n.enNode
740}
741
742type reservedNode struct {
743 basicCompositeNode
744 ranges []*rangeNode
745 names []*compoundStringNode
746}
747
748type enumNode struct {
749 basicCompositeNode
750 name *identNode
751 decls []*enumElement
752}
753
754type enumElement struct {
755 // a discriminated union: only one field will be set
756 option *optionNode
757 value *enumValueNode
758 reserved *reservedNode
759 empty *basicNode
760}
761
762func (n *enumElement) start() *SourcePos {
763 return n.get().start()
764}
765
766func (n *enumElement) end() *SourcePos {
767 return n.get().end()
768}
769
770func (n *enumElement) leadingComments() []comment {
771 return n.get().leadingComments()
772}
773
774func (n *enumElement) trailingComments() []comment {
775 return n.get().trailingComments()
776}
777
778func (n *enumElement) get() node {
779 switch {
780 case n.option != nil:
781 return n.option
782 case n.value != nil:
783 return n.value
784 default:
785 return n.empty
786 }
787}
788
789type enumValueNode struct {
790 basicCompositeNode
791 name *identNode
792 options *compactOptionsNode
793 number *compoundIntNode
794}
795
796func (n *enumValueNode) getName() node {
797 return n.name
798}
799
800func (n *enumValueNode) getNumber() node {
801 return n.number
802}
803
804type messageNode struct {
805 basicCompositeNode
806 name *identNode
807 decls []*messageElement
808}
809
810func (n *messageNode) messageName() node {
811 return n.name
812}
813
814type messageElement struct {
815 // a discriminated union: only one field will be set
816 option *optionNode
817 field *fieldNode
818 mapField *mapFieldNode
819 oneOf *oneOfNode
820 group *groupNode
821 nested *messageNode
822 enum *enumNode
823 extend *extendNode
824 extensionRange *extensionRangeNode
825 reserved *reservedNode
826 empty *basicNode
827}
828
829func (n *messageElement) start() *SourcePos {
830 return n.get().start()
831}
832
833func (n *messageElement) end() *SourcePos {
834 return n.get().end()
835}
836
837func (n *messageElement) leadingComments() []comment {
838 return n.get().leadingComments()
839}
840
841func (n *messageElement) trailingComments() []comment {
842 return n.get().trailingComments()
843}
844
845func (n *messageElement) get() node {
846 switch {
847 case n.option != nil:
848 return n.option
849 case n.field != nil:
850 return n.field
851 case n.mapField != nil:
852 return n.mapField
853 case n.oneOf != nil:
854 return n.oneOf
855 case n.group != nil:
856 return n.group
857 case n.nested != nil:
858 return n.nested
859 case n.enum != nil:
860 return n.enum
861 case n.extend != nil:
862 return n.extend
863 case n.extensionRange != nil:
864 return n.extensionRange
865 case n.reserved != nil:
866 return n.reserved
867 default:
868 return n.empty
869 }
870}
871
872type extendNode struct {
873 basicCompositeNode
874 extendee *compoundIdentNode
875 decls []*extendElement
876}
877
878type extendElement struct {
879 // a discriminated union: only one field will be set
880 field *fieldNode
881 group *groupNode
882 empty *basicNode
883}
884
885func (n *extendElement) start() *SourcePos {
886 return n.get().start()
887}
888
889func (n *extendElement) end() *SourcePos {
890 return n.get().end()
891}
892
893func (n *extendElement) leadingComments() []comment {
894 return n.get().leadingComments()
895}
896
897func (n *extendElement) trailingComments() []comment {
898 return n.get().trailingComments()
899}
900
901func (n *extendElement) get() node {
902 switch {
903 case n.field != nil:
904 return n.field
905 case n.group != nil:
906 return n.group
907 default:
908 return n.empty
909 }
910}
911
912type serviceNode struct {
913 basicCompositeNode
914 name *identNode
915 decls []*serviceElement
916}
917
918type serviceElement struct {
919 // a discriminated union: only one field will be set
920 option *optionNode
921 rpc *methodNode
922 empty *basicNode
923}
924
925func (n *serviceElement) start() *SourcePos {
926 return n.get().start()
927}
928
929func (n *serviceElement) end() *SourcePos {
930 return n.get().end()
931}
932
933func (n *serviceElement) leadingComments() []comment {
934 return n.get().leadingComments()
935}
936
937func (n *serviceElement) trailingComments() []comment {
938 return n.get().trailingComments()
939}
940
941func (n *serviceElement) get() node {
942 switch {
943 case n.option != nil:
944 return n.option
945 case n.rpc != nil:
946 return n.rpc
947 default:
948 return n.empty
949 }
950}
951
952type methodNode struct {
953 basicCompositeNode
954 name *identNode
955 input *rpcTypeNode
956 output *rpcTypeNode
957 options []*optionNode
958}
959
960func (n *methodNode) getInputType() node {
961 return n.input.msgType
962}
963
964func (n *methodNode) getOutputType() node {
965 return n.output.msgType
966}
967
968type rpcTypeNode struct {
969 basicCompositeNode
970 msgType *compoundIdentNode
971 streamKeyword node
972}
973
974type noSourceNode struct {
975 pos *SourcePos
976}
977
978func (n noSourceNode) start() *SourcePos {
979 return n.pos
980}
981
982func (n noSourceNode) end() *SourcePos {
983 return n.pos
984}
985
986func (n noSourceNode) leadingComments() []comment {
987 return nil
988}
989
990func (n noSourceNode) trailingComments() []comment {
991 return nil
992}
993
994func (n noSourceNode) getSyntax() node {
995 return n
996}
997
998func (n noSourceNode) getName() node {
999 return n
1000}
1001
1002func (n noSourceNode) getValue() valueNode {
1003 return n
1004}
1005
1006func (n noSourceNode) fieldLabel() node {
1007 return n
1008}
1009
1010func (n noSourceNode) fieldName() node {
1011 return n
1012}
1013
1014func (n noSourceNode) fieldType() node {
1015 return n
1016}
1017
1018func (n noSourceNode) fieldTag() node {
1019 return n
1020}
1021
1022func (n noSourceNode) fieldExtendee() node {
1023 return n
1024}
1025
1026func (n noSourceNode) getGroupKeyword() node {
1027 return n
1028}
1029
1030func (n noSourceNode) rangeStart() node {
1031 return n
1032}
1033
1034func (n noSourceNode) rangeEnd() node {
1035 return n
1036}
1037
1038func (n noSourceNode) getNumber() node {
1039 return n
1040}
1041
1042func (n noSourceNode) messageName() node {
1043 return n
1044}
1045
1046func (n noSourceNode) getInputType() node {
1047 return n
1048}
1049
1050func (n noSourceNode) getOutputType() node {
1051 return n
1052}
1053
1054func (n noSourceNode) value() interface{} {
1055 return nil
1056}