github.com/jhump/protoreflect@v1.16.0/desc/protoparse/ast/message.go (about) 1 package ast 2 3 import "fmt" 4 5 // MessageDeclNode is a node in the AST that defines a message type. This 6 // includes normal message fields as well as implicit messages: 7 // - *MessageNode 8 // - *GroupNode (the group is a field and inline message type) 9 // - *MapFieldNode (map fields implicitly define a MapEntry message type) 10 // 11 // This also allows NoSourceNode to be used in place of one of the above 12 // for some usages. 13 type MessageDeclNode interface { 14 Node 15 MessageName() Node 16 } 17 18 var _ MessageDeclNode = (*MessageNode)(nil) 19 var _ MessageDeclNode = (*GroupNode)(nil) 20 var _ MessageDeclNode = (*MapFieldNode)(nil) 21 var _ MessageDeclNode = NoSourceNode{} 22 23 // MessageNode represents a message declaration. Example: 24 // 25 // message Foo { 26 // string name = 1; 27 // repeated string labels = 2; 28 // bytes extra = 3; 29 // } 30 type MessageNode struct { 31 compositeNode 32 Keyword *KeywordNode 33 Name *IdentNode 34 MessageBody 35 } 36 37 func (*MessageNode) fileElement() {} 38 func (*MessageNode) msgElement() {} 39 40 // NewMessageNode creates a new *MessageNode. All arguments must be non-nil. 41 // - keyword: The token corresponding to the "message" keyword. 42 // - name: The token corresponding to the field's name. 43 // - openBrace: The token corresponding to the "{" rune that starts the body. 44 // - decls: All declarations inside the message body. 45 // - closeBrace: The token corresponding to the "}" rune that ends the body. 46 func NewMessageNode(keyword *KeywordNode, name *IdentNode, openBrace *RuneNode, decls []MessageElement, closeBrace *RuneNode) *MessageNode { 47 if keyword == nil { 48 panic("keyword is nil") 49 } 50 if name == nil { 51 panic("name is nil") 52 } 53 if openBrace == nil { 54 panic("openBrace is nil") 55 } 56 if closeBrace == nil { 57 panic("closeBrace is nil") 58 } 59 children := make([]Node, 0, 4+len(decls)) 60 children = append(children, keyword, name, openBrace) 61 for _, decl := range decls { 62 children = append(children, decl) 63 } 64 children = append(children, closeBrace) 65 66 ret := &MessageNode{ 67 compositeNode: compositeNode{ 68 children: children, 69 }, 70 Keyword: keyword, 71 Name: name, 72 } 73 populateMessageBody(&ret.MessageBody, openBrace, decls, closeBrace) 74 return ret 75 } 76 77 func (n *MessageNode) MessageName() Node { 78 return n.Name 79 } 80 81 // MessageBody represents the body of a message. It is used by both 82 // MessageNodes and GroupNodes. 83 type MessageBody struct { 84 OpenBrace *RuneNode 85 Decls []MessageElement 86 CloseBrace *RuneNode 87 } 88 89 func populateMessageBody(m *MessageBody, openBrace *RuneNode, decls []MessageElement, closeBrace *RuneNode) { 90 m.OpenBrace = openBrace 91 m.Decls = decls 92 for _, decl := range decls { 93 switch decl.(type) { 94 case *OptionNode, *FieldNode, *MapFieldNode, *GroupNode, *OneOfNode, 95 *MessageNode, *EnumNode, *ExtendNode, *ExtensionRangeNode, 96 *ReservedNode, *EmptyDeclNode: 97 default: 98 panic(fmt.Sprintf("invalid MessageElement type: %T", decl)) 99 } 100 } 101 m.CloseBrace = closeBrace 102 } 103 104 // MessageElement is an interface implemented by all AST nodes that can 105 // appear in a message body. 106 type MessageElement interface { 107 Node 108 msgElement() 109 } 110 111 var _ MessageElement = (*OptionNode)(nil) 112 var _ MessageElement = (*FieldNode)(nil) 113 var _ MessageElement = (*MapFieldNode)(nil) 114 var _ MessageElement = (*OneOfNode)(nil) 115 var _ MessageElement = (*GroupNode)(nil) 116 var _ MessageElement = (*MessageNode)(nil) 117 var _ MessageElement = (*EnumNode)(nil) 118 var _ MessageElement = (*ExtendNode)(nil) 119 var _ MessageElement = (*ExtensionRangeNode)(nil) 120 var _ MessageElement = (*ReservedNode)(nil) 121 var _ MessageElement = (*EmptyDeclNode)(nil) 122 123 // ExtendNode represents a declaration of extension fields. Example: 124 // 125 // extend google.protobuf.FieldOptions { 126 // bool redacted = 33333; 127 // } 128 type ExtendNode struct { 129 compositeNode 130 Keyword *KeywordNode 131 Extendee IdentValueNode 132 OpenBrace *RuneNode 133 Decls []ExtendElement 134 CloseBrace *RuneNode 135 } 136 137 func (*ExtendNode) fileElement() {} 138 func (*ExtendNode) msgElement() {} 139 140 // NewExtendNode creates a new *ExtendNode. All arguments must be non-nil. 141 // - keyword: The token corresponding to the "extend" keyword. 142 // - extendee: The token corresponding to the name of the extended message. 143 // - openBrace: The token corresponding to the "{" rune that starts the body. 144 // - decls: All declarations inside the message body. 145 // - closeBrace: The token corresponding to the "}" rune that ends the body. 146 func NewExtendNode(keyword *KeywordNode, extendee IdentValueNode, openBrace *RuneNode, decls []ExtendElement, closeBrace *RuneNode) *ExtendNode { 147 if keyword == nil { 148 panic("keyword is nil") 149 } 150 if extendee == nil { 151 panic("extendee is nil") 152 } 153 if openBrace == nil { 154 panic("openBrace is nil") 155 } 156 if closeBrace == nil { 157 panic("closeBrace is nil") 158 } 159 children := make([]Node, 0, 4+len(decls)) 160 children = append(children, keyword, extendee, openBrace) 161 for _, decl := range decls { 162 children = append(children, decl) 163 } 164 children = append(children, closeBrace) 165 166 ret := &ExtendNode{ 167 compositeNode: compositeNode{ 168 children: children, 169 }, 170 Keyword: keyword, 171 Extendee: extendee, 172 OpenBrace: openBrace, 173 Decls: decls, 174 CloseBrace: closeBrace, 175 } 176 for _, decl := range decls { 177 switch decl := decl.(type) { 178 case *FieldNode: 179 decl.Extendee = ret 180 case *GroupNode: 181 decl.Extendee = ret 182 case *EmptyDeclNode: 183 default: 184 panic(fmt.Sprintf("invalid ExtendElement type: %T", decl)) 185 } 186 } 187 return ret 188 } 189 190 // ExtendElement is an interface implemented by all AST nodes that can 191 // appear in the body of an extends declaration. 192 type ExtendElement interface { 193 Node 194 extendElement() 195 } 196 197 var _ ExtendElement = (*FieldNode)(nil) 198 var _ ExtendElement = (*GroupNode)(nil) 199 var _ ExtendElement = (*EmptyDeclNode)(nil)