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