github.com/jhump/protoreflect@v1.16.0/desc/protoparse/ast/service.go (about)

     1  package ast
     2  
     3  import "fmt"
     4  
     5  // ServiceNode represents a service declaration. Example:
     6  //
     7  //	service Foo {
     8  //	  rpc Bar (Baz) returns (Bob);
     9  //	  rpc Frobnitz (stream Parts) returns (Gyzmeaux);
    10  //	}
    11  type ServiceNode struct {
    12  	compositeNode
    13  	Keyword    *KeywordNode
    14  	Name       *IdentNode
    15  	OpenBrace  *RuneNode
    16  	Decls      []ServiceElement
    17  	CloseBrace *RuneNode
    18  }
    19  
    20  func (*ServiceNode) fileElement() {}
    21  
    22  // NewServiceNode creates a new *ServiceNode. All arguments must be non-nil.
    23  //   - keyword: The token corresponding to the "service" keyword.
    24  //   - name: The token corresponding to the service's name.
    25  //   - openBrace: The token corresponding to the "{" rune that starts the body.
    26  //   - decls: All declarations inside the service body.
    27  //   - closeBrace: The token corresponding to the "}" rune that ends the body.
    28  func NewServiceNode(keyword *KeywordNode, name *IdentNode, openBrace *RuneNode, decls []ServiceElement, closeBrace *RuneNode) *ServiceNode {
    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 := decl.(type) {
    50  		case *OptionNode, *RPCNode, *EmptyDeclNode:
    51  		default:
    52  			panic(fmt.Sprintf("invalid ServiceElement type: %T", decl))
    53  		}
    54  	}
    55  
    56  	return &ServiceNode{
    57  		compositeNode: compositeNode{
    58  			children: children,
    59  		},
    60  		Keyword:    keyword,
    61  		Name:       name,
    62  		OpenBrace:  openBrace,
    63  		Decls:      decls,
    64  		CloseBrace: closeBrace,
    65  	}
    66  }
    67  
    68  // ServiceElement is an interface implemented by all AST nodes that can
    69  // appear in the body of a service declaration.
    70  type ServiceElement interface {
    71  	Node
    72  	serviceElement()
    73  }
    74  
    75  var _ ServiceElement = (*OptionNode)(nil)
    76  var _ ServiceElement = (*RPCNode)(nil)
    77  var _ ServiceElement = (*EmptyDeclNode)(nil)
    78  
    79  // RPCDeclNode is a placeholder interface for AST nodes that represent RPC
    80  // declarations. This allows NoSourceNode to be used in place of *RPCNode
    81  // for some usages.
    82  type RPCDeclNode interface {
    83  	Node
    84  	GetInputType() Node
    85  	GetOutputType() Node
    86  }
    87  
    88  var _ RPCDeclNode = (*RPCNode)(nil)
    89  var _ RPCDeclNode = NoSourceNode{}
    90  
    91  // RPCNode represents an RPC declaration. Example:
    92  //
    93  //	rpc Foo (Bar) returns (Baz);
    94  type RPCNode struct {
    95  	compositeNode
    96  	Keyword    *KeywordNode
    97  	Name       *IdentNode
    98  	Input      *RPCTypeNode
    99  	Returns    *KeywordNode
   100  	Output     *RPCTypeNode
   101  	Semicolon  *RuneNode
   102  	OpenBrace  *RuneNode
   103  	Decls      []RPCElement
   104  	CloseBrace *RuneNode
   105  }
   106  
   107  func (n *RPCNode) serviceElement() {}
   108  
   109  // NewRPCNode creates a new *RPCNode with no body. All arguments must be non-nil.
   110  //   - keyword: The token corresponding to the "rpc" keyword.
   111  //   - name: The token corresponding to the RPC's name.
   112  //   - input: The token corresponding to the RPC input message type.
   113  //   - returns: The token corresponding to the "returns" keyword that precedes the output type.
   114  //   - output: The token corresponding to the RPC output message type.
   115  //   - semicolon: The token corresponding to the ";" rune that ends the declaration.
   116  func NewRPCNode(keyword *KeywordNode, name *IdentNode, input *RPCTypeNode, returns *KeywordNode, output *RPCTypeNode, semicolon *RuneNode) *RPCNode {
   117  	if keyword == nil {
   118  		panic("keyword is nil")
   119  	}
   120  	if name == nil {
   121  		panic("name is nil")
   122  	}
   123  	if input == nil {
   124  		panic("input is nil")
   125  	}
   126  	if returns == nil {
   127  		panic("returns is nil")
   128  	}
   129  	if output == nil {
   130  		panic("output is nil")
   131  	}
   132  	if semicolon == nil {
   133  		panic("semicolon is nil")
   134  	}
   135  	children := []Node{keyword, name, input, returns, output, semicolon}
   136  	return &RPCNode{
   137  		compositeNode: compositeNode{
   138  			children: children,
   139  		},
   140  		Keyword:   keyword,
   141  		Name:      name,
   142  		Input:     input,
   143  		Returns:   returns,
   144  		Output:    output,
   145  		Semicolon: semicolon,
   146  	}
   147  }
   148  
   149  // NewRPCNodeWithBody creates a new *RPCNode that includes a body (and possibly
   150  // options). All arguments must be non-nil.
   151  //   - keyword: The token corresponding to the "rpc" keyword.
   152  //   - name: The token corresponding to the RPC's name.
   153  //   - input: The token corresponding to the RPC input message type.
   154  //   - returns: The token corresponding to the "returns" keyword that precedes the output type.
   155  //   - output: The token corresponding to the RPC output message type.
   156  //   - openBrace: The token corresponding to the "{" rune that starts the body.
   157  //   - decls: All declarations inside the RPC body.
   158  //   - closeBrace: The token corresponding to the "}" rune that ends the body.
   159  func NewRPCNodeWithBody(keyword *KeywordNode, name *IdentNode, input *RPCTypeNode, returns *KeywordNode, output *RPCTypeNode, openBrace *RuneNode, decls []RPCElement, closeBrace *RuneNode) *RPCNode {
   160  	if keyword == nil {
   161  		panic("keyword is nil")
   162  	}
   163  	if name == nil {
   164  		panic("name is nil")
   165  	}
   166  	if input == nil {
   167  		panic("input is nil")
   168  	}
   169  	if returns == nil {
   170  		panic("returns is nil")
   171  	}
   172  	if output == nil {
   173  		panic("output is nil")
   174  	}
   175  	if openBrace == nil {
   176  		panic("openBrace is nil")
   177  	}
   178  	if closeBrace == nil {
   179  		panic("closeBrace is nil")
   180  	}
   181  	children := make([]Node, 0, 7+len(decls))
   182  	children = append(children, keyword, name, input, returns, output, openBrace)
   183  	for _, decl := range decls {
   184  		children = append(children, decl)
   185  	}
   186  	children = append(children, closeBrace)
   187  
   188  	for _, decl := range decls {
   189  		switch decl := decl.(type) {
   190  		case *OptionNode, *EmptyDeclNode:
   191  		default:
   192  			panic(fmt.Sprintf("invalid RPCElement type: %T", decl))
   193  		}
   194  	}
   195  
   196  	return &RPCNode{
   197  		compositeNode: compositeNode{
   198  			children: children,
   199  		},
   200  		Keyword:    keyword,
   201  		Name:       name,
   202  		Input:      input,
   203  		Returns:    returns,
   204  		Output:     output,
   205  		OpenBrace:  openBrace,
   206  		Decls:      decls,
   207  		CloseBrace: closeBrace,
   208  	}
   209  }
   210  
   211  func (n *RPCNode) GetInputType() Node {
   212  	return n.Input.MessageType
   213  }
   214  
   215  func (n *RPCNode) GetOutputType() Node {
   216  	return n.Output.MessageType
   217  }
   218  
   219  // RPCElement is an interface implemented by all AST nodes that can
   220  // appear in the body of an rpc declaration (aka method).
   221  type RPCElement interface {
   222  	Node
   223  	methodElement()
   224  }
   225  
   226  var _ RPCElement = (*OptionNode)(nil)
   227  var _ RPCElement = (*EmptyDeclNode)(nil)
   228  
   229  // RPCTypeNode represents the declaration of a request or response type for an
   230  // RPC. Example:
   231  //
   232  //	(stream foo.Bar)
   233  type RPCTypeNode struct {
   234  	compositeNode
   235  	OpenParen   *RuneNode
   236  	Stream      *KeywordNode
   237  	MessageType IdentValueNode
   238  	CloseParen  *RuneNode
   239  }
   240  
   241  // NewRPCTypeNode creates a new *RPCTypeNode. All arguments must be non-nil
   242  // except stream, which may be nil.
   243  //   - openParen: The token corresponding to the "(" rune that starts the declaration.
   244  //   - stream: The token corresponding to the "stream" keyword or nil if not present.
   245  //   - msgType: The token corresponding to the message type's name.
   246  //   - closeParen: The token corresponding to the ")" rune that ends the declaration.
   247  func NewRPCTypeNode(openParen *RuneNode, stream *KeywordNode, msgType IdentValueNode, closeParen *RuneNode) *RPCTypeNode {
   248  	if openParen == nil {
   249  		panic("openParen is nil")
   250  	}
   251  	if msgType == nil {
   252  		panic("msgType is nil")
   253  	}
   254  	if closeParen == nil {
   255  		panic("closeParen is nil")
   256  	}
   257  	var children []Node
   258  	if stream != nil {
   259  		children = []Node{openParen, stream, msgType, closeParen}
   260  	} else {
   261  		children = []Node{openParen, msgType, closeParen}
   262  	}
   263  
   264  	return &RPCTypeNode{
   265  		compositeNode: compositeNode{
   266  			children: children,
   267  		},
   268  		OpenParen:   openParen,
   269  		Stream:      stream,
   270  		MessageType: msgType,
   271  		CloseParen:  closeParen,
   272  	}
   273  }