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

     1  package ast
     2  
     3  import (
     4  	"sort"
     5  	"testing"
     6  
     7  	"github.com/jhump/protoreflect/internal/testutil"
     8  )
     9  
    10  // The single visitor returned has all functions set to record the method call.
    11  // The slice of visitors has one element per function, each with exactly one
    12  // function set. So the first visitor can be used to determine the preferred
    13  // function (which should match the node's concrete type). The slice of visitors
    14  // can be used to enumerate ALL matching function calls.
    15  //
    16  // This function is generated via commented-out code at the bottom of this file.
    17  func testVisitors(methodCalled *string) (*Visitor, []*Visitor) {
    18  	v := &Visitor{
    19  		VisitEnumNode: func(*EnumNode) (bool, *Visitor) {
    20  			*methodCalled = "*EnumNode"
    21  			return false, nil
    22  		},
    23  		VisitEnumValueNode: func(*EnumValueNode) (bool, *Visitor) {
    24  			*methodCalled = "*EnumValueNode"
    25  			return false, nil
    26  		},
    27  		VisitFieldDeclNode: func(FieldDeclNode) (bool, *Visitor) {
    28  			*methodCalled = "FieldDeclNode"
    29  			return false, nil
    30  		},
    31  		VisitFieldNode: func(*FieldNode) (bool, *Visitor) {
    32  			*methodCalled = "*FieldNode"
    33  			return false, nil
    34  		},
    35  		VisitGroupNode: func(*GroupNode) (bool, *Visitor) {
    36  			*methodCalled = "*GroupNode"
    37  			return false, nil
    38  		},
    39  		VisitOneOfNode: func(*OneOfNode) (bool, *Visitor) {
    40  			*methodCalled = "*OneOfNode"
    41  			return false, nil
    42  		},
    43  		VisitMapTypeNode: func(*MapTypeNode) (bool, *Visitor) {
    44  			*methodCalled = "*MapTypeNode"
    45  			return false, nil
    46  		},
    47  		VisitMapFieldNode: func(*MapFieldNode) (bool, *Visitor) {
    48  			*methodCalled = "*MapFieldNode"
    49  			return false, nil
    50  		},
    51  		VisitFileNode: func(*FileNode) (bool, *Visitor) {
    52  			*methodCalled = "*FileNode"
    53  			return false, nil
    54  		},
    55  		VisitSyntaxNode: func(*SyntaxNode) (bool, *Visitor) {
    56  			*methodCalled = "*SyntaxNode"
    57  			return false, nil
    58  		},
    59  		VisitImportNode: func(*ImportNode) (bool, *Visitor) {
    60  			*methodCalled = "*ImportNode"
    61  			return false, nil
    62  		},
    63  		VisitPackageNode: func(*PackageNode) (bool, *Visitor) {
    64  			*methodCalled = "*PackageNode"
    65  			return false, nil
    66  		},
    67  		VisitIdentValueNode: func(IdentValueNode) (bool, *Visitor) {
    68  			*methodCalled = "IdentValueNode"
    69  			return false, nil
    70  		},
    71  		VisitIdentNode: func(*IdentNode) (bool, *Visitor) {
    72  			*methodCalled = "*IdentNode"
    73  			return false, nil
    74  		},
    75  		VisitCompoundIdentNode: func(*CompoundIdentNode) (bool, *Visitor) {
    76  			*methodCalled = "*CompoundIdentNode"
    77  			return false, nil
    78  		},
    79  		VisitKeywordNode: func(*KeywordNode) (bool, *Visitor) {
    80  			*methodCalled = "*KeywordNode"
    81  			return false, nil
    82  		},
    83  		VisitMessageDeclNode: func(MessageDeclNode) (bool, *Visitor) {
    84  			*methodCalled = "MessageDeclNode"
    85  			return false, nil
    86  		},
    87  		VisitMessageNode: func(*MessageNode) (bool, *Visitor) {
    88  			*methodCalled = "*MessageNode"
    89  			return false, nil
    90  		},
    91  		VisitExtendNode: func(*ExtendNode) (bool, *Visitor) {
    92  			*methodCalled = "*ExtendNode"
    93  			return false, nil
    94  		},
    95  		VisitNode: func(Node) (bool, *Visitor) {
    96  			*methodCalled = "Node"
    97  			return false, nil
    98  		},
    99  		VisitTerminalNode: func(TerminalNode) (bool, *Visitor) {
   100  			*methodCalled = "TerminalNode"
   101  			return false, nil
   102  		},
   103  		VisitCompositeNode: func(CompositeNode) (bool, *Visitor) {
   104  			*methodCalled = "CompositeNode"
   105  			return false, nil
   106  		},
   107  		VisitRuneNode: func(*RuneNode) (bool, *Visitor) {
   108  			*methodCalled = "*RuneNode"
   109  			return false, nil
   110  		},
   111  		VisitEmptyDeclNode: func(*EmptyDeclNode) (bool, *Visitor) {
   112  			*methodCalled = "*EmptyDeclNode"
   113  			return false, nil
   114  		},
   115  		VisitOptionNode: func(*OptionNode) (bool, *Visitor) {
   116  			*methodCalled = "*OptionNode"
   117  			return false, nil
   118  		},
   119  		VisitOptionNameNode: func(*OptionNameNode) (bool, *Visitor) {
   120  			*methodCalled = "*OptionNameNode"
   121  			return false, nil
   122  		},
   123  		VisitFieldReferenceNode: func(*FieldReferenceNode) (bool, *Visitor) {
   124  			*methodCalled = "*FieldReferenceNode"
   125  			return false, nil
   126  		},
   127  		VisitCompactOptionsNode: func(*CompactOptionsNode) (bool, *Visitor) {
   128  			*methodCalled = "*CompactOptionsNode"
   129  			return false, nil
   130  		},
   131  		VisitExtensionRangeNode: func(*ExtensionRangeNode) (bool, *Visitor) {
   132  			*methodCalled = "*ExtensionRangeNode"
   133  			return false, nil
   134  		},
   135  		VisitRangeNode: func(*RangeNode) (bool, *Visitor) {
   136  			*methodCalled = "*RangeNode"
   137  			return false, nil
   138  		},
   139  		VisitReservedNode: func(*ReservedNode) (bool, *Visitor) {
   140  			*methodCalled = "*ReservedNode"
   141  			return false, nil
   142  		},
   143  		VisitServiceNode: func(*ServiceNode) (bool, *Visitor) {
   144  			*methodCalled = "*ServiceNode"
   145  			return false, nil
   146  		},
   147  		VisitRPCNode: func(*RPCNode) (bool, *Visitor) {
   148  			*methodCalled = "*RPCNode"
   149  			return false, nil
   150  		},
   151  		VisitRPCTypeNode: func(*RPCTypeNode) (bool, *Visitor) {
   152  			*methodCalled = "*RPCTypeNode"
   153  			return false, nil
   154  		},
   155  		VisitValueNode: func(ValueNode) (bool, *Visitor) {
   156  			*methodCalled = "ValueNode"
   157  			return false, nil
   158  		},
   159  		VisitStringValueNode: func(StringValueNode) (bool, *Visitor) {
   160  			*methodCalled = "StringValueNode"
   161  			return false, nil
   162  		},
   163  		VisitStringLiteralNode: func(*StringLiteralNode) (bool, *Visitor) {
   164  			*methodCalled = "*StringLiteralNode"
   165  			return false, nil
   166  		},
   167  		VisitCompoundStringLiteralNode: func(*CompoundStringLiteralNode) (bool, *Visitor) {
   168  			*methodCalled = "*CompoundStringLiteralNode"
   169  			return false, nil
   170  		},
   171  		VisitIntValueNode: func(IntValueNode) (bool, *Visitor) {
   172  			*methodCalled = "IntValueNode"
   173  			return false, nil
   174  		},
   175  		VisitUintLiteralNode: func(*UintLiteralNode) (bool, *Visitor) {
   176  			*methodCalled = "*UintLiteralNode"
   177  			return false, nil
   178  		},
   179  		VisitPositiveUintLiteralNode: func(*PositiveUintLiteralNode) (bool, *Visitor) {
   180  			*methodCalled = "*PositiveUintLiteralNode"
   181  			return false, nil
   182  		},
   183  		VisitNegativeIntLiteralNode: func(*NegativeIntLiteralNode) (bool, *Visitor) {
   184  			*methodCalled = "*NegativeIntLiteralNode"
   185  			return false, nil
   186  		},
   187  		VisitFloatValueNode: func(FloatValueNode) (bool, *Visitor) {
   188  			*methodCalled = "FloatValueNode"
   189  			return false, nil
   190  		},
   191  		VisitFloatLiteralNode: func(*FloatLiteralNode) (bool, *Visitor) {
   192  			*methodCalled = "*FloatLiteralNode"
   193  			return false, nil
   194  		},
   195  		VisitSpecialFloatLiteralNode: func(*SpecialFloatLiteralNode) (bool, *Visitor) {
   196  			*methodCalled = "*SpecialFloatLiteralNode"
   197  			return false, nil
   198  		},
   199  		VisitSignedFloatLiteralNode: func(*SignedFloatLiteralNode) (bool, *Visitor) {
   200  			*methodCalled = "*SignedFloatLiteralNode"
   201  			return false, nil
   202  		},
   203  		VisitBoolLiteralNode: func(*BoolLiteralNode) (bool, *Visitor) {
   204  			*methodCalled = "*BoolLiteralNode"
   205  			return false, nil
   206  		},
   207  		VisitArrayLiteralNode: func(*ArrayLiteralNode) (bool, *Visitor) {
   208  			*methodCalled = "*ArrayLiteralNode"
   209  			return false, nil
   210  		},
   211  		VisitMessageLiteralNode: func(*MessageLiteralNode) (bool, *Visitor) {
   212  			*methodCalled = "*MessageLiteralNode"
   213  			return false, nil
   214  		},
   215  		VisitMessageFieldNode: func(*MessageFieldNode) (bool, *Visitor) {
   216  			*methodCalled = "*MessageFieldNode"
   217  			return false, nil
   218  		},
   219  	}
   220  	others := []*Visitor{
   221  		{
   222  			VisitEnumNode: v.VisitEnumNode,
   223  		},
   224  		{
   225  			VisitEnumValueNode: v.VisitEnumValueNode,
   226  		},
   227  		{
   228  			VisitFieldDeclNode: v.VisitFieldDeclNode,
   229  		},
   230  		{
   231  			VisitFieldNode: v.VisitFieldNode,
   232  		},
   233  		{
   234  			VisitGroupNode: v.VisitGroupNode,
   235  		},
   236  		{
   237  			VisitOneOfNode: v.VisitOneOfNode,
   238  		},
   239  		{
   240  			VisitMapTypeNode: v.VisitMapTypeNode,
   241  		},
   242  		{
   243  			VisitMapFieldNode: v.VisitMapFieldNode,
   244  		},
   245  		{
   246  			VisitFileNode: v.VisitFileNode,
   247  		},
   248  		{
   249  			VisitSyntaxNode: v.VisitSyntaxNode,
   250  		},
   251  		{
   252  			VisitImportNode: v.VisitImportNode,
   253  		},
   254  		{
   255  			VisitPackageNode: v.VisitPackageNode,
   256  		},
   257  		{
   258  			VisitIdentValueNode: v.VisitIdentValueNode,
   259  		},
   260  		{
   261  			VisitIdentNode: v.VisitIdentNode,
   262  		},
   263  		{
   264  			VisitCompoundIdentNode: v.VisitCompoundIdentNode,
   265  		},
   266  		{
   267  			VisitKeywordNode: v.VisitKeywordNode,
   268  		},
   269  		{
   270  			VisitMessageDeclNode: v.VisitMessageDeclNode,
   271  		},
   272  		{
   273  			VisitMessageNode: v.VisitMessageNode,
   274  		},
   275  		{
   276  			VisitExtendNode: v.VisitExtendNode,
   277  		},
   278  		{
   279  			VisitNode: v.VisitNode,
   280  		},
   281  		{
   282  			VisitTerminalNode: v.VisitTerminalNode,
   283  		},
   284  		{
   285  			VisitCompositeNode: v.VisitCompositeNode,
   286  		},
   287  		{
   288  			VisitRuneNode: v.VisitRuneNode,
   289  		},
   290  		{
   291  			VisitEmptyDeclNode: v.VisitEmptyDeclNode,
   292  		},
   293  		{
   294  			VisitOptionNode: v.VisitOptionNode,
   295  		},
   296  		{
   297  			VisitOptionNameNode: v.VisitOptionNameNode,
   298  		},
   299  		{
   300  			VisitFieldReferenceNode: v.VisitFieldReferenceNode,
   301  		},
   302  		{
   303  			VisitCompactOptionsNode: v.VisitCompactOptionsNode,
   304  		},
   305  		{
   306  			VisitExtensionRangeNode: v.VisitExtensionRangeNode,
   307  		},
   308  		{
   309  			VisitRangeNode: v.VisitRangeNode,
   310  		},
   311  		{
   312  			VisitReservedNode: v.VisitReservedNode,
   313  		},
   314  		{
   315  			VisitServiceNode: v.VisitServiceNode,
   316  		},
   317  		{
   318  			VisitRPCNode: v.VisitRPCNode,
   319  		},
   320  		{
   321  			VisitRPCTypeNode: v.VisitRPCTypeNode,
   322  		},
   323  		{
   324  			VisitValueNode: v.VisitValueNode,
   325  		},
   326  		{
   327  			VisitStringValueNode: v.VisitStringValueNode,
   328  		},
   329  		{
   330  			VisitStringLiteralNode: v.VisitStringLiteralNode,
   331  		},
   332  		{
   333  			VisitCompoundStringLiteralNode: v.VisitCompoundStringLiteralNode,
   334  		},
   335  		{
   336  			VisitIntValueNode: v.VisitIntValueNode,
   337  		},
   338  		{
   339  			VisitUintLiteralNode: v.VisitUintLiteralNode,
   340  		},
   341  		{
   342  			VisitPositiveUintLiteralNode: v.VisitPositiveUintLiteralNode,
   343  		},
   344  		{
   345  			VisitNegativeIntLiteralNode: v.VisitNegativeIntLiteralNode,
   346  		},
   347  		{
   348  			VisitFloatValueNode: v.VisitFloatValueNode,
   349  		},
   350  		{
   351  			VisitFloatLiteralNode: v.VisitFloatLiteralNode,
   352  		},
   353  		{
   354  			VisitSpecialFloatLiteralNode: v.VisitSpecialFloatLiteralNode,
   355  		},
   356  		{
   357  			VisitSignedFloatLiteralNode: v.VisitSignedFloatLiteralNode,
   358  		},
   359  		{
   360  			VisitBoolLiteralNode: v.VisitBoolLiteralNode,
   361  		},
   362  		{
   363  			VisitArrayLiteralNode: v.VisitArrayLiteralNode,
   364  		},
   365  		{
   366  			VisitMessageLiteralNode: v.VisitMessageLiteralNode,
   367  		},
   368  		{
   369  			VisitMessageFieldNode: v.VisitMessageFieldNode,
   370  		},
   371  	}
   372  	return v, others
   373  }
   374  
   375  func TestVisitorAll(t *testing.T) {
   376  	testCases := map[Node][]string{
   377  		(*EnumNode)(nil): {
   378  			"*EnumNode", "CompositeNode", "Node",
   379  		},
   380  		(*EnumValueNode)(nil): {
   381  			"*EnumValueNode", "CompositeNode", "Node",
   382  		},
   383  		(*FieldNode)(nil): {
   384  			"*FieldNode", "FieldDeclNode", "CompositeNode", "Node",
   385  		},
   386  		(*GroupNode)(nil): {
   387  			"*GroupNode", "FieldDeclNode", "MessageDeclNode", "CompositeNode", "Node",
   388  		},
   389  		(*OneOfNode)(nil): {
   390  			"*OneOfNode", "CompositeNode", "Node",
   391  		},
   392  		(*MapTypeNode)(nil): {
   393  			"*MapTypeNode", "CompositeNode", "Node",
   394  		},
   395  		(*MapFieldNode)(nil): {
   396  			"*MapFieldNode", "FieldDeclNode", "MessageDeclNode", "CompositeNode", "Node",
   397  		},
   398  		(*FileNode)(nil): {
   399  			"*FileNode", "CompositeNode", "Node",
   400  		},
   401  		(*SyntaxNode)(nil): {
   402  			"*SyntaxNode", "CompositeNode", "Node",
   403  		},
   404  		(*ImportNode)(nil): {
   405  			"*ImportNode", "CompositeNode", "Node",
   406  		},
   407  		(*PackageNode)(nil): {
   408  			"*PackageNode", "CompositeNode", "Node",
   409  		},
   410  		(*IdentNode)(nil): {
   411  			"*IdentNode", "ValueNode", "IdentValueNode", "TerminalNode", "Node",
   412  		},
   413  		(*CompoundIdentNode)(nil): {
   414  			"*CompoundIdentNode", "ValueNode", "IdentValueNode", "CompositeNode", "Node",
   415  		},
   416  		(*KeywordNode)(nil): {
   417  			"*KeywordNode", "TerminalNode", "Node",
   418  		},
   419  		(*MessageNode)(nil): {
   420  			"*MessageNode", "MessageDeclNode", "CompositeNode", "Node",
   421  		},
   422  		(*ExtendNode)(nil): {
   423  			"*ExtendNode", "CompositeNode", "Node",
   424  		},
   425  		(*RuneNode)(nil): {
   426  			"*RuneNode", "TerminalNode", "Node",
   427  		},
   428  		(*EmptyDeclNode)(nil): {
   429  			"*EmptyDeclNode", "CompositeNode", "Node",
   430  		},
   431  		(*OptionNode)(nil): {
   432  			"*OptionNode", "CompositeNode", "Node",
   433  		},
   434  		(*OptionNameNode)(nil): {
   435  			"*OptionNameNode", "CompositeNode", "Node",
   436  		},
   437  		(*FieldReferenceNode)(nil): {
   438  			"*FieldReferenceNode", "CompositeNode", "Node",
   439  		},
   440  		(*CompactOptionsNode)(nil): {
   441  			"*CompactOptionsNode", "CompositeNode", "Node",
   442  		},
   443  		(*ExtensionRangeNode)(nil): {
   444  			"*ExtensionRangeNode", "CompositeNode", "Node",
   445  		},
   446  		(*RangeNode)(nil): {
   447  			"*RangeNode", "CompositeNode", "Node",
   448  		},
   449  		(*ReservedNode)(nil): {
   450  			"*ReservedNode", "CompositeNode", "Node",
   451  		},
   452  		(*ServiceNode)(nil): {
   453  			"*ServiceNode", "CompositeNode", "Node",
   454  		},
   455  		(*RPCNode)(nil): {
   456  			"*RPCNode", "CompositeNode", "Node",
   457  		},
   458  		(*RPCTypeNode)(nil): {
   459  			"*RPCTypeNode", "CompositeNode", "Node",
   460  		},
   461  		(*StringLiteralNode)(nil): {
   462  			"*StringLiteralNode", "ValueNode", "StringValueNode", "TerminalNode", "Node",
   463  		},
   464  		(*CompoundStringLiteralNode)(nil): {
   465  			"*CompoundStringLiteralNode", "ValueNode", "StringValueNode", "CompositeNode", "Node",
   466  		},
   467  		(*UintLiteralNode)(nil): {
   468  			"*UintLiteralNode", "ValueNode", "IntValueNode", "FloatValueNode", "TerminalNode", "Node",
   469  		},
   470  		(*PositiveUintLiteralNode)(nil): {
   471  			"*PositiveUintLiteralNode", "ValueNode", "IntValueNode", "CompositeNode", "Node",
   472  		},
   473  		(*NegativeIntLiteralNode)(nil): {
   474  			"*NegativeIntLiteralNode", "ValueNode", "IntValueNode", "CompositeNode", "Node",
   475  		},
   476  		(*FloatLiteralNode)(nil): {
   477  			"*FloatLiteralNode", "ValueNode", "FloatValueNode", "TerminalNode", "Node",
   478  		},
   479  		(*SpecialFloatLiteralNode)(nil): {
   480  			"*SpecialFloatLiteralNode", "ValueNode", "FloatValueNode", "TerminalNode", "Node",
   481  		},
   482  		(*SignedFloatLiteralNode)(nil): {
   483  			"*SignedFloatLiteralNode", "ValueNode", "FloatValueNode", "CompositeNode", "Node",
   484  		},
   485  		(*BoolLiteralNode)(nil): {
   486  			"*BoolLiteralNode", "ValueNode", "TerminalNode", "Node",
   487  		},
   488  		(*ArrayLiteralNode)(nil): {
   489  			"*ArrayLiteralNode", "ValueNode", "CompositeNode", "Node",
   490  		},
   491  		(*MessageLiteralNode)(nil): {
   492  			"*MessageLiteralNode", "ValueNode", "CompositeNode", "Node",
   493  		},
   494  		(*MessageFieldNode)(nil): {
   495  			"*MessageFieldNode", "CompositeNode", "Node",
   496  		},
   497  	}
   498  
   499  	for n, expectedCalls := range testCases {
   500  		var call string
   501  		v, all := testVisitors(&call)
   502  		_, _ = v.Visit(n)
   503  		testutil.Eq(t, expectedCalls[0], call)
   504  		var allCalls []string
   505  		for _, v := range all {
   506  			call = ""
   507  			_, _ = v.Visit(n)
   508  			if call != "" {
   509  				allCalls = append(allCalls, call)
   510  			}
   511  		}
   512  		sort.Strings(allCalls)
   513  		sort.Strings(expectedCalls)
   514  		testutil.Eq(t, expectedCalls, allCalls)
   515  	}
   516  }
   517  
   518  func TestVisitorPriorityOrder(t *testing.T) {
   519  	// This tests a handful of cases, concrete types that implement numerous interfaces,
   520  	// and verifies that the preferred function on the visitor is called when present.
   521  	var call string
   522  	var n Node
   523  
   524  	v, _ := testVisitors(&call)
   525  	n = (*StringLiteralNode)(nil)
   526  
   527  	v.VisitStringLiteralNode = nil
   528  	_, _ = v.Visit(n)
   529  	testutil.Eq(t, "StringValueNode", call)
   530  	call = ""
   531  	v.VisitStringValueNode = nil
   532  	_, _ = v.Visit(n)
   533  	testutil.Eq(t, "ValueNode", call)
   534  	call = ""
   535  	v.VisitValueNode = nil
   536  	_, _ = v.Visit(n)
   537  	testutil.Eq(t, "TerminalNode", call)
   538  	call = ""
   539  	v.VisitTerminalNode = nil
   540  	_, _ = v.Visit(n)
   541  	testutil.Eq(t, "Node", call)
   542  	call = ""
   543  	v.VisitNode = nil
   544  	_, _ = v.Visit(n)
   545  	testutil.Eq(t, "", call)
   546  
   547  	v, _ = testVisitors(&call)
   548  	n = (*CompoundStringLiteralNode)(nil)
   549  
   550  	v.VisitCompoundStringLiteralNode = nil
   551  	_, _ = v.Visit(n)
   552  	testutil.Eq(t, "StringValueNode", call)
   553  	call = ""
   554  	v.VisitStringValueNode = nil
   555  	_, _ = v.Visit(n)
   556  	testutil.Eq(t, "ValueNode", call)
   557  	call = ""
   558  	v.VisitValueNode = nil
   559  	_, _ = v.Visit(n)
   560  	testutil.Eq(t, "CompositeNode", call)
   561  	call = ""
   562  	v.VisitCompositeNode = nil
   563  	_, _ = v.Visit(n)
   564  	testutil.Eq(t, "Node", call)
   565  	call = ""
   566  	v.VisitNode = nil
   567  	_, _ = v.Visit(n)
   568  	testutil.Eq(t, "", call)
   569  
   570  	v, _ = testVisitors(&call)
   571  	n = (*UintLiteralNode)(nil)
   572  
   573  	v.VisitUintLiteralNode = nil
   574  	_, _ = v.Visit(n)
   575  	testutil.Eq(t, "IntValueNode", call)
   576  	call = ""
   577  	v.VisitIntValueNode = nil
   578  	_, _ = v.Visit(n)
   579  	testutil.Eq(t, "FloatValueNode", call)
   580  	call = ""
   581  	v.VisitFloatValueNode = nil
   582  	_, _ = v.Visit(n)
   583  	testutil.Eq(t, "ValueNode", call)
   584  	call = ""
   585  	v.VisitValueNode = nil
   586  	_, _ = v.Visit(n)
   587  	testutil.Eq(t, "TerminalNode", call)
   588  	call = ""
   589  	v.VisitTerminalNode = nil
   590  	_, _ = v.Visit(n)
   591  	testutil.Eq(t, "Node", call)
   592  	call = ""
   593  	v.VisitNode = nil
   594  	_, _ = v.Visit(n)
   595  	testutil.Eq(t, "", call)
   596  
   597  	v, _ = testVisitors(&call)
   598  	n = (*GroupNode)(nil)
   599  
   600  	v.VisitGroupNode = nil
   601  	_, _ = v.Visit(n)
   602  	testutil.Eq(t, "FieldDeclNode", call)
   603  	call = ""
   604  	v.VisitFieldDeclNode = nil
   605  	_, _ = v.Visit(n)
   606  	testutil.Eq(t, "MessageDeclNode", call)
   607  	call = ""
   608  	v.VisitMessageDeclNode = nil
   609  	_, _ = v.Visit(n)
   610  	testutil.Eq(t, "CompositeNode", call)
   611  	call = ""
   612  	v.VisitCompositeNode = nil
   613  	_, _ = v.Visit(n)
   614  	testutil.Eq(t, "Node", call)
   615  	call = ""
   616  	v.VisitNode = nil
   617  	_, _ = v.Visit(n)
   618  	testutil.Eq(t, "", call)
   619  
   620  	v, _ = testVisitors(&call)
   621  	n = (*MapFieldNode)(nil)
   622  
   623  	v.VisitMapFieldNode = nil
   624  	_, _ = v.Visit(n)
   625  	testutil.Eq(t, "FieldDeclNode", call)
   626  	call = ""
   627  	v.VisitFieldDeclNode = nil
   628  	_, _ = v.Visit(n)
   629  	testutil.Eq(t, "MessageDeclNode", call)
   630  	call = ""
   631  	v.VisitMessageDeclNode = nil
   632  	_, _ = v.Visit(n)
   633  	testutil.Eq(t, "CompositeNode", call)
   634  	call = ""
   635  	v.VisitCompositeNode = nil
   636  	_, _ = v.Visit(n)
   637  	testutil.Eq(t, "Node", call)
   638  	call = ""
   639  	v.VisitNode = nil
   640  	_, _ = v.Visit(n)
   641  	testutil.Eq(t, "", call)
   642  }
   643  
   644  //func TestDoGenerate(t *testing.T) {
   645  //	generateVisitors()
   646  //}
   647  //
   648  //func generateVisitors() {
   649  //	// This is manually-curated list of all node types in this package
   650  //	// Not all of them are valid as visitor functions, since we intentionally
   651  //	// omit NoSourceNode, SyntheticMapFieldNode, the various *Element interfaces,
   652  //	// and all of the *DeclNode interfaces that have only one real impl.
   653  //	types := `
   654  //*EnumNode
   655  //EnumElement
   656  //EnumValueDeclNode
   657  //*EnumValueNode
   658  //FieldDeclNode
   659  //*FieldNode
   660  //*FieldLabel
   661  //*GroupNode
   662  //*OneOfNode
   663  //OneOfElement
   664  //*MapTypeNode
   665  //*MapFieldNode
   666  //*SyntheticMapField
   667  //FileDeclNode
   668  //*FileNode
   669  //FileElement
   670  //*SyntaxNode
   671  //*ImportNode
   672  //*PackageNode
   673  //IdentValueNode
   674  //*IdentNode
   675  //*CompoundIdentNode
   676  //*KeywordNode
   677  //MessageDeclNode
   678  //*MessageNode
   679  //MessageElement
   680  //*ExtendNode
   681  //ExtendElement
   682  //Node
   683  //TerminalNode
   684  //CompositeNode
   685  //*RuneNode
   686  //*EmptyDeclNode
   687  //OptionDeclNode
   688  //*OptionNode
   689  //*OptionNameNode
   690  //*FieldReferenceNode
   691  //*CompactOptionsNode
   692  //*ExtensionRangeNode
   693  //RangeDeclNode
   694  //*RangeNode
   695  //*ReservedNode
   696  //*ServiceNode
   697  //ServiceElement
   698  //RPCDeclNode
   699  //*RPCNode
   700  //RPCElement
   701  //*RPCTypeNode
   702  //ValueNode
   703  //StringValueNode
   704  //*StringLiteralNode
   705  //*CompoundStringLiteralNode
   706  //IntValueNode
   707  //*UintLiteralNode
   708  //*PositiveUintLiteralNode
   709  //*NegativeIntLiteralNode
   710  //FloatValueNode
   711  //*FloatLiteralNode
   712  //*SpecialFloatLiteralNode
   713  //*SignedFloatLiteralNode
   714  //*BoolLiteralNode
   715  //*ArrayLiteralNode
   716  //*MessageLiteralNode
   717  //*MessageFieldNode
   718  //`
   719  //	strs := strings.Split(types, "\n")
   720  //	fmt.Println(`func testVisitors(methodCalled *string) (*Visitor, []*Visitor) {`)
   721  //	fmt.Println(`	v := &Visitor{`)
   722  //	for _, str := range strs {
   723  //		if str == "" {
   724  //			continue
   725  //		}
   726  //		name := strings.TrimPrefix(str, "*")
   727  //		fmt.Printf(`		Visit%s: func(%s) (bool, *Visitor) {`, name, str); fmt.Println()
   728  //		fmt.Printf(`			*methodCalled = "%s"`, str); fmt.Println()
   729  //		fmt.Println(`			return false, nil`)
   730  //		fmt.Println(`		},`)
   731  //	}
   732  //	fmt.Println(`	}`)
   733  //	fmt.Println(`	others := []*Visitor{`)
   734  //	for _, str := range strs {
   735  //		if str == "" {
   736  //			continue
   737  //		}
   738  //		name := strings.TrimPrefix(str, "*")
   739  //		fmt.Println(`		{`)
   740  //		fmt.Printf(`			Visit%s: v.Visit%s,`, name, name); fmt.Println()
   741  //		fmt.Println(`		},`)
   742  //	}
   743  //	fmt.Println(`	}`)
   744  //	fmt.Println(`}`)
   745  //}