206 lines
4.4 KiB
Go
206 lines
4.4 KiB
Go
|
package protoparse
|
||
|
|
||
|
import "github.com/jhump/protoreflect/desc/protoparse/ast"
|
||
|
|
||
|
// SourcePos is the same as ast.SourcePos. This alias exists for
|
||
|
// backwards compatibility (SourcePos used to be defined in this package.)
|
||
|
type SourcePos = ast.SourcePos
|
||
|
|
||
|
// the types below are accumulator types: linked lists that are
|
||
|
// constructed during parsing and then converted to slices of AST nodes
|
||
|
// once the whole list has been parsed
|
||
|
|
||
|
type compactOptionList struct {
|
||
|
option *ast.OptionNode
|
||
|
comma *ast.RuneNode
|
||
|
next *compactOptionList
|
||
|
}
|
||
|
|
||
|
func (list *compactOptionList) toNodes() ([]*ast.OptionNode, []*ast.RuneNode) {
|
||
|
l := 0
|
||
|
for cur := list; cur != nil; cur = cur.next {
|
||
|
l++
|
||
|
}
|
||
|
opts := make([]*ast.OptionNode, l)
|
||
|
commas := make([]*ast.RuneNode, l-1)
|
||
|
for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 {
|
||
|
opts[i] = cur.option
|
||
|
if cur.comma != nil {
|
||
|
commas[i] = cur.comma
|
||
|
}
|
||
|
}
|
||
|
return opts, commas
|
||
|
}
|
||
|
|
||
|
type stringList struct {
|
||
|
str *ast.StringLiteralNode
|
||
|
next *stringList
|
||
|
}
|
||
|
|
||
|
func (list *stringList) toStringValueNode() ast.StringValueNode {
|
||
|
if list.next == nil {
|
||
|
// single name
|
||
|
return list.str
|
||
|
}
|
||
|
|
||
|
l := 0
|
||
|
for cur := list; cur != nil; cur = cur.next {
|
||
|
l++
|
||
|
}
|
||
|
strs := make([]*ast.StringLiteralNode, l)
|
||
|
for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 {
|
||
|
strs[i] = cur.str
|
||
|
}
|
||
|
return ast.NewCompoundLiteralStringNode(strs...)
|
||
|
}
|
||
|
|
||
|
type nameList struct {
|
||
|
name ast.StringValueNode
|
||
|
comma *ast.RuneNode
|
||
|
next *nameList
|
||
|
}
|
||
|
|
||
|
func (list *nameList) toNodes() ([]ast.StringValueNode, []*ast.RuneNode) {
|
||
|
l := 0
|
||
|
for cur := list; cur != nil; cur = cur.next {
|
||
|
l++
|
||
|
}
|
||
|
names := make([]ast.StringValueNode, l)
|
||
|
commas := make([]*ast.RuneNode, l-1)
|
||
|
for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 {
|
||
|
names[i] = cur.name
|
||
|
if cur.comma != nil {
|
||
|
commas[i] = cur.comma
|
||
|
}
|
||
|
}
|
||
|
return names, commas
|
||
|
}
|
||
|
|
||
|
type rangeList struct {
|
||
|
rng *ast.RangeNode
|
||
|
comma *ast.RuneNode
|
||
|
next *rangeList
|
||
|
}
|
||
|
|
||
|
func (list *rangeList) toNodes() ([]*ast.RangeNode, []*ast.RuneNode) {
|
||
|
l := 0
|
||
|
for cur := list; cur != nil; cur = cur.next {
|
||
|
l++
|
||
|
}
|
||
|
ranges := make([]*ast.RangeNode, l)
|
||
|
commas := make([]*ast.RuneNode, l-1)
|
||
|
for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 {
|
||
|
ranges[i] = cur.rng
|
||
|
if cur.comma != nil {
|
||
|
commas[i] = cur.comma
|
||
|
}
|
||
|
}
|
||
|
return ranges, commas
|
||
|
}
|
||
|
|
||
|
type valueList struct {
|
||
|
val ast.ValueNode
|
||
|
comma *ast.RuneNode
|
||
|
next *valueList
|
||
|
}
|
||
|
|
||
|
func (list *valueList) toNodes() ([]ast.ValueNode, []*ast.RuneNode) {
|
||
|
if list == nil {
|
||
|
return nil, nil
|
||
|
}
|
||
|
l := 0
|
||
|
for cur := list; cur != nil; cur = cur.next {
|
||
|
l++
|
||
|
}
|
||
|
vals := make([]ast.ValueNode, l)
|
||
|
commas := make([]*ast.RuneNode, l-1)
|
||
|
for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 {
|
||
|
vals[i] = cur.val
|
||
|
if cur.comma != nil {
|
||
|
commas[i] = cur.comma
|
||
|
}
|
||
|
}
|
||
|
return vals, commas
|
||
|
}
|
||
|
|
||
|
type fieldRefList struct {
|
||
|
ref *ast.FieldReferenceNode
|
||
|
dot *ast.RuneNode
|
||
|
next *fieldRefList
|
||
|
}
|
||
|
|
||
|
func (list *fieldRefList) toNodes() ([]*ast.FieldReferenceNode, []*ast.RuneNode) {
|
||
|
l := 0
|
||
|
for cur := list; cur != nil; cur = cur.next {
|
||
|
l++
|
||
|
}
|
||
|
refs := make([]*ast.FieldReferenceNode, l)
|
||
|
dots := make([]*ast.RuneNode, l-1)
|
||
|
for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 {
|
||
|
refs[i] = cur.ref
|
||
|
if cur.dot != nil {
|
||
|
dots[i] = cur.dot
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return refs, dots
|
||
|
}
|
||
|
|
||
|
type identList struct {
|
||
|
ident *ast.IdentNode
|
||
|
dot *ast.RuneNode
|
||
|
next *identList
|
||
|
}
|
||
|
|
||
|
func (list *identList) toIdentValueNode(leadingDot *ast.RuneNode) ast.IdentValueNode {
|
||
|
if list.next == nil && leadingDot == nil {
|
||
|
// single name
|
||
|
return list.ident
|
||
|
}
|
||
|
|
||
|
l := 0
|
||
|
for cur := list; cur != nil; cur = cur.next {
|
||
|
l++
|
||
|
}
|
||
|
idents := make([]*ast.IdentNode, l)
|
||
|
dots := make([]*ast.RuneNode, l-1)
|
||
|
for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 {
|
||
|
idents[i] = cur.ident
|
||
|
if cur.dot != nil {
|
||
|
dots[i] = cur.dot
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ast.NewCompoundIdentNode(leadingDot, idents, dots)
|
||
|
}
|
||
|
|
||
|
type messageFieldEntry struct {
|
||
|
field *ast.MessageFieldNode
|
||
|
delimiter *ast.RuneNode
|
||
|
}
|
||
|
|
||
|
type messageFieldList struct {
|
||
|
field *messageFieldEntry
|
||
|
next *messageFieldList
|
||
|
}
|
||
|
|
||
|
func (list *messageFieldList) toNodes() ([]*ast.MessageFieldNode, []*ast.RuneNode) {
|
||
|
if list == nil {
|
||
|
return nil, nil
|
||
|
}
|
||
|
l := 0
|
||
|
for cur := list; cur != nil; cur = cur.next {
|
||
|
l++
|
||
|
}
|
||
|
fields := make([]*ast.MessageFieldNode, l)
|
||
|
delimiters := make([]*ast.RuneNode, l)
|
||
|
for cur, i := list, 0; cur != nil; cur, i = cur.next, i+1 {
|
||
|
fields[i] = cur.field.field
|
||
|
if cur.field.delimiter != nil {
|
||
|
delimiters[i] = cur.field.delimiter
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return fields, delimiters
|
||
|
}
|