github.com/jhump/protoreflect@v1.16.0/desc/protoparse/ast/enum.go (about) 1 package ast 2 3 import "fmt" 4 5 // EnumNode represents an enum declaration. Example: 6 // 7 // enum Foo { BAR = 0; BAZ = 1 } 8 type EnumNode struct { 9 compositeNode 10 Keyword *KeywordNode 11 Name *IdentNode 12 OpenBrace *RuneNode 13 Decls []EnumElement 14 CloseBrace *RuneNode 15 } 16 17 func (*EnumNode) fileElement() {} 18 func (*EnumNode) msgElement() {} 19 20 // NewEnumNode creates a new *EnumNode. All arguments must be non-nil. While 21 // it is technically allowed for decls to be nil or empty, the resulting node 22 // will not be a valid enum, which must have at least one value. 23 // - keyword: The token corresponding to the "enum" keyword. 24 // - name: The token corresponding to the enum's name. 25 // - openBrace: The token corresponding to the "{" rune that starts the body. 26 // - decls: All declarations inside the enum body. 27 // - closeBrace: The token corresponding to the "}" rune that ends the body. 28 func NewEnumNode(keyword *KeywordNode, name *IdentNode, openBrace *RuneNode, decls []EnumElement, closeBrace *RuneNode) *EnumNode { 29 if keyword == nil { 30 panic("keyword is nil") 31 } 32 if name == nil { 33 panic("name is nil") 34 } 35 if openBrace == nil { 36 panic("openBrace is nil") 37 } 38 if closeBrace == nil { 39 panic("closeBrace is nil") 40 } 41 children := make([]Node, 0, 4+len(decls)) 42 children = append(children, keyword, name, openBrace) 43 for _, decl := range decls { 44 children = append(children, decl) 45 } 46 children = append(children, closeBrace) 47 48 for _, decl := range decls { 49 switch decl.(type) { 50 case *OptionNode, *EnumValueNode, *ReservedNode, *EmptyDeclNode: 51 default: 52 panic(fmt.Sprintf("invalid EnumElement type: %T", decl)) 53 } 54 } 55 56 return &EnumNode{ 57 compositeNode: compositeNode{ 58 children: children, 59 }, 60 Keyword: keyword, 61 Name: name, 62 OpenBrace: openBrace, 63 CloseBrace: closeBrace, 64 Decls: decls, 65 } 66 } 67 68 // EnumElement is an interface implemented by all AST nodes that can 69 // appear in the body of an enum declaration. 70 type EnumElement interface { 71 Node 72 enumElement() 73 } 74 75 var _ EnumElement = (*OptionNode)(nil) 76 var _ EnumElement = (*EnumValueNode)(nil) 77 var _ EnumElement = (*ReservedNode)(nil) 78 var _ EnumElement = (*EmptyDeclNode)(nil) 79 80 // EnumValueDeclNode is a placeholder interface for AST nodes that represent 81 // enum values. This allows NoSourceNode to be used in place of *EnumValueNode 82 // for some usages. 83 type EnumValueDeclNode interface { 84 Node 85 GetName() Node 86 GetNumber() Node 87 } 88 89 var _ EnumValueDeclNode = (*EnumValueNode)(nil) 90 var _ EnumValueDeclNode = NoSourceNode{} 91 92 // EnumNode represents an enum declaration. Example: 93 // 94 // UNSET = 0 [deprecated = true]; 95 type EnumValueNode struct { 96 compositeNode 97 Name *IdentNode 98 Equals *RuneNode 99 Number IntValueNode 100 Options *CompactOptionsNode 101 Semicolon *RuneNode 102 } 103 104 func (*EnumValueNode) enumElement() {} 105 106 // NewEnumValueNode creates a new *EnumValueNode. All arguments must be non-nil 107 // except opts which is only non-nil if the declaration included options. 108 // - name: The token corresponding to the enum value's name. 109 // - equals: The token corresponding to the '=' rune after the name. 110 // - number: The token corresponding to the enum value's number. 111 // - opts: Optional set of enum value options. 112 // - semicolon: The token corresponding to the ";" rune that ends the declaration. 113 func NewEnumValueNode(name *IdentNode, equals *RuneNode, number IntValueNode, opts *CompactOptionsNode, semicolon *RuneNode) *EnumValueNode { 114 if name == nil { 115 panic("name is nil") 116 } 117 if equals == nil { 118 panic("equals is nil") 119 } 120 if number == nil { 121 panic("number is nil") 122 } 123 if semicolon == nil { 124 panic("semicolon is nil") 125 } 126 numChildren := 4 127 if opts != nil { 128 numChildren++ 129 } 130 children := make([]Node, 0, numChildren) 131 children = append(children, name, equals, number) 132 if opts != nil { 133 children = append(children, opts) 134 } 135 children = append(children, semicolon) 136 return &EnumValueNode{ 137 compositeNode: compositeNode{ 138 children: children, 139 }, 140 Name: name, 141 Equals: equals, 142 Number: number, 143 Options: opts, 144 Semicolon: semicolon, 145 } 146 } 147 148 func (e *EnumValueNode) GetName() Node { 149 return e.Name 150 } 151 152 func (e *EnumValueNode) GetNumber() Node { 153 return e.Number 154 }