github.com/Big-big-orange/protoreflect@v0.0.0-20240408141420-285cedfdf6a4/desc/protoparse/ast.go (about)

     1  package protoparse
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/bufbuild/protocompile/ast"
     7  
     8  	ast2 "github.com/Big-big-orange/protoreflect/desc/protoparse/ast"
     9  )
    10  
    11  func convertAST(file *ast.FileNode) *ast2.FileNode {
    12  	elements := make([]ast2.FileElement, len(file.Decls))
    13  	for i := range file.Decls {
    14  		elements[i] = convertASTFileElement(file, file.Decls[i])
    15  	}
    16  	root := ast2.NewFileNode(convertASTSyntax(file, file.Syntax), elements)
    17  	eofInfo := file.NodeInfo(file.EOF)
    18  	root.FinalComments = convertASTComments(eofInfo.LeadingComments())
    19  	root.FinalWhitespace = eofInfo.LeadingWhitespace()
    20  	return root
    21  }
    22  
    23  func convertASTSyntax(f *ast.FileNode, s *ast.SyntaxNode) *ast2.SyntaxNode {
    24  	return ast2.NewSyntaxNode(
    25  		convertASTKeyword(f, s.Keyword),
    26  		convertASTRune(f, s.Equals),
    27  		convertASTString(f, s.Syntax),
    28  		convertASTRune(f, s.Semicolon),
    29  	)
    30  }
    31  
    32  func convertASTFileElement(f *ast.FileNode, el ast.FileElement) ast2.FileElement {
    33  	switch el := el.(type) {
    34  	case *ast.ImportNode:
    35  		return convertASTImport(f, el)
    36  	case *ast.PackageNode:
    37  		return convertASTPackage(f, el)
    38  	case *ast.OptionNode:
    39  		return convertASTOption(f, el)
    40  	case *ast.MessageNode:
    41  		return convertASTMessage(f, el)
    42  	case *ast.EnumNode:
    43  		return convertASTEnum(f, el)
    44  	case *ast.ExtendNode:
    45  		return convertASTExtend(f, el)
    46  	case *ast.ServiceNode:
    47  		return convertASTService(f, el)
    48  	case *ast.EmptyDeclNode:
    49  		return convertASTEmpty(f, el)
    50  	default:
    51  		panic(fmt.Sprintf("unrecognized type of ast.FileElement: %T", el))
    52  	}
    53  }
    54  
    55  func convertASTImport(f *ast.FileNode, imp *ast.ImportNode) *ast2.ImportNode {
    56  	var public, weak *ast2.KeywordNode
    57  	if imp.Public != nil {
    58  		public = convertASTKeyword(f, imp.Public)
    59  	}
    60  	if imp.Weak != nil {
    61  		weak = convertASTKeyword(f, imp.Weak)
    62  	}
    63  	return ast2.NewImportNode(
    64  		convertASTKeyword(f, imp.Keyword),
    65  		public, weak,
    66  		convertASTString(f, imp.Name),
    67  		convertASTRune(f, imp.Semicolon),
    68  	)
    69  }
    70  
    71  func convertASTPackage(f *ast.FileNode, p *ast.PackageNode) *ast2.PackageNode {
    72  	return ast2.NewPackageNode(
    73  		convertASTKeyword(f, p.Keyword),
    74  		convertASTIdent(f, p.Name),
    75  		convertASTRune(f, p.Semicolon),
    76  	)
    77  }
    78  
    79  func convertASTOption(f *ast.FileNode, o *ast.OptionNode) *ast2.OptionNode {
    80  	if o.Keyword == nil {
    81  		return ast2.NewCompactOptionNode(
    82  			convertASTOptionName(f, o.Name),
    83  			convertASTRune(f, o.Equals),
    84  			convertASTValue(f, o.Val),
    85  		)
    86  	}
    87  	return ast2.NewOptionNode(
    88  		convertASTKeyword(f, o.Keyword),
    89  		convertASTOptionName(f, o.Name),
    90  		convertASTRune(f, o.Equals),
    91  		convertASTValue(f, o.Val),
    92  		convertASTRune(f, o.Semicolon),
    93  	)
    94  }
    95  
    96  func convertASTOptionName(f *ast.FileNode, n *ast.OptionNameNode) *ast2.OptionNameNode {
    97  	parts := make([]*ast2.FieldReferenceNode, len(n.Parts))
    98  	for i := range n.Parts {
    99  		parts[i] = convertASTFieldReference(f, n.Parts[i])
   100  	}
   101  	dots := make([]*ast2.RuneNode, len(n.Dots))
   102  	for i := range n.Dots {
   103  		dots[i] = convertASTRune(f, n.Dots[i])
   104  	}
   105  	return ast2.NewOptionNameNode(parts, dots)
   106  }
   107  
   108  func convertASTFieldReference(f *ast.FileNode, n *ast.FieldReferenceNode) *ast2.FieldReferenceNode {
   109  	switch {
   110  	case n.IsExtension():
   111  		return ast2.NewExtensionFieldReferenceNode(
   112  			convertASTRune(f, n.Open),
   113  			convertASTIdent(f, n.Name),
   114  			convertASTRune(f, n.Close),
   115  		)
   116  	case n.IsAnyTypeReference():
   117  		return ast2.NewAnyTypeReferenceNode(
   118  			convertASTRune(f, n.Open),
   119  			convertASTIdent(f, n.URLPrefix),
   120  			convertASTRune(f, n.Slash),
   121  			convertASTIdent(f, n.Name),
   122  			convertASTRune(f, n.Close),
   123  		)
   124  	default:
   125  		return ast2.NewFieldReferenceNode(convertASTIdent(f, n.Name).(*ast2.IdentNode))
   126  	}
   127  }
   128  
   129  func convertASTMessage(f *ast.FileNode, m *ast.MessageNode) *ast2.MessageNode {
   130  	decls := make([]ast2.MessageElement, len(m.Decls))
   131  	for i := range m.Decls {
   132  		decls[i] = convertASTMessageElement(f, m.Decls[i])
   133  	}
   134  	return ast2.NewMessageNode(
   135  		convertASTKeyword(f, m.Keyword),
   136  		convertASTIdentToken(f, m.Name),
   137  		convertASTRune(f, m.OpenBrace),
   138  		decls,
   139  		convertASTRune(f, m.CloseBrace),
   140  	)
   141  }
   142  
   143  func convertASTMessageElement(f *ast.FileNode, el ast.MessageElement) ast2.MessageElement {
   144  	switch el := el.(type) {
   145  	case *ast.OptionNode:
   146  		return convertASTOption(f, el)
   147  	case *ast.FieldNode:
   148  		return convertASTField(f, el)
   149  	case *ast.MapFieldNode:
   150  		return convertASTMapField(f, el)
   151  	case *ast.OneofNode:
   152  		return convertASTOneOf(f, el)
   153  	case *ast.GroupNode:
   154  		return convertASTGroup(f, el)
   155  	case *ast.MessageNode:
   156  		return convertASTMessage(f, el)
   157  	case *ast.EnumNode:
   158  		return convertASTEnum(f, el)
   159  	case *ast.ExtendNode:
   160  		return convertASTExtend(f, el)
   161  	case *ast.ExtensionRangeNode:
   162  		return convertASTExtensions(f, el)
   163  	case *ast.ReservedNode:
   164  		return convertASTReserved(f, el)
   165  	case *ast.EmptyDeclNode:
   166  		return convertASTEmpty(f, el)
   167  	default:
   168  		panic(fmt.Sprintf("unrecognized type of ast.MessageElement: %T", el))
   169  	}
   170  }
   171  
   172  func convertASTField(f *ast.FileNode, fld *ast.FieldNode) *ast2.FieldNode {
   173  	var lbl *ast2.KeywordNode
   174  	if fld.Label.KeywordNode != nil {
   175  		lbl = convertASTKeyword(f, fld.Label.KeywordNode)
   176  	}
   177  	var opts *ast2.CompactOptionsNode
   178  	if fld.Options != nil {
   179  		opts = convertASTCompactOptions(f, fld.Options)
   180  	}
   181  	return ast2.NewFieldNode(
   182  		lbl,
   183  		convertASTIdent(f, fld.FldType),
   184  		convertASTIdentToken(f, fld.Name),
   185  		convertASTRune(f, fld.Equals),
   186  		convertASTUintLiteral(f, fld.Tag),
   187  		opts,
   188  		convertASTRune(f, fld.Semicolon),
   189  	)
   190  }
   191  
   192  func convertASTMapField(f *ast.FileNode, fld *ast.MapFieldNode) *ast2.MapFieldNode {
   193  	var opts *ast2.CompactOptionsNode
   194  	if fld.Options != nil {
   195  		opts = convertASTCompactOptions(f, fld.Options)
   196  	}
   197  	return ast2.NewMapFieldNode(
   198  		convertASTMapFieldType(f, fld.MapType),
   199  		convertASTIdentToken(f, fld.Name),
   200  		convertASTRune(f, fld.Equals),
   201  		convertASTUintLiteral(f, fld.Tag),
   202  		opts,
   203  		convertASTRune(f, fld.Semicolon),
   204  	)
   205  }
   206  
   207  func convertASTMapFieldType(f *ast.FileNode, t *ast.MapTypeNode) *ast2.MapTypeNode {
   208  	return ast2.NewMapTypeNode(
   209  		convertASTKeyword(f, t.Keyword),
   210  		convertASTRune(f, t.OpenAngle),
   211  		convertASTIdentToken(f, t.KeyType),
   212  		convertASTRune(f, t.Comma),
   213  		convertASTIdent(f, t.ValueType),
   214  		convertASTRune(f, t.CloseAngle),
   215  	)
   216  }
   217  
   218  func convertASTGroup(f *ast.FileNode, g *ast.GroupNode) *ast2.GroupNode {
   219  	var lbl *ast2.KeywordNode
   220  	if g.Label.KeywordNode != nil {
   221  		lbl = convertASTKeyword(f, g.Label.KeywordNode)
   222  	}
   223  	var opts *ast2.CompactOptionsNode
   224  	if g.Options != nil {
   225  		opts = convertASTCompactOptions(f, g.Options)
   226  	}
   227  	decls := make([]ast2.MessageElement, len(g.Decls))
   228  	for i := range g.Decls {
   229  		decls[i] = convertASTMessageElement(f, g.Decls[i])
   230  	}
   231  	return ast2.NewGroupNode(
   232  		lbl,
   233  		convertASTKeyword(f, g.Keyword),
   234  		convertASTIdentToken(f, g.Name),
   235  		convertASTRune(f, g.Equals),
   236  		convertASTUintLiteral(f, g.Tag),
   237  		opts,
   238  		convertASTRune(f, g.OpenBrace),
   239  		decls,
   240  		convertASTRune(f, g.CloseBrace),
   241  	)
   242  }
   243  
   244  func convertASTOneOf(f *ast.FileNode, oo *ast.OneofNode) *ast2.OneOfNode {
   245  	decls := make([]ast2.OneOfElement, len(oo.Decls))
   246  	for i := range oo.Decls {
   247  		decls[i] = convertASTOneOfElement(f, oo.Decls[i])
   248  	}
   249  	return ast2.NewOneOfNode(
   250  		convertASTKeyword(f, oo.Keyword),
   251  		convertASTIdentToken(f, oo.Name),
   252  		convertASTRune(f, oo.OpenBrace),
   253  		decls,
   254  		convertASTRune(f, oo.CloseBrace),
   255  	)
   256  }
   257  
   258  func convertASTOneOfElement(f *ast.FileNode, el ast.OneofElement) ast2.OneOfElement {
   259  	switch el := el.(type) {
   260  	case *ast.OptionNode:
   261  		return convertASTOption(f, el)
   262  	case *ast.FieldNode:
   263  		return convertASTField(f, el)
   264  	case *ast.GroupNode:
   265  		return convertASTGroup(f, el)
   266  	case *ast.EmptyDeclNode:
   267  		return convertASTEmpty(f, el)
   268  	default:
   269  		panic(fmt.Sprintf("unrecognized type of ast.OneOfElement: %T", el))
   270  	}
   271  }
   272  
   273  func convertASTExtensions(f *ast.FileNode, e *ast.ExtensionRangeNode) *ast2.ExtensionRangeNode {
   274  	var opts *ast2.CompactOptionsNode
   275  	if e.Options != nil {
   276  		opts = convertASTCompactOptions(f, e.Options)
   277  	}
   278  	ranges := make([]*ast2.RangeNode, len(e.Ranges))
   279  	for i := range e.Ranges {
   280  		ranges[i] = convertASTRange(f, e.Ranges[i])
   281  	}
   282  	commas := make([]*ast2.RuneNode, len(e.Commas))
   283  	for i := range e.Commas {
   284  		commas[i] = convertASTRune(f, e.Commas[i])
   285  	}
   286  	return ast2.NewExtensionRangeNode(
   287  		convertASTKeyword(f, e.Keyword),
   288  		ranges, commas, opts,
   289  		convertASTRune(f, e.Semicolon),
   290  	)
   291  }
   292  
   293  func convertASTReserved(f *ast.FileNode, r *ast.ReservedNode) *ast2.ReservedNode {
   294  	ranges := make([]*ast2.RangeNode, len(r.Ranges))
   295  	for i := range r.Ranges {
   296  		ranges[i] = convertASTRange(f, r.Ranges[i])
   297  	}
   298  	commas := make([]*ast2.RuneNode, len(r.Commas))
   299  	for i := range r.Commas {
   300  		commas[i] = convertASTRune(f, r.Commas[i])
   301  	}
   302  	names := make([]ast2.StringValueNode, len(r.Names))
   303  	for i := range r.Names {
   304  		names[i] = convertASTString(f, r.Names[i])
   305  	}
   306  	if len(r.Ranges) > 0 {
   307  		return ast2.NewReservedRangesNode(
   308  			convertASTKeyword(f, r.Keyword),
   309  			ranges, commas,
   310  			convertASTRune(f, r.Semicolon),
   311  		)
   312  	}
   313  	return ast2.NewReservedNamesNode(
   314  		convertASTKeyword(f, r.Keyword),
   315  		names, commas,
   316  		convertASTRune(f, r.Semicolon),
   317  	)
   318  }
   319  
   320  func convertASTRange(f *ast.FileNode, r *ast.RangeNode) *ast2.RangeNode {
   321  	var to, max *ast2.KeywordNode
   322  	var end ast2.IntValueNode
   323  	if r.To != nil {
   324  		to = convertASTKeyword(f, r.To)
   325  	}
   326  	if r.Max != nil {
   327  		max = convertASTKeyword(f, r.Max)
   328  	}
   329  	if r.EndVal != nil {
   330  		end = convertASTInt(f, r.EndVal)
   331  	}
   332  	return ast2.NewRangeNode(
   333  		convertASTInt(f, r.StartVal),
   334  		to, end, max,
   335  	)
   336  }
   337  
   338  func convertASTEnum(f *ast.FileNode, e *ast.EnumNode) *ast2.EnumNode {
   339  	decls := make([]ast2.EnumElement, len(e.Decls))
   340  	for i := range e.Decls {
   341  		decls[i] = convertASTEnumElement(f, e.Decls[i])
   342  	}
   343  	return ast2.NewEnumNode(
   344  		convertASTKeyword(f, e.Keyword),
   345  		convertASTIdentToken(f, e.Name),
   346  		convertASTRune(f, e.OpenBrace),
   347  		decls,
   348  		convertASTRune(f, e.CloseBrace),
   349  	)
   350  }
   351  
   352  func convertASTEnumElement(f *ast.FileNode, el ast.EnumElement) ast2.EnumElement {
   353  	switch el := el.(type) {
   354  	case *ast.OptionNode:
   355  		return convertASTOption(f, el)
   356  	case *ast.EnumValueNode:
   357  		return convertASTEnumValue(f, el)
   358  	case *ast.ReservedNode:
   359  		return convertASTReserved(f, el)
   360  	case *ast.EmptyDeclNode:
   361  		return convertASTEmpty(f, el)
   362  	default:
   363  		panic(fmt.Sprintf("unrecognized type of ast.EnumElement: %T", el))
   364  	}
   365  }
   366  
   367  func convertASTEnumValue(f *ast.FileNode, e *ast.EnumValueNode) *ast2.EnumValueNode {
   368  	var opts *ast2.CompactOptionsNode
   369  	if e.Options != nil {
   370  		opts = convertASTCompactOptions(f, e.Options)
   371  	}
   372  	return ast2.NewEnumValueNode(
   373  		convertASTIdentToken(f, e.Name),
   374  		convertASTRune(f, e.Equals),
   375  		convertASTInt(f, e.Number),
   376  		opts,
   377  		convertASTRune(f, e.Semicolon),
   378  	)
   379  }
   380  
   381  func convertASTExtend(f *ast.FileNode, e *ast.ExtendNode) *ast2.ExtendNode {
   382  	decls := make([]ast2.ExtendElement, len(e.Decls))
   383  	for i := range e.Decls {
   384  		decls[i] = convertASTExtendElement(f, e.Decls[i])
   385  	}
   386  	return ast2.NewExtendNode(
   387  		convertASTKeyword(f, e.Keyword),
   388  		convertASTIdent(f, e.Extendee),
   389  		convertASTRune(f, e.OpenBrace),
   390  		decls,
   391  		convertASTRune(f, e.CloseBrace),
   392  	)
   393  }
   394  
   395  func convertASTExtendElement(f *ast.FileNode, el ast.ExtendElement) ast2.ExtendElement {
   396  	switch el := el.(type) {
   397  	case *ast.FieldNode:
   398  		return convertASTField(f, el)
   399  	case *ast.GroupNode:
   400  		return convertASTGroup(f, el)
   401  	case *ast.EmptyDeclNode:
   402  		return convertASTEmpty(f, el)
   403  	default:
   404  		panic(fmt.Sprintf("unrecognized type of ast.ExtendElement: %T", el))
   405  	}
   406  }
   407  
   408  func convertASTService(f *ast.FileNode, s *ast.ServiceNode) *ast2.ServiceNode {
   409  	decls := make([]ast2.ServiceElement, len(s.Decls))
   410  	for i := range s.Decls {
   411  		decls[i] = convertASTServiceElement(f, s.Decls[i])
   412  	}
   413  	return ast2.NewServiceNode(
   414  		convertASTKeyword(f, s.Keyword),
   415  		convertASTIdentToken(f, s.Name),
   416  		convertASTRune(f, s.OpenBrace),
   417  		decls,
   418  		convertASTRune(f, s.CloseBrace),
   419  	)
   420  }
   421  
   422  func convertASTServiceElement(f *ast.FileNode, el ast.ServiceElement) ast2.ServiceElement {
   423  	switch el := el.(type) {
   424  	case *ast.OptionNode:
   425  		return convertASTOption(f, el)
   426  	case *ast.RPCNode:
   427  		return convertASTMethod(f, el)
   428  	case *ast.EmptyDeclNode:
   429  		return convertASTEmpty(f, el)
   430  	default:
   431  		panic(fmt.Sprintf("unrecognized type of ast.ServiceElement: %T", el))
   432  	}
   433  }
   434  
   435  func convertASTMethod(f *ast.FileNode, m *ast.RPCNode) *ast2.RPCNode {
   436  	if m.OpenBrace == nil {
   437  		return ast2.NewRPCNode(
   438  			convertASTKeyword(f, m.Keyword),
   439  			convertASTIdentToken(f, m.Name),
   440  			convertASTMethodType(f, m.Input),
   441  			convertASTKeyword(f, m.Returns),
   442  			convertASTMethodType(f, m.Output),
   443  			convertASTRune(f, m.Semicolon),
   444  		)
   445  	}
   446  	decls := make([]ast2.RPCElement, len(m.Decls))
   447  	for i := range m.Decls {
   448  		decls[i] = convertASTMethodElement(f, m.Decls[i])
   449  	}
   450  	return ast2.NewRPCNodeWithBody(
   451  		convertASTKeyword(f, m.Keyword),
   452  		convertASTIdentToken(f, m.Name),
   453  		convertASTMethodType(f, m.Input),
   454  		convertASTKeyword(f, m.Returns),
   455  		convertASTMethodType(f, m.Output),
   456  		convertASTRune(f, m.OpenBrace),
   457  		decls,
   458  		convertASTRune(f, m.CloseBrace),
   459  	)
   460  }
   461  
   462  func convertASTMethodElement(f *ast.FileNode, el ast.RPCElement) ast2.RPCElement {
   463  	switch el := el.(type) {
   464  	case *ast.OptionNode:
   465  		return convertASTOption(f, el)
   466  	case *ast.EmptyDeclNode:
   467  		return convertASTEmpty(f, el)
   468  	default:
   469  		panic(fmt.Sprintf("unrecognized type of ast.RPCElement: %T", el))
   470  	}
   471  }
   472  
   473  func convertASTMethodType(f *ast.FileNode, t *ast.RPCTypeNode) *ast2.RPCTypeNode {
   474  	var stream *ast2.KeywordNode
   475  	if t.Stream != nil {
   476  		stream = convertASTKeyword(f, t.Stream)
   477  	}
   478  	return ast2.NewRPCTypeNode(
   479  		convertASTRune(f, t.OpenParen),
   480  		stream,
   481  		convertASTIdent(f, t.MessageType),
   482  		convertASTRune(f, t.CloseParen),
   483  	)
   484  }
   485  
   486  func convertASTCompactOptions(f *ast.FileNode, opts *ast.CompactOptionsNode) *ast2.CompactOptionsNode {
   487  	elems := make([]*ast2.OptionNode, len(opts.Options))
   488  	for i := range opts.Options {
   489  		elems[i] = convertASTOption(f, opts.Options[i])
   490  	}
   491  	commas := make([]*ast2.RuneNode, len(opts.Commas))
   492  	for i := range opts.Commas {
   493  		commas[i] = convertASTRune(f, opts.Commas[i])
   494  	}
   495  	return ast2.NewCompactOptionsNode(
   496  		convertASTRune(f, opts.OpenBracket),
   497  		elems, commas,
   498  		convertASTRune(f, opts.CloseBracket),
   499  	)
   500  }
   501  
   502  func convertASTEmpty(f *ast.FileNode, e *ast.EmptyDeclNode) *ast2.EmptyDeclNode {
   503  	return ast2.NewEmptyDeclNode(convertASTRune(f, e.Semicolon))
   504  }
   505  
   506  func convertASTValue(f *ast.FileNode, v ast.ValueNode) ast2.ValueNode {
   507  	switch v := v.(type) {
   508  	case *ast.IdentNode:
   509  		return convertASTIdentToken(f, v)
   510  	case *ast.CompoundIdentNode:
   511  		return convertASTCompoundIdent(f, v)
   512  	case *ast.StringLiteralNode:
   513  		return convertASTStringLiteral(f, v)
   514  	case *ast.CompoundStringLiteralNode:
   515  		return convertASTCompoundStringLiteral(f, v)
   516  	case *ast.UintLiteralNode:
   517  		return convertASTUintLiteral(f, v)
   518  	case *ast.NegativeIntLiteralNode:
   519  		return convertASTNegativeIntLiteral(f, v)
   520  	case *ast.FloatLiteralNode:
   521  		return convertASTFloatLiteral(f, v)
   522  	case *ast.SpecialFloatLiteralNode:
   523  		return convertASTSpecialFloatLiteral(f, v)
   524  	case *ast.SignedFloatLiteralNode:
   525  		return convertASTSignedFloatLiteral(f, v)
   526  	case *ast.ArrayLiteralNode:
   527  		return convertASTArrayLiteral(f, v)
   528  	case *ast.MessageLiteralNode:
   529  		return convertASTMessageLiteral(f, v)
   530  	default:
   531  		panic(fmt.Sprintf("unrecognized type of ast.ValueNode: %T", v))
   532  	}
   533  }
   534  
   535  func convertASTIdent(f *ast.FileNode, ident ast.IdentValueNode) ast2.IdentValueNode {
   536  	switch ident := ident.(type) {
   537  	case *ast.IdentNode:
   538  		return convertASTIdentToken(f, ident)
   539  	case *ast.CompoundIdentNode:
   540  		return convertASTCompoundIdent(f, ident)
   541  	default:
   542  		panic(fmt.Sprintf("unrecognized type of ast.IdentValueNode: %T", ident))
   543  	}
   544  }
   545  
   546  func convertASTIdentToken(f *ast.FileNode, ident *ast.IdentNode) *ast2.IdentNode {
   547  	return ast2.NewIdentNode(ident.Val, convertASTTokenInfo(f, ident.Token()))
   548  }
   549  
   550  func convertASTCompoundIdent(f *ast.FileNode, ident *ast.CompoundIdentNode) *ast2.CompoundIdentNode {
   551  	var leadingDot *ast2.RuneNode
   552  	if ident.LeadingDot != nil {
   553  		leadingDot = convertASTRune(f, ident.LeadingDot)
   554  	}
   555  	components := make([]*ast2.IdentNode, len(ident.Components))
   556  	for i := range ident.Components {
   557  		components[i] = convertASTIdentToken(f, ident.Components[i])
   558  	}
   559  	dots := make([]*ast2.RuneNode, len(ident.Dots))
   560  	for i := range ident.Dots {
   561  		dots[i] = convertASTRune(f, ident.Dots[i])
   562  	}
   563  	return ast2.NewCompoundIdentNode(leadingDot, components, dots)
   564  }
   565  
   566  func convertASTString(f *ast.FileNode, str ast.StringValueNode) ast2.StringValueNode {
   567  	switch str := str.(type) {
   568  	case *ast.StringLiteralNode:
   569  		return convertASTStringLiteral(f, str)
   570  	case *ast.CompoundStringLiteralNode:
   571  		return convertASTCompoundStringLiteral(f, str)
   572  	default:
   573  		panic(fmt.Sprintf("unrecognized type of ast.StringValueNode: %T", str))
   574  	}
   575  }
   576  
   577  func convertASTStringLiteral(f *ast.FileNode, str *ast.StringLiteralNode) *ast2.StringLiteralNode {
   578  	return ast2.NewStringLiteralNode(str.Val, convertASTTokenInfo(f, str.Token()))
   579  }
   580  
   581  func convertASTCompoundStringLiteral(f *ast.FileNode, str *ast.CompoundStringLiteralNode) *ast2.CompoundStringLiteralNode {
   582  	children := str.Children()
   583  	components := make([]*ast2.StringLiteralNode, len(children))
   584  	for i := range children {
   585  		components[i] = convertASTStringLiteral(f, children[i].(*ast.StringLiteralNode))
   586  	}
   587  	return ast2.NewCompoundLiteralStringNode(components...)
   588  }
   589  
   590  func convertASTInt(f *ast.FileNode, n ast.IntValueNode) ast2.IntValueNode {
   591  	switch n := n.(type) {
   592  	case *ast.UintLiteralNode:
   593  		return convertASTUintLiteral(f, n)
   594  	case *ast.NegativeIntLiteralNode:
   595  		return convertASTNegativeIntLiteral(f, n)
   596  	default:
   597  		panic(fmt.Sprintf("unrecognized type of ast.IntValueNode: %T", n))
   598  	}
   599  }
   600  
   601  func convertASTUintLiteral(f *ast.FileNode, n *ast.UintLiteralNode) *ast2.UintLiteralNode {
   602  	return ast2.NewUintLiteralNode(n.Val, convertASTTokenInfo(f, n.Token()))
   603  }
   604  
   605  func convertASTNegativeIntLiteral(f *ast.FileNode, n *ast.NegativeIntLiteralNode) *ast2.NegativeIntLiteralNode {
   606  	return ast2.NewNegativeIntLiteralNode(convertASTRune(f, n.Minus), convertASTUintLiteral(f, n.Uint))
   607  }
   608  
   609  func convertASTFloat(f *ast.FileNode, n ast.FloatValueNode) ast2.FloatValueNode {
   610  	switch n := n.(type) {
   611  	case *ast.FloatLiteralNode:
   612  		return convertASTFloatLiteral(f, n)
   613  	case *ast.SpecialFloatLiteralNode:
   614  		return convertASTSpecialFloatLiteral(f, n)
   615  	case *ast.UintLiteralNode:
   616  		return convertASTUintLiteral(f, n)
   617  	default:
   618  		panic(fmt.Sprintf("unrecognized type of ast.FloatValueNode: %T", n))
   619  	}
   620  }
   621  
   622  func convertASTFloatLiteral(f *ast.FileNode, n *ast.FloatLiteralNode) *ast2.FloatLiteralNode {
   623  	return ast2.NewFloatLiteralNode(n.Val, convertASTTokenInfo(f, n.Token()))
   624  }
   625  
   626  func convertASTSpecialFloatLiteral(f *ast.FileNode, n *ast.SpecialFloatLiteralNode) *ast2.SpecialFloatLiteralNode {
   627  	return ast2.NewSpecialFloatLiteralNode(convertASTKeyword(f, n.KeywordNode))
   628  }
   629  
   630  func convertASTSignedFloatLiteral(f *ast.FileNode, n *ast.SignedFloatLiteralNode) *ast2.SignedFloatLiteralNode {
   631  	return ast2.NewSignedFloatLiteralNode(convertASTRune(f, n.Sign), convertASTFloat(f, n.Float))
   632  }
   633  
   634  func convertASTArrayLiteral(f *ast.FileNode, ar *ast.ArrayLiteralNode) *ast2.ArrayLiteralNode {
   635  	vals := make([]ast2.ValueNode, len(ar.Elements))
   636  	for i := range ar.Elements {
   637  		vals[i] = convertASTValue(f, ar.Elements[i])
   638  	}
   639  	commas := make([]*ast2.RuneNode, len(ar.Commas))
   640  	for i := range ar.Commas {
   641  		commas[i] = convertASTRune(f, ar.Commas[i])
   642  	}
   643  	return ast2.NewArrayLiteralNode(
   644  		convertASTRune(f, ar.OpenBracket),
   645  		vals, commas,
   646  		convertASTRune(f, ar.CloseBracket),
   647  	)
   648  }
   649  
   650  func convertASTMessageLiteral(f *ast.FileNode, m *ast.MessageLiteralNode) *ast2.MessageLiteralNode {
   651  	fields := make([]*ast2.MessageFieldNode, len(m.Elements))
   652  	for i := range m.Elements {
   653  		fields[i] = convertASTMessageLiteralField(f, m.Elements[i])
   654  	}
   655  	seps := make([]*ast2.RuneNode, len(m.Seps))
   656  	for i := range m.Seps {
   657  		if m.Seps[i] != nil {
   658  			seps[i] = convertASTRune(f, m.Seps[i])
   659  		}
   660  	}
   661  	return ast2.NewMessageLiteralNode(
   662  		convertASTRune(f, m.Open),
   663  		fields, seps,
   664  		convertASTRune(f, m.Close),
   665  	)
   666  }
   667  
   668  func convertASTMessageLiteralField(f *ast.FileNode, fld *ast.MessageFieldNode) *ast2.MessageFieldNode {
   669  	var sep *ast2.RuneNode
   670  	if fld.Sep != nil {
   671  		sep = convertASTRune(f, fld.Sep)
   672  	}
   673  	return ast2.NewMessageFieldNode(
   674  		convertASTFieldReference(f, fld.Name),
   675  		sep,
   676  		convertASTValue(f, fld.Val),
   677  	)
   678  }
   679  
   680  func convertASTKeyword(f *ast.FileNode, k *ast.KeywordNode) *ast2.KeywordNode {
   681  	return ast2.NewKeywordNode(k.Val, convertASTTokenInfo(f, k.Token()))
   682  }
   683  
   684  func convertASTRune(f *ast.FileNode, r *ast.RuneNode) *ast2.RuneNode {
   685  	return ast2.NewRuneNode(r.Rune, convertASTTokenInfo(f, r.Token()))
   686  }
   687  
   688  func convertASTTokenInfo(f *ast.FileNode, tok ast.Token) ast2.TokenInfo {
   689  	info := f.TokenInfo(tok)
   690  	return ast2.TokenInfo{
   691  		PosRange: ast2.PosRange{
   692  			Start: info.Start(),
   693  			End:   info.End(),
   694  		},
   695  		RawText:           info.RawText(),
   696  		LeadingWhitespace: info.LeadingWhitespace(),
   697  		LeadingComments:   convertASTComments(info.LeadingComments()),
   698  		TrailingComments:  convertASTComments(info.TrailingComments()),
   699  	}
   700  }
   701  
   702  func convertASTComments(comments ast.Comments) []ast2.Comment {
   703  	results := make([]ast2.Comment, comments.Len())
   704  	for i := 0; i < comments.Len(); i++ {
   705  		cmt := comments.Index(i)
   706  		results[i] = ast2.Comment{
   707  			PosRange: ast2.PosRange{
   708  				Start: cmt.Start(),
   709  				End:   cmt.End(),
   710  			},
   711  			LeadingWhitespace: cmt.LeadingWhitespace(),
   712  			Text:              cmt.RawText(),
   713  		}
   714  	}
   715  	return results
   716  }