// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated by the codec package. DO NOT EDIT.

package godoc

import (
	"go/ast"
	"go/token"
	"golang.org/x/pkgsite/internal/godoc/codec"
)

// Fields of ast_ArrayType: Lbrack Len Elt

func encode_ast_ArrayType(e *codec.Encoder, x *ast.ArrayType) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Lbrack != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Lbrack))
	}
	if x.Len != nil {
		e.EncodeUint(1)
		e.EncodeAny(x.Len)
	}
	if x.Elt != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Elt)
	}
	e.EndStruct()
}

func decode_ast_ArrayType(d *codec.Decoder, p **ast.ArrayType) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.ArrayType)
		return
	}
	var x ast.ArrayType
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Lbrack = token.Pos(d.DecodeInt())
		case 1:
			x.Len = d.DecodeAny().(ast.Expr)
		case 2:
			x.Elt = d.DecodeAny().(ast.Expr)
		default:
			d.UnknownField("ast.ArrayType", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.ArrayType{},
		func(e *codec.Encoder, x any) { encode_ast_ArrayType(e, x.(*ast.ArrayType)) },
		func(d *codec.Decoder) any {
			var x *ast.ArrayType
			decode_ast_ArrayType(d, &x)
			return x
		})
}

// Fields of ast_AssignStmt: Lhs TokPos Tok Rhs

func encode_ast_AssignStmt(e *codec.Encoder, x *ast.AssignStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Lhs != nil {
		e.EncodeUint(0)
		encode_slice_ast_Expr(e, x.Lhs)
	}
	if x.TokPos != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.TokPos))
	}
	if x.Tok != 0 {
		e.EncodeUint(2)
		e.EncodeInt(int64(x.Tok))
	}
	if x.Rhs != nil {
		e.EncodeUint(3)
		encode_slice_ast_Expr(e, x.Rhs)
	}
	e.EndStruct()
}

func decode_ast_AssignStmt(d *codec.Decoder, p **ast.AssignStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.AssignStmt)
		return
	}
	var x ast.AssignStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			decode_slice_ast_Expr(d, &x.Lhs)
		case 1:
			x.TokPos = token.Pos(d.DecodeInt())
		case 2:
			x.Tok = token.Token(d.DecodeInt())
		case 3:
			decode_slice_ast_Expr(d, &x.Rhs)
		default:
			d.UnknownField("ast.AssignStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.AssignStmt{},
		func(e *codec.Encoder, x any) { encode_ast_AssignStmt(e, x.(*ast.AssignStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.AssignStmt
			decode_ast_AssignStmt(d, &x)
			return x
		})
}

// Fields of ast_BadDecl: From To

func encode_ast_BadDecl(e *codec.Encoder, x *ast.BadDecl) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.From != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.From))
	}
	if x.To != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.To))
	}
	e.EndStruct()
}

func decode_ast_BadDecl(d *codec.Decoder, p **ast.BadDecl) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.BadDecl)
		return
	}
	var x ast.BadDecl
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.From = token.Pos(d.DecodeInt())
		case 1:
			x.To = token.Pos(d.DecodeInt())
		default:
			d.UnknownField("ast.BadDecl", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.BadDecl{},
		func(e *codec.Encoder, x any) { encode_ast_BadDecl(e, x.(*ast.BadDecl)) },
		func(d *codec.Decoder) any {
			var x *ast.BadDecl
			decode_ast_BadDecl(d, &x)
			return x
		})
}

// Fields of ast_BadExpr: From To

func encode_ast_BadExpr(e *codec.Encoder, x *ast.BadExpr) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.From != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.From))
	}
	if x.To != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.To))
	}
	e.EndStruct()
}

func decode_ast_BadExpr(d *codec.Decoder, p **ast.BadExpr) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.BadExpr)
		return
	}
	var x ast.BadExpr
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.From = token.Pos(d.DecodeInt())
		case 1:
			x.To = token.Pos(d.DecodeInt())
		default:
			d.UnknownField("ast.BadExpr", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.BadExpr{},
		func(e *codec.Encoder, x any) { encode_ast_BadExpr(e, x.(*ast.BadExpr)) },
		func(d *codec.Decoder) any {
			var x *ast.BadExpr
			decode_ast_BadExpr(d, &x)
			return x
		})
}

// Fields of ast_BadStmt: From To

func encode_ast_BadStmt(e *codec.Encoder, x *ast.BadStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.From != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.From))
	}
	if x.To != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.To))
	}
	e.EndStruct()
}

func decode_ast_BadStmt(d *codec.Decoder, p **ast.BadStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.BadStmt)
		return
	}
	var x ast.BadStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.From = token.Pos(d.DecodeInt())
		case 1:
			x.To = token.Pos(d.DecodeInt())
		default:
			d.UnknownField("ast.BadStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.BadStmt{},
		func(e *codec.Encoder, x any) { encode_ast_BadStmt(e, x.(*ast.BadStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.BadStmt
			decode_ast_BadStmt(d, &x)
			return x
		})
}

// Fields of ast_BasicLit: ValuePos Kind Value

func encode_ast_BasicLit(e *codec.Encoder, x *ast.BasicLit) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.ValuePos != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.ValuePos))
	}
	if x.Kind != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Kind))
	}
	if x.Value != "" {
		e.EncodeUint(2)
		e.EncodeString(x.Value)
	}
	e.EndStruct()
}

func decode_ast_BasicLit(d *codec.Decoder, p **ast.BasicLit) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.BasicLit)
		return
	}
	var x ast.BasicLit
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.ValuePos = token.Pos(d.DecodeInt())
		case 1:
			x.Kind = token.Token(d.DecodeInt())
		case 2:
			x.Value = d.DecodeString()
		default:
			d.UnknownField("ast.BasicLit", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.BasicLit{},
		func(e *codec.Encoder, x any) { encode_ast_BasicLit(e, x.(*ast.BasicLit)) },
		func(d *codec.Decoder) any {
			var x *ast.BasicLit
			decode_ast_BasicLit(d, &x)
			return x
		})
}

// Fields of ast_BinaryExpr: X OpPos Op Y

func encode_ast_BinaryExpr(e *codec.Encoder, x *ast.BinaryExpr) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.X != nil {
		e.EncodeUint(0)
		e.EncodeAny(x.X)
	}
	if x.OpPos != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.OpPos))
	}
	if x.Op != 0 {
		e.EncodeUint(2)
		e.EncodeInt(int64(x.Op))
	}
	if x.Y != nil {
		e.EncodeUint(3)
		e.EncodeAny(x.Y)
	}
	e.EndStruct()
}

func decode_ast_BinaryExpr(d *codec.Decoder, p **ast.BinaryExpr) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.BinaryExpr)
		return
	}
	var x ast.BinaryExpr
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.X = d.DecodeAny().(ast.Expr)
		case 1:
			x.OpPos = token.Pos(d.DecodeInt())
		case 2:
			x.Op = token.Token(d.DecodeInt())
		case 3:
			x.Y = d.DecodeAny().(ast.Expr)
		default:
			d.UnknownField("ast.BinaryExpr", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.BinaryExpr{},
		func(e *codec.Encoder, x any) { encode_ast_BinaryExpr(e, x.(*ast.BinaryExpr)) },
		func(d *codec.Decoder) any {
			var x *ast.BinaryExpr
			decode_ast_BinaryExpr(d, &x)
			return x
		})
}

// Fields of ast_BlockStmt: Lbrace List Rbrace

func encode_ast_BlockStmt(e *codec.Encoder, x *ast.BlockStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Lbrace != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Lbrace))
	}
	if x.List != nil {
		e.EncodeUint(1)
		encode_slice_ast_Stmt(e, x.List)
	}
	if x.Rbrace != 0 {
		e.EncodeUint(2)
		e.EncodeInt(int64(x.Rbrace))
	}
	e.EndStruct()
}

func decode_ast_BlockStmt(d *codec.Decoder, p **ast.BlockStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.BlockStmt)
		return
	}
	var x ast.BlockStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Lbrace = token.Pos(d.DecodeInt())
		case 1:
			decode_slice_ast_Stmt(d, &x.List)
		case 2:
			x.Rbrace = token.Pos(d.DecodeInt())
		default:
			d.UnknownField("ast.BlockStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.BlockStmt{},
		func(e *codec.Encoder, x any) { encode_ast_BlockStmt(e, x.(*ast.BlockStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.BlockStmt
			decode_ast_BlockStmt(d, &x)
			return x
		})
}

// Fields of ast_BranchStmt: TokPos Tok Label

func encode_ast_BranchStmt(e *codec.Encoder, x *ast.BranchStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.TokPos != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.TokPos))
	}
	if x.Tok != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Tok))
	}
	if x.Label != nil {
		e.EncodeUint(2)
		encode_ast_Ident(e, x.Label)
	}
	e.EndStruct()
}

func decode_ast_BranchStmt(d *codec.Decoder, p **ast.BranchStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.BranchStmt)
		return
	}
	var x ast.BranchStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.TokPos = token.Pos(d.DecodeInt())
		case 1:
			x.Tok = token.Token(d.DecodeInt())
		case 2:
			decode_ast_Ident(d, &x.Label)
		default:
			d.UnknownField("ast.BranchStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.BranchStmt{},
		func(e *codec.Encoder, x any) { encode_ast_BranchStmt(e, x.(*ast.BranchStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.BranchStmt
			decode_ast_BranchStmt(d, &x)
			return x
		})
}

// Fields of ast_CallExpr: Fun Lparen Args Ellipsis Rparen

func encode_ast_CallExpr(e *codec.Encoder, x *ast.CallExpr) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Fun != nil {
		e.EncodeUint(0)
		e.EncodeAny(x.Fun)
	}
	if x.Lparen != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Lparen))
	}
	if x.Args != nil {
		e.EncodeUint(2)
		encode_slice_ast_Expr(e, x.Args)
	}
	if x.Ellipsis != 0 {
		e.EncodeUint(3)
		e.EncodeInt(int64(x.Ellipsis))
	}
	if x.Rparen != 0 {
		e.EncodeUint(4)
		e.EncodeInt(int64(x.Rparen))
	}
	e.EndStruct()
}

func decode_ast_CallExpr(d *codec.Decoder, p **ast.CallExpr) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.CallExpr)
		return
	}
	var x ast.CallExpr
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Fun = d.DecodeAny().(ast.Expr)
		case 1:
			x.Lparen = token.Pos(d.DecodeInt())
		case 2:
			decode_slice_ast_Expr(d, &x.Args)
		case 3:
			x.Ellipsis = token.Pos(d.DecodeInt())
		case 4:
			x.Rparen = token.Pos(d.DecodeInt())
		default:
			d.UnknownField("ast.CallExpr", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.CallExpr{},
		func(e *codec.Encoder, x any) { encode_ast_CallExpr(e, x.(*ast.CallExpr)) },
		func(d *codec.Decoder) any {
			var x *ast.CallExpr
			decode_ast_CallExpr(d, &x)
			return x
		})
}

// Fields of ast_CaseClause: Case List Colon Body

func encode_ast_CaseClause(e *codec.Encoder, x *ast.CaseClause) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Case != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Case))
	}
	if x.List != nil {
		e.EncodeUint(1)
		encode_slice_ast_Expr(e, x.List)
	}
	if x.Colon != 0 {
		e.EncodeUint(2)
		e.EncodeInt(int64(x.Colon))
	}
	if x.Body != nil {
		e.EncodeUint(3)
		encode_slice_ast_Stmt(e, x.Body)
	}
	e.EndStruct()
}

func decode_ast_CaseClause(d *codec.Decoder, p **ast.CaseClause) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.CaseClause)
		return
	}
	var x ast.CaseClause
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Case = token.Pos(d.DecodeInt())
		case 1:
			decode_slice_ast_Expr(d, &x.List)
		case 2:
			x.Colon = token.Pos(d.DecodeInt())
		case 3:
			decode_slice_ast_Stmt(d, &x.Body)
		default:
			d.UnknownField("ast.CaseClause", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.CaseClause{},
		func(e *codec.Encoder, x any) { encode_ast_CaseClause(e, x.(*ast.CaseClause)) },
		func(d *codec.Decoder) any {
			var x *ast.CaseClause
			decode_ast_CaseClause(d, &x)
			return x
		})
}

// Fields of ast_ChanType: Begin Arrow Dir Value

func encode_ast_ChanType(e *codec.Encoder, x *ast.ChanType) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Begin != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Begin))
	}
	if x.Arrow != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Arrow))
	}
	if x.Dir != 0 {
		e.EncodeUint(2)
		e.EncodeInt(int64(x.Dir))
	}
	if x.Value != nil {
		e.EncodeUint(3)
		e.EncodeAny(x.Value)
	}
	e.EndStruct()
}

func decode_ast_ChanType(d *codec.Decoder, p **ast.ChanType) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.ChanType)
		return
	}
	var x ast.ChanType
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Begin = token.Pos(d.DecodeInt())
		case 1:
			x.Arrow = token.Pos(d.DecodeInt())
		case 2:
			x.Dir = ast.ChanDir(d.DecodeInt())
		case 3:
			x.Value = d.DecodeAny().(ast.Expr)
		default:
			d.UnknownField("ast.ChanType", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.ChanType{},
		func(e *codec.Encoder, x any) { encode_ast_ChanType(e, x.(*ast.ChanType)) },
		func(d *codec.Decoder) any {
			var x *ast.ChanType
			decode_ast_ChanType(d, &x)
			return x
		})
}

// Fields of ast_CommClause: Case Comm Colon Body

func encode_ast_CommClause(e *codec.Encoder, x *ast.CommClause) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Case != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Case))
	}
	if x.Comm != nil {
		e.EncodeUint(1)
		e.EncodeAny(x.Comm)
	}
	if x.Colon != 0 {
		e.EncodeUint(2)
		e.EncodeInt(int64(x.Colon))
	}
	if x.Body != nil {
		e.EncodeUint(3)
		encode_slice_ast_Stmt(e, x.Body)
	}
	e.EndStruct()
}

func decode_ast_CommClause(d *codec.Decoder, p **ast.CommClause) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.CommClause)
		return
	}
	var x ast.CommClause
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Case = token.Pos(d.DecodeInt())
		case 1:
			x.Comm = d.DecodeAny().(ast.Stmt)
		case 2:
			x.Colon = token.Pos(d.DecodeInt())
		case 3:
			decode_slice_ast_Stmt(d, &x.Body)
		default:
			d.UnknownField("ast.CommClause", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.CommClause{},
		func(e *codec.Encoder, x any) { encode_ast_CommClause(e, x.(*ast.CommClause)) },
		func(d *codec.Decoder) any {
			var x *ast.CommClause
			decode_ast_CommClause(d, &x)
			return x
		})
}

// Fields of ast_CommentGroup: List

func encode_ast_CommentGroup(e *codec.Encoder, x *ast.CommentGroup) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.List != nil {
		e.EncodeUint(0)
		encode_slice_ast_Comment(e, x.List)
	}
	e.EndStruct()
}

func decode_ast_CommentGroup(d *codec.Decoder, p **ast.CommentGroup) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.CommentGroup)
		return
	}
	var x ast.CommentGroup
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			decode_slice_ast_Comment(d, &x.List)
		default:
			d.UnknownField("ast.CommentGroup", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.CommentGroup{},
		func(e *codec.Encoder, x any) { encode_ast_CommentGroup(e, x.(*ast.CommentGroup)) },
		func(d *codec.Decoder) any {
			var x *ast.CommentGroup
			decode_ast_CommentGroup(d, &x)
			return x
		})
}

// Fields of ast_Comment: Slash Text

func encode_ast_Comment(e *codec.Encoder, x *ast.Comment) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Slash != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Slash))
	}
	if x.Text != "" {
		e.EncodeUint(1)
		e.EncodeString(x.Text)
	}
	e.EndStruct()
}

func decode_ast_Comment(d *codec.Decoder, p **ast.Comment) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.Comment)
		return
	}
	var x ast.Comment
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Slash = token.Pos(d.DecodeInt())
		case 1:
			x.Text = d.DecodeString()
		default:
			d.UnknownField("ast.Comment", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.Comment{},
		func(e *codec.Encoder, x any) { encode_ast_Comment(e, x.(*ast.Comment)) },
		func(d *codec.Decoder) any {
			var x *ast.Comment
			decode_ast_Comment(d, &x)
			return x
		})
}

// Fields of ast_CompositeLit: Type Lbrace Elts Rbrace Incomplete

func encode_ast_CompositeLit(e *codec.Encoder, x *ast.CompositeLit) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Type != nil {
		e.EncodeUint(0)
		e.EncodeAny(x.Type)
	}
	if x.Lbrace != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Lbrace))
	}
	if x.Elts != nil {
		e.EncodeUint(2)
		encode_slice_ast_Expr(e, x.Elts)
	}
	if x.Rbrace != 0 {
		e.EncodeUint(3)
		e.EncodeInt(int64(x.Rbrace))
	}
	if x.Incomplete != false {
		e.EncodeUint(4)
		e.EncodeBool(x.Incomplete)
	}
	e.EndStruct()
}

func decode_ast_CompositeLit(d *codec.Decoder, p **ast.CompositeLit) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.CompositeLit)
		return
	}
	var x ast.CompositeLit
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Type = d.DecodeAny().(ast.Expr)
		case 1:
			x.Lbrace = token.Pos(d.DecodeInt())
		case 2:
			decode_slice_ast_Expr(d, &x.Elts)
		case 3:
			x.Rbrace = token.Pos(d.DecodeInt())
		case 4:
			x.Incomplete = d.DecodeBool()
		default:
			d.UnknownField("ast.CompositeLit", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.CompositeLit{},
		func(e *codec.Encoder, x any) { encode_ast_CompositeLit(e, x.(*ast.CompositeLit)) },
		func(d *codec.Decoder) any {
			var x *ast.CompositeLit
			decode_ast_CompositeLit(d, &x)
			return x
		})
}

// Fields of ast_DeclStmt: Decl

func encode_ast_DeclStmt(e *codec.Encoder, x *ast.DeclStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Decl != nil {
		e.EncodeUint(0)
		e.EncodeAny(x.Decl)
	}
	e.EndStruct()
}

func decode_ast_DeclStmt(d *codec.Decoder, p **ast.DeclStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.DeclStmt)
		return
	}
	var x ast.DeclStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Decl = d.DecodeAny().(ast.Decl)
		default:
			d.UnknownField("ast.DeclStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.DeclStmt{},
		func(e *codec.Encoder, x any) { encode_ast_DeclStmt(e, x.(*ast.DeclStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.DeclStmt
			decode_ast_DeclStmt(d, &x)
			return x
		})
}

// Fields of ast_DeferStmt: Defer Call

func encode_ast_DeferStmt(e *codec.Encoder, x *ast.DeferStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Defer != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Defer))
	}
	if x.Call != nil {
		e.EncodeUint(1)
		encode_ast_CallExpr(e, x.Call)
	}
	e.EndStruct()
}

func decode_ast_DeferStmt(d *codec.Decoder, p **ast.DeferStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.DeferStmt)
		return
	}
	var x ast.DeferStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Defer = token.Pos(d.DecodeInt())
		case 1:
			decode_ast_CallExpr(d, &x.Call)
		default:
			d.UnknownField("ast.DeferStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.DeferStmt{},
		func(e *codec.Encoder, x any) { encode_ast_DeferStmt(e, x.(*ast.DeferStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.DeferStmt
			decode_ast_DeferStmt(d, &x)
			return x
		})
}

// Fields of ast_Ellipsis: Ellipsis Elt

func encode_ast_Ellipsis(e *codec.Encoder, x *ast.Ellipsis) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Ellipsis != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Ellipsis))
	}
	if x.Elt != nil {
		e.EncodeUint(1)
		e.EncodeAny(x.Elt)
	}
	e.EndStruct()
}

func decode_ast_Ellipsis(d *codec.Decoder, p **ast.Ellipsis) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.Ellipsis)
		return
	}
	var x ast.Ellipsis
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Ellipsis = token.Pos(d.DecodeInt())
		case 1:
			x.Elt = d.DecodeAny().(ast.Expr)
		default:
			d.UnknownField("ast.Ellipsis", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.Ellipsis{},
		func(e *codec.Encoder, x any) { encode_ast_Ellipsis(e, x.(*ast.Ellipsis)) },
		func(d *codec.Decoder) any {
			var x *ast.Ellipsis
			decode_ast_Ellipsis(d, &x)
			return x
		})
}

// Fields of ast_EmptyStmt: Semicolon Implicit

func encode_ast_EmptyStmt(e *codec.Encoder, x *ast.EmptyStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Semicolon != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Semicolon))
	}
	if x.Implicit != false {
		e.EncodeUint(1)
		e.EncodeBool(x.Implicit)
	}
	e.EndStruct()
}

func decode_ast_EmptyStmt(d *codec.Decoder, p **ast.EmptyStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.EmptyStmt)
		return
	}
	var x ast.EmptyStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Semicolon = token.Pos(d.DecodeInt())
		case 1:
			x.Implicit = d.DecodeBool()
		default:
			d.UnknownField("ast.EmptyStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.EmptyStmt{},
		func(e *codec.Encoder, x any) { encode_ast_EmptyStmt(e, x.(*ast.EmptyStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.EmptyStmt
			decode_ast_EmptyStmt(d, &x)
			return x
		})
}

// Fields of ast_ExprStmt: X

func encode_ast_ExprStmt(e *codec.Encoder, x *ast.ExprStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.X != nil {
		e.EncodeUint(0)
		e.EncodeAny(x.X)
	}
	e.EndStruct()
}

func decode_ast_ExprStmt(d *codec.Decoder, p **ast.ExprStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.ExprStmt)
		return
	}
	var x ast.ExprStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.X = d.DecodeAny().(ast.Expr)
		default:
			d.UnknownField("ast.ExprStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.ExprStmt{},
		func(e *codec.Encoder, x any) { encode_ast_ExprStmt(e, x.(*ast.ExprStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.ExprStmt
			decode_ast_ExprStmt(d, &x)
			return x
		})
}

// Fields of ast_FieldList: Opening List Closing

func encode_ast_FieldList(e *codec.Encoder, x *ast.FieldList) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Opening != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Opening))
	}
	if x.List != nil {
		e.EncodeUint(1)
		encode_slice_ast_Field(e, x.List)
	}
	if x.Closing != 0 {
		e.EncodeUint(2)
		e.EncodeInt(int64(x.Closing))
	}
	e.EndStruct()
}

func decode_ast_FieldList(d *codec.Decoder, p **ast.FieldList) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.FieldList)
		return
	}
	var x ast.FieldList
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Opening = token.Pos(d.DecodeInt())
		case 1:
			decode_slice_ast_Field(d, &x.List)
		case 2:
			x.Closing = token.Pos(d.DecodeInt())
		default:
			d.UnknownField("ast.FieldList", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.FieldList{},
		func(e *codec.Encoder, x any) { encode_ast_FieldList(e, x.(*ast.FieldList)) },
		func(d *codec.Decoder) any {
			var x *ast.FieldList
			decode_ast_FieldList(d, &x)
			return x
		})
}

// Fields of ast_Field: Doc Names Type Tag Comment

func encode_ast_Field(e *codec.Encoder, x *ast.Field) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Doc != nil {
		e.EncodeUint(0)
		encode_ast_CommentGroup(e, x.Doc)
	}
	if x.Names != nil {
		e.EncodeUint(1)
		encode_slice_ast_Ident(e, x.Names)
	}
	if x.Type != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Type)
	}
	if x.Tag != nil {
		e.EncodeUint(3)
		encode_ast_BasicLit(e, x.Tag)
	}
	if x.Comment != nil {
		e.EncodeUint(4)
		encode_ast_CommentGroup(e, x.Comment)
	}
	e.EndStruct()
}

func decode_ast_Field(d *codec.Decoder, p **ast.Field) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.Field)
		return
	}
	var x ast.Field
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			decode_ast_CommentGroup(d, &x.Doc)
		case 1:
			decode_slice_ast_Ident(d, &x.Names)
		case 2:
			x.Type = d.DecodeAny().(ast.Expr)
		case 3:
			decode_ast_BasicLit(d, &x.Tag)
		case 4:
			decode_ast_CommentGroup(d, &x.Comment)
		default:
			d.UnknownField("ast.Field", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.Field{},
		func(e *codec.Encoder, x any) { encode_ast_Field(e, x.(*ast.Field)) },
		func(d *codec.Decoder) any {
			var x *ast.Field
			decode_ast_Field(d, &x)
			return x
		})
}

// Fields of ast_ForStmt: For Init Cond Post Body

func encode_ast_ForStmt(e *codec.Encoder, x *ast.ForStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.For != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.For))
	}
	if x.Init != nil {
		e.EncodeUint(1)
		e.EncodeAny(x.Init)
	}
	if x.Cond != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Cond)
	}
	if x.Post != nil {
		e.EncodeUint(3)
		e.EncodeAny(x.Post)
	}
	if x.Body != nil {
		e.EncodeUint(4)
		encode_ast_BlockStmt(e, x.Body)
	}
	e.EndStruct()
}

func decode_ast_ForStmt(d *codec.Decoder, p **ast.ForStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.ForStmt)
		return
	}
	var x ast.ForStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.For = token.Pos(d.DecodeInt())
		case 1:
			x.Init = d.DecodeAny().(ast.Stmt)
		case 2:
			x.Cond = d.DecodeAny().(ast.Expr)
		case 3:
			x.Post = d.DecodeAny().(ast.Stmt)
		case 4:
			decode_ast_BlockStmt(d, &x.Body)
		default:
			d.UnknownField("ast.ForStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.ForStmt{},
		func(e *codec.Encoder, x any) { encode_ast_ForStmt(e, x.(*ast.ForStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.ForStmt
			decode_ast_ForStmt(d, &x)
			return x
		})
}

// Fields of ast_FuncDecl: Doc Recv Name Type Body

func encode_ast_FuncDecl(e *codec.Encoder, x *ast.FuncDecl) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Doc != nil {
		e.EncodeUint(0)
		encode_ast_CommentGroup(e, x.Doc)
	}
	if x.Recv != nil {
		e.EncodeUint(1)
		encode_ast_FieldList(e, x.Recv)
	}
	if x.Name != nil {
		e.EncodeUint(2)
		encode_ast_Ident(e, x.Name)
	}
	if x.Type != nil {
		e.EncodeUint(3)
		encode_ast_FuncType(e, x.Type)
	}
	if x.Body != nil {
		e.EncodeUint(4)
		encode_ast_BlockStmt(e, x.Body)
	}
	e.EndStruct()
}

func decode_ast_FuncDecl(d *codec.Decoder, p **ast.FuncDecl) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.FuncDecl)
		return
	}
	var x ast.FuncDecl
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			decode_ast_CommentGroup(d, &x.Doc)
		case 1:
			decode_ast_FieldList(d, &x.Recv)
		case 2:
			decode_ast_Ident(d, &x.Name)
		case 3:
			decode_ast_FuncType(d, &x.Type)
		case 4:
			decode_ast_BlockStmt(d, &x.Body)
		default:
			d.UnknownField("ast.FuncDecl", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.FuncDecl{},
		func(e *codec.Encoder, x any) { encode_ast_FuncDecl(e, x.(*ast.FuncDecl)) },
		func(d *codec.Decoder) any {
			var x *ast.FuncDecl
			decode_ast_FuncDecl(d, &x)
			return x
		})
}

// Fields of ast_FuncLit: Type Body

func encode_ast_FuncLit(e *codec.Encoder, x *ast.FuncLit) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Type != nil {
		e.EncodeUint(0)
		encode_ast_FuncType(e, x.Type)
	}
	if x.Body != nil {
		e.EncodeUint(1)
		encode_ast_BlockStmt(e, x.Body)
	}
	e.EndStruct()
}

func decode_ast_FuncLit(d *codec.Decoder, p **ast.FuncLit) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.FuncLit)
		return
	}
	var x ast.FuncLit
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			decode_ast_FuncType(d, &x.Type)
		case 1:
			decode_ast_BlockStmt(d, &x.Body)
		default:
			d.UnknownField("ast.FuncLit", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.FuncLit{},
		func(e *codec.Encoder, x any) { encode_ast_FuncLit(e, x.(*ast.FuncLit)) },
		func(d *codec.Decoder) any {
			var x *ast.FuncLit
			decode_ast_FuncLit(d, &x)
			return x
		})
}

// Fields of ast_FuncType: Func Params Results TypeParams

func encode_ast_FuncType(e *codec.Encoder, x *ast.FuncType) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Func != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Func))
	}
	if x.Params != nil {
		e.EncodeUint(1)
		encode_ast_FieldList(e, x.Params)
	}
	if x.Results != nil {
		e.EncodeUint(2)
		encode_ast_FieldList(e, x.Results)
	}
	if x.TypeParams != nil {
		e.EncodeUint(3)
		encode_ast_FieldList(e, x.TypeParams)
	}
	e.EndStruct()
}

func decode_ast_FuncType(d *codec.Decoder, p **ast.FuncType) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.FuncType)
		return
	}
	var x ast.FuncType
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Func = token.Pos(d.DecodeInt())
		case 1:
			decode_ast_FieldList(d, &x.Params)
		case 2:
			decode_ast_FieldList(d, &x.Results)
		case 3:
			decode_ast_FieldList(d, &x.TypeParams)
		default:
			d.UnknownField("ast.FuncType", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.FuncType{},
		func(e *codec.Encoder, x any) { encode_ast_FuncType(e, x.(*ast.FuncType)) },
		func(d *codec.Decoder) any {
			var x *ast.FuncType
			decode_ast_FuncType(d, &x)
			return x
		})
}

// Fields of ast_GenDecl: Doc TokPos Tok Lparen Specs Rparen

func encode_ast_GenDecl(e *codec.Encoder, x *ast.GenDecl) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Doc != nil {
		e.EncodeUint(0)
		encode_ast_CommentGroup(e, x.Doc)
	}
	if x.TokPos != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.TokPos))
	}
	if x.Tok != 0 {
		e.EncodeUint(2)
		e.EncodeInt(int64(x.Tok))
	}
	if x.Lparen != 0 {
		e.EncodeUint(3)
		e.EncodeInt(int64(x.Lparen))
	}
	if x.Specs != nil {
		e.EncodeUint(4)
		encode_slice_ast_Spec(e, x.Specs)
	}
	if x.Rparen != 0 {
		e.EncodeUint(5)
		e.EncodeInt(int64(x.Rparen))
	}
	e.EndStruct()
}

func decode_ast_GenDecl(d *codec.Decoder, p **ast.GenDecl) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.GenDecl)
		return
	}
	var x ast.GenDecl
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			decode_ast_CommentGroup(d, &x.Doc)
		case 1:
			x.TokPos = token.Pos(d.DecodeInt())
		case 2:
			x.Tok = token.Token(d.DecodeInt())
		case 3:
			x.Lparen = token.Pos(d.DecodeInt())
		case 4:
			decode_slice_ast_Spec(d, &x.Specs)
		case 5:
			x.Rparen = token.Pos(d.DecodeInt())
		default:
			d.UnknownField("ast.GenDecl", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.GenDecl{},
		func(e *codec.Encoder, x any) { encode_ast_GenDecl(e, x.(*ast.GenDecl)) },
		func(d *codec.Decoder) any {
			var x *ast.GenDecl
			decode_ast_GenDecl(d, &x)
			return x
		})
}

// Fields of ast_GoStmt: Go Call

func encode_ast_GoStmt(e *codec.Encoder, x *ast.GoStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Go != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Go))
	}
	if x.Call != nil {
		e.EncodeUint(1)
		encode_ast_CallExpr(e, x.Call)
	}
	e.EndStruct()
}

func decode_ast_GoStmt(d *codec.Decoder, p **ast.GoStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.GoStmt)
		return
	}
	var x ast.GoStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Go = token.Pos(d.DecodeInt())
		case 1:
			decode_ast_CallExpr(d, &x.Call)
		default:
			d.UnknownField("ast.GoStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.GoStmt{},
		func(e *codec.Encoder, x any) { encode_ast_GoStmt(e, x.(*ast.GoStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.GoStmt
			decode_ast_GoStmt(d, &x)
			return x
		})
}

// Fields of ast_Ident: NamePos Name Obj

func encode_ast_Ident(e *codec.Encoder, x *ast.Ident) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.NamePos != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.NamePos))
	}
	if x.Name != "" {
		e.EncodeUint(1)
		e.EncodeString(x.Name)
	}
	if x.Obj != nil {
		e.EncodeUint(2)
		encode_ast_Object(e, x.Obj)
	}
	e.EndStruct()
}

func decode_ast_Ident(d *codec.Decoder, p **ast.Ident) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.Ident)
		return
	}
	var x ast.Ident
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.NamePos = token.Pos(d.DecodeInt())
		case 1:
			x.Name = d.DecodeString()
		case 2:
			decode_ast_Object(d, &x.Obj)
		default:
			d.UnknownField("ast.Ident", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.Ident{},
		func(e *codec.Encoder, x any) { encode_ast_Ident(e, x.(*ast.Ident)) },
		func(d *codec.Decoder) any {
			var x *ast.Ident
			decode_ast_Ident(d, &x)
			return x
		})
}

// Fields of ast_IfStmt: If Init Cond Body Else

func encode_ast_IfStmt(e *codec.Encoder, x *ast.IfStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.If != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.If))
	}
	if x.Init != nil {
		e.EncodeUint(1)
		e.EncodeAny(x.Init)
	}
	if x.Cond != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Cond)
	}
	if x.Body != nil {
		e.EncodeUint(3)
		encode_ast_BlockStmt(e, x.Body)
	}
	if x.Else != nil {
		e.EncodeUint(4)
		e.EncodeAny(x.Else)
	}
	e.EndStruct()
}

func decode_ast_IfStmt(d *codec.Decoder, p **ast.IfStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.IfStmt)
		return
	}
	var x ast.IfStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.If = token.Pos(d.DecodeInt())
		case 1:
			x.Init = d.DecodeAny().(ast.Stmt)
		case 2:
			x.Cond = d.DecodeAny().(ast.Expr)
		case 3:
			decode_ast_BlockStmt(d, &x.Body)
		case 4:
			x.Else = d.DecodeAny().(ast.Stmt)
		default:
			d.UnknownField("ast.IfStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.IfStmt{},
		func(e *codec.Encoder, x any) { encode_ast_IfStmt(e, x.(*ast.IfStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.IfStmt
			decode_ast_IfStmt(d, &x)
			return x
		})
}

// Fields of ast_ImportSpec: Doc Name Path Comment EndPos

func encode_ast_ImportSpec(e *codec.Encoder, x *ast.ImportSpec) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Doc != nil {
		e.EncodeUint(0)
		encode_ast_CommentGroup(e, x.Doc)
	}
	if x.Name != nil {
		e.EncodeUint(1)
		encode_ast_Ident(e, x.Name)
	}
	if x.Path != nil {
		e.EncodeUint(2)
		encode_ast_BasicLit(e, x.Path)
	}
	if x.Comment != nil {
		e.EncodeUint(3)
		encode_ast_CommentGroup(e, x.Comment)
	}
	if x.EndPos != 0 {
		e.EncodeUint(4)
		e.EncodeInt(int64(x.EndPos))
	}
	e.EndStruct()
}

func decode_ast_ImportSpec(d *codec.Decoder, p **ast.ImportSpec) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.ImportSpec)
		return
	}
	var x ast.ImportSpec
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			decode_ast_CommentGroup(d, &x.Doc)
		case 1:
			decode_ast_Ident(d, &x.Name)
		case 2:
			decode_ast_BasicLit(d, &x.Path)
		case 3:
			decode_ast_CommentGroup(d, &x.Comment)
		case 4:
			x.EndPos = token.Pos(d.DecodeInt())
		default:
			d.UnknownField("ast.ImportSpec", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.ImportSpec{},
		func(e *codec.Encoder, x any) { encode_ast_ImportSpec(e, x.(*ast.ImportSpec)) },
		func(d *codec.Decoder) any {
			var x *ast.ImportSpec
			decode_ast_ImportSpec(d, &x)
			return x
		})
}

// Fields of ast_IncDecStmt: X TokPos Tok

func encode_ast_IncDecStmt(e *codec.Encoder, x *ast.IncDecStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.X != nil {
		e.EncodeUint(0)
		e.EncodeAny(x.X)
	}
	if x.TokPos != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.TokPos))
	}
	if x.Tok != 0 {
		e.EncodeUint(2)
		e.EncodeInt(int64(x.Tok))
	}
	e.EndStruct()
}

func decode_ast_IncDecStmt(d *codec.Decoder, p **ast.IncDecStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.IncDecStmt)
		return
	}
	var x ast.IncDecStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.X = d.DecodeAny().(ast.Expr)
		case 1:
			x.TokPos = token.Pos(d.DecodeInt())
		case 2:
			x.Tok = token.Token(d.DecodeInt())
		default:
			d.UnknownField("ast.IncDecStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.IncDecStmt{},
		func(e *codec.Encoder, x any) { encode_ast_IncDecStmt(e, x.(*ast.IncDecStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.IncDecStmt
			decode_ast_IncDecStmt(d, &x)
			return x
		})
}

// Fields of ast_IndexExpr: X Lbrack Index Rbrack

func encode_ast_IndexExpr(e *codec.Encoder, x *ast.IndexExpr) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.X != nil {
		e.EncodeUint(0)
		e.EncodeAny(x.X)
	}
	if x.Lbrack != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Lbrack))
	}
	if x.Index != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Index)
	}
	if x.Rbrack != 0 {
		e.EncodeUint(3)
		e.EncodeInt(int64(x.Rbrack))
	}
	e.EndStruct()
}

func decode_ast_IndexExpr(d *codec.Decoder, p **ast.IndexExpr) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.IndexExpr)
		return
	}
	var x ast.IndexExpr
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.X = d.DecodeAny().(ast.Expr)
		case 1:
			x.Lbrack = token.Pos(d.DecodeInt())
		case 2:
			x.Index = d.DecodeAny().(ast.Expr)
		case 3:
			x.Rbrack = token.Pos(d.DecodeInt())
		default:
			d.UnknownField("ast.IndexExpr", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.IndexExpr{},
		func(e *codec.Encoder, x any) { encode_ast_IndexExpr(e, x.(*ast.IndexExpr)) },
		func(d *codec.Decoder) any {
			var x *ast.IndexExpr
			decode_ast_IndexExpr(d, &x)
			return x
		})
}

// Fields of ast_IndexListExpr: X Lbrack Indices Rbrack

func encode_ast_IndexListExpr(e *codec.Encoder, x *ast.IndexListExpr) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.X != nil {
		e.EncodeUint(0)
		e.EncodeAny(x.X)
	}
	if x.Lbrack != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Lbrack))
	}
	if x.Indices != nil {
		e.EncodeUint(2)
		encode_slice_ast_Expr(e, x.Indices)
	}
	if x.Rbrack != 0 {
		e.EncodeUint(3)
		e.EncodeInt(int64(x.Rbrack))
	}
	e.EndStruct()
}

func decode_ast_IndexListExpr(d *codec.Decoder, p **ast.IndexListExpr) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.IndexListExpr)
		return
	}
	var x ast.IndexListExpr
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.X = d.DecodeAny().(ast.Expr)
		case 1:
			x.Lbrack = token.Pos(d.DecodeInt())
		case 2:
			decode_slice_ast_Expr(d, &x.Indices)
		case 3:
			x.Rbrack = token.Pos(d.DecodeInt())
		default:
			d.UnknownField("ast.IndexListExpr", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.IndexListExpr{},
		func(e *codec.Encoder, x any) { encode_ast_IndexListExpr(e, x.(*ast.IndexListExpr)) },
		func(d *codec.Decoder) any {
			var x *ast.IndexListExpr
			decode_ast_IndexListExpr(d, &x)
			return x
		})
}

// Fields of ast_InterfaceType: Interface Methods Incomplete

func encode_ast_InterfaceType(e *codec.Encoder, x *ast.InterfaceType) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Interface != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Interface))
	}
	if x.Methods != nil {
		e.EncodeUint(1)
		encode_ast_FieldList(e, x.Methods)
	}
	if x.Incomplete != false {
		e.EncodeUint(2)
		e.EncodeBool(x.Incomplete)
	}
	e.EndStruct()
}

func decode_ast_InterfaceType(d *codec.Decoder, p **ast.InterfaceType) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.InterfaceType)
		return
	}
	var x ast.InterfaceType
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Interface = token.Pos(d.DecodeInt())
		case 1:
			decode_ast_FieldList(d, &x.Methods)
		case 2:
			x.Incomplete = d.DecodeBool()
		default:
			d.UnknownField("ast.InterfaceType", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.InterfaceType{},
		func(e *codec.Encoder, x any) { encode_ast_InterfaceType(e, x.(*ast.InterfaceType)) },
		func(d *codec.Decoder) any {
			var x *ast.InterfaceType
			decode_ast_InterfaceType(d, &x)
			return x
		})
}

// Fields of ast_KeyValueExpr: Key Colon Value

func encode_ast_KeyValueExpr(e *codec.Encoder, x *ast.KeyValueExpr) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Key != nil {
		e.EncodeUint(0)
		e.EncodeAny(x.Key)
	}
	if x.Colon != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Colon))
	}
	if x.Value != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Value)
	}
	e.EndStruct()
}

func decode_ast_KeyValueExpr(d *codec.Decoder, p **ast.KeyValueExpr) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.KeyValueExpr)
		return
	}
	var x ast.KeyValueExpr
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Key = d.DecodeAny().(ast.Expr)
		case 1:
			x.Colon = token.Pos(d.DecodeInt())
		case 2:
			x.Value = d.DecodeAny().(ast.Expr)
		default:
			d.UnknownField("ast.KeyValueExpr", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.KeyValueExpr{},
		func(e *codec.Encoder, x any) { encode_ast_KeyValueExpr(e, x.(*ast.KeyValueExpr)) },
		func(d *codec.Decoder) any {
			var x *ast.KeyValueExpr
			decode_ast_KeyValueExpr(d, &x)
			return x
		})
}

// Fields of ast_LabeledStmt: Label Colon Stmt

func encode_ast_LabeledStmt(e *codec.Encoder, x *ast.LabeledStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Label != nil {
		e.EncodeUint(0)
		encode_ast_Ident(e, x.Label)
	}
	if x.Colon != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Colon))
	}
	if x.Stmt != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Stmt)
	}
	e.EndStruct()
}

func decode_ast_LabeledStmt(d *codec.Decoder, p **ast.LabeledStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.LabeledStmt)
		return
	}
	var x ast.LabeledStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			decode_ast_Ident(d, &x.Label)
		case 1:
			x.Colon = token.Pos(d.DecodeInt())
		case 2:
			x.Stmt = d.DecodeAny().(ast.Stmt)
		default:
			d.UnknownField("ast.LabeledStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.LabeledStmt{},
		func(e *codec.Encoder, x any) { encode_ast_LabeledStmt(e, x.(*ast.LabeledStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.LabeledStmt
			decode_ast_LabeledStmt(d, &x)
			return x
		})
}

// Fields of ast_MapType: Map Key Value

func encode_ast_MapType(e *codec.Encoder, x *ast.MapType) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Map != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Map))
	}
	if x.Key != nil {
		e.EncodeUint(1)
		e.EncodeAny(x.Key)
	}
	if x.Value != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Value)
	}
	e.EndStruct()
}

func decode_ast_MapType(d *codec.Decoder, p **ast.MapType) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.MapType)
		return
	}
	var x ast.MapType
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Map = token.Pos(d.DecodeInt())
		case 1:
			x.Key = d.DecodeAny().(ast.Expr)
		case 2:
			x.Value = d.DecodeAny().(ast.Expr)
		default:
			d.UnknownField("ast.MapType", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.MapType{},
		func(e *codec.Encoder, x any) { encode_ast_MapType(e, x.(*ast.MapType)) },
		func(d *codec.Decoder) any {
			var x *ast.MapType
			decode_ast_MapType(d, &x)
			return x
		})
}

// Fields of ast_ParenExpr: Lparen X Rparen

func encode_ast_ParenExpr(e *codec.Encoder, x *ast.ParenExpr) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Lparen != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Lparen))
	}
	if x.X != nil {
		e.EncodeUint(1)
		e.EncodeAny(x.X)
	}
	if x.Rparen != 0 {
		e.EncodeUint(2)
		e.EncodeInt(int64(x.Rparen))
	}
	e.EndStruct()
}

func decode_ast_ParenExpr(d *codec.Decoder, p **ast.ParenExpr) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.ParenExpr)
		return
	}
	var x ast.ParenExpr
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Lparen = token.Pos(d.DecodeInt())
		case 1:
			x.X = d.DecodeAny().(ast.Expr)
		case 2:
			x.Rparen = token.Pos(d.DecodeInt())
		default:
			d.UnknownField("ast.ParenExpr", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.ParenExpr{},
		func(e *codec.Encoder, x any) { encode_ast_ParenExpr(e, x.(*ast.ParenExpr)) },
		func(d *codec.Decoder) any {
			var x *ast.ParenExpr
			decode_ast_ParenExpr(d, &x)
			return x
		})
}

// Fields of ast_RangeStmt: For Key Value TokPos Tok X Body

func encode_ast_RangeStmt(e *codec.Encoder, x *ast.RangeStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.For != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.For))
	}
	if x.Key != nil {
		e.EncodeUint(1)
		e.EncodeAny(x.Key)
	}
	if x.Value != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Value)
	}
	if x.TokPos != 0 {
		e.EncodeUint(3)
		e.EncodeInt(int64(x.TokPos))
	}
	if x.Tok != 0 {
		e.EncodeUint(4)
		e.EncodeInt(int64(x.Tok))
	}
	if x.X != nil {
		e.EncodeUint(5)
		e.EncodeAny(x.X)
	}
	if x.Body != nil {
		e.EncodeUint(6)
		encode_ast_BlockStmt(e, x.Body)
	}
	e.EndStruct()
}

func decode_ast_RangeStmt(d *codec.Decoder, p **ast.RangeStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.RangeStmt)
		return
	}
	var x ast.RangeStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.For = token.Pos(d.DecodeInt())
		case 1:
			x.Key = d.DecodeAny().(ast.Expr)
		case 2:
			x.Value = d.DecodeAny().(ast.Expr)
		case 3:
			x.TokPos = token.Pos(d.DecodeInt())
		case 4:
			x.Tok = token.Token(d.DecodeInt())
		case 5:
			x.X = d.DecodeAny().(ast.Expr)
		case 6:
			decode_ast_BlockStmt(d, &x.Body)
		default:
			d.UnknownField("ast.RangeStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.RangeStmt{},
		func(e *codec.Encoder, x any) { encode_ast_RangeStmt(e, x.(*ast.RangeStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.RangeStmt
			decode_ast_RangeStmt(d, &x)
			return x
		})
}

// Fields of ast_ReturnStmt: Return Results

func encode_ast_ReturnStmt(e *codec.Encoder, x *ast.ReturnStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Return != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Return))
	}
	if x.Results != nil {
		e.EncodeUint(1)
		encode_slice_ast_Expr(e, x.Results)
	}
	e.EndStruct()
}

func decode_ast_ReturnStmt(d *codec.Decoder, p **ast.ReturnStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.ReturnStmt)
		return
	}
	var x ast.ReturnStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Return = token.Pos(d.DecodeInt())
		case 1:
			decode_slice_ast_Expr(d, &x.Results)
		default:
			d.UnknownField("ast.ReturnStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.ReturnStmt{},
		func(e *codec.Encoder, x any) { encode_ast_ReturnStmt(e, x.(*ast.ReturnStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.ReturnStmt
			decode_ast_ReturnStmt(d, &x)
			return x
		})
}

// Fields of ast_Scope: Outer Objects

func encode_ast_Scope(e *codec.Encoder, x *ast.Scope) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Outer != nil {
		e.EncodeUint(0)
		encode_ast_Scope(e, x.Outer)
	}
	if x.Objects != nil {
		e.EncodeUint(1)
		encode_map_string_ast_Object(e, x.Objects)
	}
	e.EndStruct()
}

func decode_ast_Scope(d *codec.Decoder, p **ast.Scope) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.Scope)
		return
	}
	var x ast.Scope
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			decode_ast_Scope(d, &x.Outer)
		case 1:
			decode_map_string_ast_Object(d, &x.Objects)
		default:
			d.UnknownField("ast.Scope", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.Scope{},
		func(e *codec.Encoder, x any) { encode_ast_Scope(e, x.(*ast.Scope)) },
		func(d *codec.Decoder) any {
			var x *ast.Scope
			decode_ast_Scope(d, &x)
			return x
		})
}

// Fields of ast_SelectStmt: Select Body

func encode_ast_SelectStmt(e *codec.Encoder, x *ast.SelectStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Select != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Select))
	}
	if x.Body != nil {
		e.EncodeUint(1)
		encode_ast_BlockStmt(e, x.Body)
	}
	e.EndStruct()
}

func decode_ast_SelectStmt(d *codec.Decoder, p **ast.SelectStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.SelectStmt)
		return
	}
	var x ast.SelectStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Select = token.Pos(d.DecodeInt())
		case 1:
			decode_ast_BlockStmt(d, &x.Body)
		default:
			d.UnknownField("ast.SelectStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.SelectStmt{},
		func(e *codec.Encoder, x any) { encode_ast_SelectStmt(e, x.(*ast.SelectStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.SelectStmt
			decode_ast_SelectStmt(d, &x)
			return x
		})
}

// Fields of ast_SelectorExpr: X Sel

func encode_ast_SelectorExpr(e *codec.Encoder, x *ast.SelectorExpr) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.X != nil {
		e.EncodeUint(0)
		e.EncodeAny(x.X)
	}
	if x.Sel != nil {
		e.EncodeUint(1)
		encode_ast_Ident(e, x.Sel)
	}
	e.EndStruct()
}

func decode_ast_SelectorExpr(d *codec.Decoder, p **ast.SelectorExpr) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.SelectorExpr)
		return
	}
	var x ast.SelectorExpr
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.X = d.DecodeAny().(ast.Expr)
		case 1:
			decode_ast_Ident(d, &x.Sel)
		default:
			d.UnknownField("ast.SelectorExpr", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.SelectorExpr{},
		func(e *codec.Encoder, x any) { encode_ast_SelectorExpr(e, x.(*ast.SelectorExpr)) },
		func(d *codec.Decoder) any {
			var x *ast.SelectorExpr
			decode_ast_SelectorExpr(d, &x)
			return x
		})
}

// Fields of ast_SendStmt: Chan Arrow Value

func encode_ast_SendStmt(e *codec.Encoder, x *ast.SendStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Chan != nil {
		e.EncodeUint(0)
		e.EncodeAny(x.Chan)
	}
	if x.Arrow != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Arrow))
	}
	if x.Value != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Value)
	}
	e.EndStruct()
}

func decode_ast_SendStmt(d *codec.Decoder, p **ast.SendStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.SendStmt)
		return
	}
	var x ast.SendStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Chan = d.DecodeAny().(ast.Expr)
		case 1:
			x.Arrow = token.Pos(d.DecodeInt())
		case 2:
			x.Value = d.DecodeAny().(ast.Expr)
		default:
			d.UnknownField("ast.SendStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.SendStmt{},
		func(e *codec.Encoder, x any) { encode_ast_SendStmt(e, x.(*ast.SendStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.SendStmt
			decode_ast_SendStmt(d, &x)
			return x
		})
}

// Fields of ast_SliceExpr: X Lbrack Low High Max Slice3 Rbrack

func encode_ast_SliceExpr(e *codec.Encoder, x *ast.SliceExpr) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.X != nil {
		e.EncodeUint(0)
		e.EncodeAny(x.X)
	}
	if x.Lbrack != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Lbrack))
	}
	if x.Low != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Low)
	}
	if x.High != nil {
		e.EncodeUint(3)
		e.EncodeAny(x.High)
	}
	if x.Max != nil {
		e.EncodeUint(4)
		e.EncodeAny(x.Max)
	}
	if x.Slice3 != false {
		e.EncodeUint(5)
		e.EncodeBool(x.Slice3)
	}
	if x.Rbrack != 0 {
		e.EncodeUint(6)
		e.EncodeInt(int64(x.Rbrack))
	}
	e.EndStruct()
}

func decode_ast_SliceExpr(d *codec.Decoder, p **ast.SliceExpr) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.SliceExpr)
		return
	}
	var x ast.SliceExpr
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.X = d.DecodeAny().(ast.Expr)
		case 1:
			x.Lbrack = token.Pos(d.DecodeInt())
		case 2:
			x.Low = d.DecodeAny().(ast.Expr)
		case 3:
			x.High = d.DecodeAny().(ast.Expr)
		case 4:
			x.Max = d.DecodeAny().(ast.Expr)
		case 5:
			x.Slice3 = d.DecodeBool()
		case 6:
			x.Rbrack = token.Pos(d.DecodeInt())
		default:
			d.UnknownField("ast.SliceExpr", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.SliceExpr{},
		func(e *codec.Encoder, x any) { encode_ast_SliceExpr(e, x.(*ast.SliceExpr)) },
		func(d *codec.Decoder) any {
			var x *ast.SliceExpr
			decode_ast_SliceExpr(d, &x)
			return x
		})
}

// Fields of ast_StarExpr: Star X

func encode_ast_StarExpr(e *codec.Encoder, x *ast.StarExpr) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Star != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Star))
	}
	if x.X != nil {
		e.EncodeUint(1)
		e.EncodeAny(x.X)
	}
	e.EndStruct()
}

func decode_ast_StarExpr(d *codec.Decoder, p **ast.StarExpr) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.StarExpr)
		return
	}
	var x ast.StarExpr
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Star = token.Pos(d.DecodeInt())
		case 1:
			x.X = d.DecodeAny().(ast.Expr)
		default:
			d.UnknownField("ast.StarExpr", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.StarExpr{},
		func(e *codec.Encoder, x any) { encode_ast_StarExpr(e, x.(*ast.StarExpr)) },
		func(d *codec.Decoder) any {
			var x *ast.StarExpr
			decode_ast_StarExpr(d, &x)
			return x
		})
}

// Fields of ast_StructType: Struct Fields Incomplete

func encode_ast_StructType(e *codec.Encoder, x *ast.StructType) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Struct != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Struct))
	}
	if x.Fields != nil {
		e.EncodeUint(1)
		encode_ast_FieldList(e, x.Fields)
	}
	if x.Incomplete != false {
		e.EncodeUint(2)
		e.EncodeBool(x.Incomplete)
	}
	e.EndStruct()
}

func decode_ast_StructType(d *codec.Decoder, p **ast.StructType) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.StructType)
		return
	}
	var x ast.StructType
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Struct = token.Pos(d.DecodeInt())
		case 1:
			decode_ast_FieldList(d, &x.Fields)
		case 2:
			x.Incomplete = d.DecodeBool()
		default:
			d.UnknownField("ast.StructType", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.StructType{},
		func(e *codec.Encoder, x any) { encode_ast_StructType(e, x.(*ast.StructType)) },
		func(d *codec.Decoder) any {
			var x *ast.StructType
			decode_ast_StructType(d, &x)
			return x
		})
}

// Fields of ast_SwitchStmt: Switch Init Tag Body

func encode_ast_SwitchStmt(e *codec.Encoder, x *ast.SwitchStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Switch != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Switch))
	}
	if x.Init != nil {
		e.EncodeUint(1)
		e.EncodeAny(x.Init)
	}
	if x.Tag != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Tag)
	}
	if x.Body != nil {
		e.EncodeUint(3)
		encode_ast_BlockStmt(e, x.Body)
	}
	e.EndStruct()
}

func decode_ast_SwitchStmt(d *codec.Decoder, p **ast.SwitchStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.SwitchStmt)
		return
	}
	var x ast.SwitchStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Switch = token.Pos(d.DecodeInt())
		case 1:
			x.Init = d.DecodeAny().(ast.Stmt)
		case 2:
			x.Tag = d.DecodeAny().(ast.Expr)
		case 3:
			decode_ast_BlockStmt(d, &x.Body)
		default:
			d.UnknownField("ast.SwitchStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.SwitchStmt{},
		func(e *codec.Encoder, x any) { encode_ast_SwitchStmt(e, x.(*ast.SwitchStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.SwitchStmt
			decode_ast_SwitchStmt(d, &x)
			return x
		})
}

// Fields of ast_TypeAssertExpr: X Lparen Type Rparen

func encode_ast_TypeAssertExpr(e *codec.Encoder, x *ast.TypeAssertExpr) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.X != nil {
		e.EncodeUint(0)
		e.EncodeAny(x.X)
	}
	if x.Lparen != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Lparen))
	}
	if x.Type != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Type)
	}
	if x.Rparen != 0 {
		e.EncodeUint(3)
		e.EncodeInt(int64(x.Rparen))
	}
	e.EndStruct()
}

func decode_ast_TypeAssertExpr(d *codec.Decoder, p **ast.TypeAssertExpr) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.TypeAssertExpr)
		return
	}
	var x ast.TypeAssertExpr
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.X = d.DecodeAny().(ast.Expr)
		case 1:
			x.Lparen = token.Pos(d.DecodeInt())
		case 2:
			x.Type = d.DecodeAny().(ast.Expr)
		case 3:
			x.Rparen = token.Pos(d.DecodeInt())
		default:
			d.UnknownField("ast.TypeAssertExpr", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.TypeAssertExpr{},
		func(e *codec.Encoder, x any) { encode_ast_TypeAssertExpr(e, x.(*ast.TypeAssertExpr)) },
		func(d *codec.Decoder) any {
			var x *ast.TypeAssertExpr
			decode_ast_TypeAssertExpr(d, &x)
			return x
		})
}

// Fields of ast_TypeSpec: Doc Name Assign Type Comment TypeParams

func encode_ast_TypeSpec(e *codec.Encoder, x *ast.TypeSpec) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Doc != nil {
		e.EncodeUint(0)
		encode_ast_CommentGroup(e, x.Doc)
	}
	if x.Name != nil {
		e.EncodeUint(1)
		encode_ast_Ident(e, x.Name)
	}
	if x.Assign != 0 {
		e.EncodeUint(2)
		e.EncodeInt(int64(x.Assign))
	}
	if x.Type != nil {
		e.EncodeUint(3)
		e.EncodeAny(x.Type)
	}
	if x.Comment != nil {
		e.EncodeUint(4)
		encode_ast_CommentGroup(e, x.Comment)
	}
	if x.TypeParams != nil {
		e.EncodeUint(5)
		encode_ast_FieldList(e, x.TypeParams)
	}
	e.EndStruct()
}

func decode_ast_TypeSpec(d *codec.Decoder, p **ast.TypeSpec) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.TypeSpec)
		return
	}
	var x ast.TypeSpec
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			decode_ast_CommentGroup(d, &x.Doc)
		case 1:
			decode_ast_Ident(d, &x.Name)
		case 2:
			x.Assign = token.Pos(d.DecodeInt())
		case 3:
			x.Type = d.DecodeAny().(ast.Expr)
		case 4:
			decode_ast_CommentGroup(d, &x.Comment)
		case 5:
			decode_ast_FieldList(d, &x.TypeParams)
		default:
			d.UnknownField("ast.TypeSpec", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.TypeSpec{},
		func(e *codec.Encoder, x any) { encode_ast_TypeSpec(e, x.(*ast.TypeSpec)) },
		func(d *codec.Decoder) any {
			var x *ast.TypeSpec
			decode_ast_TypeSpec(d, &x)
			return x
		})
}

// Fields of ast_TypeSwitchStmt: Switch Init Assign Body

func encode_ast_TypeSwitchStmt(e *codec.Encoder, x *ast.TypeSwitchStmt) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Switch != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Switch))
	}
	if x.Init != nil {
		e.EncodeUint(1)
		e.EncodeAny(x.Init)
	}
	if x.Assign != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Assign)
	}
	if x.Body != nil {
		e.EncodeUint(3)
		encode_ast_BlockStmt(e, x.Body)
	}
	e.EndStruct()
}

func decode_ast_TypeSwitchStmt(d *codec.Decoder, p **ast.TypeSwitchStmt) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.TypeSwitchStmt)
		return
	}
	var x ast.TypeSwitchStmt
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Switch = token.Pos(d.DecodeInt())
		case 1:
			x.Init = d.DecodeAny().(ast.Stmt)
		case 2:
			x.Assign = d.DecodeAny().(ast.Stmt)
		case 3:
			decode_ast_BlockStmt(d, &x.Body)
		default:
			d.UnknownField("ast.TypeSwitchStmt", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.TypeSwitchStmt{},
		func(e *codec.Encoder, x any) { encode_ast_TypeSwitchStmt(e, x.(*ast.TypeSwitchStmt)) },
		func(d *codec.Decoder) any {
			var x *ast.TypeSwitchStmt
			decode_ast_TypeSwitchStmt(d, &x)
			return x
		})
}

// Fields of ast_UnaryExpr: OpPos Op X

func encode_ast_UnaryExpr(e *codec.Encoder, x *ast.UnaryExpr) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.OpPos != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.OpPos))
	}
	if x.Op != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Op))
	}
	if x.X != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.X)
	}
	e.EndStruct()
}

func decode_ast_UnaryExpr(d *codec.Decoder, p **ast.UnaryExpr) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.UnaryExpr)
		return
	}
	var x ast.UnaryExpr
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.OpPos = token.Pos(d.DecodeInt())
		case 1:
			x.Op = token.Token(d.DecodeInt())
		case 2:
			x.X = d.DecodeAny().(ast.Expr)
		default:
			d.UnknownField("ast.UnaryExpr", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.UnaryExpr{},
		func(e *codec.Encoder, x any) { encode_ast_UnaryExpr(e, x.(*ast.UnaryExpr)) },
		func(d *codec.Decoder) any {
			var x *ast.UnaryExpr
			decode_ast_UnaryExpr(d, &x)
			return x
		})
}

// Fields of ast_ValueSpec: Doc Names Type Values Comment

func encode_ast_ValueSpec(e *codec.Encoder, x *ast.ValueSpec) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Doc != nil {
		e.EncodeUint(0)
		encode_ast_CommentGroup(e, x.Doc)
	}
	if x.Names != nil {
		e.EncodeUint(1)
		encode_slice_ast_Ident(e, x.Names)
	}
	if x.Type != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Type)
	}
	if x.Values != nil {
		e.EncodeUint(3)
		encode_slice_ast_Expr(e, x.Values)
	}
	if x.Comment != nil {
		e.EncodeUint(4)
		encode_ast_CommentGroup(e, x.Comment)
	}
	e.EndStruct()
}

func decode_ast_ValueSpec(d *codec.Decoder, p **ast.ValueSpec) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.ValueSpec)
		return
	}
	var x ast.ValueSpec
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			decode_ast_CommentGroup(d, &x.Doc)
		case 1:
			decode_slice_ast_Ident(d, &x.Names)
		case 2:
			x.Type = d.DecodeAny().(ast.Expr)
		case 3:
			decode_slice_ast_Expr(d, &x.Values)
		case 4:
			decode_ast_CommentGroup(d, &x.Comment)
		default:
			d.UnknownField("ast.ValueSpec", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.ValueSpec{},
		func(e *codec.Encoder, x any) { encode_ast_ValueSpec(e, x.(*ast.ValueSpec)) },
		func(d *codec.Decoder) any {
			var x *ast.ValueSpec
			decode_ast_ValueSpec(d, &x)
			return x
		})
}

// Fields of encPackage: GOOS GOARCH Files ModulePackagePaths

func encode_encPackage(e *codec.Encoder, x *encPackage) {
	if !e.StartStruct(x == nil, x) {
		return
	}

	if x.Files != nil {
		e.EncodeUint(2)
		encode_slice_File(e, x.Files)
	}
	if x.ModulePackagePaths != nil {
		e.EncodeUint(3)
		encode_map_string_bool(e, x.ModulePackagePaths)
	}
	e.EndStruct()
}

func decode_encPackage(d *codec.Decoder, p **encPackage) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*encPackage)
		return
	}
	var x encPackage
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 2:
			decode_slice_File(d, &x.Files)
		case 3:
			decode_map_string_bool(d, &x.ModulePackagePaths)
		default:
			d.UnknownField("encPackage", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&encPackage{},
		func(e *codec.Encoder, x any) { encode_encPackage(e, x.(*encPackage)) },
		func(d *codec.Decoder) any {
			var x *encPackage
			decode_encPackage(d, &x)
			return x
		})
}

func encode_slice_ast_Expr(e *codec.Encoder, s []ast.Expr) {
	if s == nil {
		e.EncodeNil()
		return
	}
	e.StartList(len(s))
	for _, x := range s {
		e.EncodeAny(x)
	}
}

func decode_slice_ast_Expr(d *codec.Decoder, p *[]ast.Expr) {
	n := d.StartList()
	if n < 0 {
		return
	}
	s := make([]ast.Expr, n)
	for i := 0; i < n; i++ {
		s[i] = d.DecodeAny().(ast.Expr)
	}
	*p = s
}

func init() {
	codec.Register([]ast.Expr(nil),
		func(e *codec.Encoder, x any) { encode_slice_ast_Expr(e, x.([]ast.Expr)) },
		func(d *codec.Decoder) any { var x []ast.Expr; decode_slice_ast_Expr(d, &x); return x })
}

func encode_slice_ast_Stmt(e *codec.Encoder, s []ast.Stmt) {
	if s == nil {
		e.EncodeNil()
		return
	}
	e.StartList(len(s))
	for _, x := range s {
		e.EncodeAny(x)
	}
}

func decode_slice_ast_Stmt(d *codec.Decoder, p *[]ast.Stmt) {
	n := d.StartList()
	if n < 0 {
		return
	}
	s := make([]ast.Stmt, n)
	for i := 0; i < n; i++ {
		s[i] = d.DecodeAny().(ast.Stmt)
	}
	*p = s
}

func init() {
	codec.Register([]ast.Stmt(nil),
		func(e *codec.Encoder, x any) { encode_slice_ast_Stmt(e, x.([]ast.Stmt)) },
		func(d *codec.Decoder) any { var x []ast.Stmt; decode_slice_ast_Stmt(d, &x); return x })
}

func encode_slice_ast_Comment(e *codec.Encoder, s []*ast.Comment) {
	if s == nil {
		e.EncodeNil()
		return
	}
	e.StartList(len(s))
	for _, x := range s {
		encode_ast_Comment(e, x)
	}
}

func decode_slice_ast_Comment(d *codec.Decoder, p *[]*ast.Comment) {
	n := d.StartList()
	if n < 0 {
		return
	}
	s := make([]*ast.Comment, n)
	for i := 0; i < n; i++ {
		decode_ast_Comment(d, &s[i])
	}
	*p = s
}

func init() {
	codec.Register([]*ast.Comment(nil),
		func(e *codec.Encoder, x any) { encode_slice_ast_Comment(e, x.([]*ast.Comment)) },
		func(d *codec.Decoder) any { var x []*ast.Comment; decode_slice_ast_Comment(d, &x); return x })
}

func encode_slice_ast_Field(e *codec.Encoder, s []*ast.Field) {
	if s == nil {
		e.EncodeNil()
		return
	}
	e.StartList(len(s))
	for _, x := range s {
		encode_ast_Field(e, x)
	}
}

func decode_slice_ast_Field(d *codec.Decoder, p *[]*ast.Field) {
	n := d.StartList()
	if n < 0 {
		return
	}
	s := make([]*ast.Field, n)
	for i := 0; i < n; i++ {
		decode_ast_Field(d, &s[i])
	}
	*p = s
}

func init() {
	codec.Register([]*ast.Field(nil),
		func(e *codec.Encoder, x any) { encode_slice_ast_Field(e, x.([]*ast.Field)) },
		func(d *codec.Decoder) any { var x []*ast.Field; decode_slice_ast_Field(d, &x); return x })
}

func encode_slice_ast_Ident(e *codec.Encoder, s []*ast.Ident) {
	if s == nil {
		e.EncodeNil()
		return
	}
	e.StartList(len(s))
	for _, x := range s {
		encode_ast_Ident(e, x)
	}
}

func decode_slice_ast_Ident(d *codec.Decoder, p *[]*ast.Ident) {
	n := d.StartList()
	if n < 0 {
		return
	}
	s := make([]*ast.Ident, n)
	for i := 0; i < n; i++ {
		decode_ast_Ident(d, &s[i])
	}
	*p = s
}

func init() {
	codec.Register([]*ast.Ident(nil),
		func(e *codec.Encoder, x any) { encode_slice_ast_Ident(e, x.([]*ast.Ident)) },
		func(d *codec.Decoder) any { var x []*ast.Ident; decode_slice_ast_Ident(d, &x); return x })
}

func encode_slice_ast_Spec(e *codec.Encoder, s []ast.Spec) {
	if s == nil {
		e.EncodeNil()
		return
	}
	e.StartList(len(s))
	for _, x := range s {
		e.EncodeAny(x)
	}
}

func decode_slice_ast_Spec(d *codec.Decoder, p *[]ast.Spec) {
	n := d.StartList()
	if n < 0 {
		return
	}
	s := make([]ast.Spec, n)
	for i := 0; i < n; i++ {
		s[i] = d.DecodeAny().(ast.Spec)
	}
	*p = s
}

func init() {
	codec.Register([]ast.Spec(nil),
		func(e *codec.Encoder, x any) { encode_slice_ast_Spec(e, x.([]ast.Spec)) },
		func(d *codec.Decoder) any { var x []ast.Spec; decode_slice_ast_Spec(d, &x); return x })
}

// Fields of ast_Object: Kind Name Decl Data Type

func encode_ast_Object(e *codec.Encoder, x *ast.Object) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Kind != 0 {
		e.EncodeUint(0)
		e.EncodeInt(int64(x.Kind))
	}
	if x.Name != "" {
		e.EncodeUint(1)
		e.EncodeString(x.Name)
	}
	if x.Decl != nil {
		e.EncodeUint(2)
		e.EncodeAny(x.Decl)
	}
	if x.Data != nil {
		e.EncodeUint(3)
		e.EncodeAny(x.Data)
	}
	if x.Type != nil {
		e.EncodeUint(4)
		e.EncodeAny(x.Type)
	}
	e.EndStruct()
}

func decode_ast_Object(d *codec.Decoder, p **ast.Object) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.Object)
		return
	}
	var x ast.Object
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Kind = ast.ObjKind(d.DecodeInt())
		case 1:
			x.Name = d.DecodeString()
		case 2:
			x.Decl = d.DecodeAny()
		case 3:
			x.Data = d.DecodeAny()
		case 4:
			x.Type = d.DecodeAny()
		default:
			d.UnknownField("ast.Object", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.Object{},
		func(e *codec.Encoder, x any) { encode_ast_Object(e, x.(*ast.Object)) },
		func(d *codec.Decoder) any {
			var x *ast.Object
			decode_ast_Object(d, &x)
			return x
		})
}

func encode_map_string_ast_Object(e *codec.Encoder, m map[string]*ast.Object) {
	if m == nil {
		e.EncodeNil()
		return
	}
	e.StartList(2 * len(m))
	for k, v := range m {
		e.EncodeString(k)
		encode_ast_Object(e, v)
	}
}

func decode_map_string_ast_Object(d *codec.Decoder, p *map[string]*ast.Object) {
	n2 := d.StartList()
	if n2 < 0 {
		return
	}
	n := n2 / 2
	m := make(map[string]*ast.Object, n)
	var k string
	var v *ast.Object
	for i := 0; i < n; i++ {
		k = d.DecodeString()
		decode_ast_Object(d, &v)
		m[k] = v
	}
	*p = m
}

func init() {
	codec.Register(map[string]*ast.Object(nil),
		func(e *codec.Encoder, x any) { encode_map_string_ast_Object(e, x.(map[string]*ast.Object)) },
		func(d *codec.Decoder) any {
			var x map[string]*ast.Object
			decode_map_string_ast_Object(d, &x)
			return x
		})
}

func encode_slice_File(e *codec.Encoder, s []*File) {
	if s == nil {
		e.EncodeNil()
		return
	}
	e.StartList(len(s))
	for _, x := range s {
		encode_File(e, x)
	}
}

func decode_slice_File(d *codec.Decoder, p *[]*File) {
	n := d.StartList()
	if n < 0 {
		return
	}
	s := make([]*File, n)
	for i := 0; i < n; i++ {
		decode_File(d, &s[i])
	}
	*p = s
}

func init() {
	codec.Register([]*File(nil),
		func(e *codec.Encoder, x any) { encode_slice_File(e, x.([]*File)) },
		func(d *codec.Decoder) any { var x []*File; decode_slice_File(d, &x); return x })
}

func encode_map_string_bool(e *codec.Encoder, m map[string]bool) {
	if m == nil {
		e.EncodeNil()
		return
	}
	e.StartList(2 * len(m))
	for k, v := range m {
		e.EncodeString(k)
		e.EncodeBool(v)
	}
}

func decode_map_string_bool(d *codec.Decoder, p *map[string]bool) {
	n2 := d.StartList()
	if n2 < 0 {
		return
	}
	n := n2 / 2
	m := make(map[string]bool, n)
	var k string
	var v bool
	for i := 0; i < n; i++ {
		k = d.DecodeString()
		v = d.DecodeBool()
		m[k] = v
	}
	*p = m
}

func init() {
	codec.Register(map[string]bool(nil),
		func(e *codec.Encoder, x any) { encode_map_string_bool(e, x.(map[string]bool)) },
		func(d *codec.Decoder) any { var x map[string]bool; decode_map_string_bool(d, &x); return x })
}

// Fields of File: Name AST

func encode_File(e *codec.Encoder, x *File) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Name != "" {
		e.EncodeUint(0)
		e.EncodeString(x.Name)
	}
	if x.AST != nil {
		e.EncodeUint(1)
		encode_ast_File(e, x.AST)
	}
	e.EndStruct()
}

func decode_File(d *codec.Decoder, p **File) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*File)
		return
	}
	var x File
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			x.Name = d.DecodeString()
		case 1:
			decode_ast_File(d, &x.AST)
		default:
			d.UnknownField("File", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&File{},
		func(e *codec.Encoder, x any) { encode_File(e, x.(*File)) },
		func(d *codec.Decoder) any {
			var x *File
			decode_File(d, &x)
			return x
		})
}

// Fields of ast_File: Doc Package Name Decls Scope Imports Unresolved Comments

func encode_ast_File(e *codec.Encoder, x *ast.File) {
	if !e.StartStruct(x == nil, x) {
		return
	}
	if x.Doc != nil {
		e.EncodeUint(0)
		encode_ast_CommentGroup(e, x.Doc)
	}
	if x.Package != 0 {
		e.EncodeUint(1)
		e.EncodeInt(int64(x.Package))
	}
	if x.Name != nil {
		e.EncodeUint(2)
		encode_ast_Ident(e, x.Name)
	}
	if x.Decls != nil {
		e.EncodeUint(3)
		encode_slice_ast_Decl(e, x.Decls)
	}
	if x.Scope != nil {
		e.EncodeUint(4)
		encode_ast_Scope(e, x.Scope)
	}
	if x.Imports != nil {
		e.EncodeUint(5)
		encode_slice_ast_ImportSpec(e, x.Imports)
	}
	if x.Unresolved != nil {
		e.EncodeUint(6)
		encode_slice_ast_Ident(e, x.Unresolved)
	}
	if x.Comments != nil {
		e.EncodeUint(7)
		encode_slice_ast_CommentGroup(e, x.Comments)
	}
	e.EndStruct()
}

func decode_ast_File(d *codec.Decoder, p **ast.File) {
	proceed, ref := d.StartStruct()
	if !proceed {
		return
	}
	if ref != nil {
		*p = ref.(*ast.File)
		return
	}
	var x ast.File
	d.StoreRef(&x)
	for {
		n := d.NextStructField()
		if n < 0 {
			break
		}
		switch n {
		case 0:
			decode_ast_CommentGroup(d, &x.Doc)
		case 1:
			x.Package = token.Pos(d.DecodeInt())
		case 2:
			decode_ast_Ident(d, &x.Name)
		case 3:
			decode_slice_ast_Decl(d, &x.Decls)
		case 4:
			decode_ast_Scope(d, &x.Scope)
		case 5:
			decode_slice_ast_ImportSpec(d, &x.Imports)
		case 6:
			decode_slice_ast_Ident(d, &x.Unresolved)
		case 7:
			decode_slice_ast_CommentGroup(d, &x.Comments)
		default:
			d.UnknownField("ast.File", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.File{},
		func(e *codec.Encoder, x any) { encode_ast_File(e, x.(*ast.File)) },
		func(d *codec.Decoder) any {
			var x *ast.File
			decode_ast_File(d, &x)
			return x
		})
}

func encode_slice_ast_Decl(e *codec.Encoder, s []ast.Decl) {
	if s == nil {
		e.EncodeNil()
		return
	}
	e.StartList(len(s))
	for _, x := range s {
		e.EncodeAny(x)
	}
}

func decode_slice_ast_Decl(d *codec.Decoder, p *[]ast.Decl) {
	n := d.StartList()
	if n < 0 {
		return
	}
	s := make([]ast.Decl, n)
	for i := 0; i < n; i++ {
		s[i] = d.DecodeAny().(ast.Decl)
	}
	*p = s
}

func init() {
	codec.Register([]ast.Decl(nil),
		func(e *codec.Encoder, x any) { encode_slice_ast_Decl(e, x.([]ast.Decl)) },
		func(d *codec.Decoder) any { var x []ast.Decl; decode_slice_ast_Decl(d, &x); return x })
}

func encode_slice_ast_ImportSpec(e *codec.Encoder, s []*ast.ImportSpec) {
	if s == nil {
		e.EncodeNil()
		return
	}
	e.StartList(len(s))
	for _, x := range s {
		encode_ast_ImportSpec(e, x)
	}
}

func decode_slice_ast_ImportSpec(d *codec.Decoder, p *[]*ast.ImportSpec) {
	n := d.StartList()
	if n < 0 {
		return
	}
	s := make([]*ast.ImportSpec, n)
	for i := 0; i < n; i++ {
		decode_ast_ImportSpec(d, &s[i])
	}
	*p = s
}

func init() {
	codec.Register([]*ast.ImportSpec(nil),
		func(e *codec.Encoder, x any) { encode_slice_ast_ImportSpec(e, x.([]*ast.ImportSpec)) },
		func(d *codec.Decoder) any { var x []*ast.ImportSpec; decode_slice_ast_ImportSpec(d, &x); return x })
}

func encode_slice_ast_CommentGroup(e *codec.Encoder, s []*ast.CommentGroup) {
	if s == nil {
		e.EncodeNil()
		return
	}
	e.StartList(len(s))
	for _, x := range s {
		encode_ast_CommentGroup(e, x)
	}
}

func decode_slice_ast_CommentGroup(d *codec.Decoder, p *[]*ast.CommentGroup) {
	n := d.StartList()
	if n < 0 {
		return
	}
	s := make([]*ast.CommentGroup, n)
	for i := 0; i < n; i++ {
		decode_ast_CommentGroup(d, &s[i])
	}
	*p = s
}

func init() {
	codec.Register([]*ast.CommentGroup(nil),
		func(e *codec.Encoder, x any) { encode_slice_ast_CommentGroup(e, x.([]*ast.CommentGroup)) },
		func(d *codec.Decoder) any { var x []*ast.CommentGroup; decode_slice_ast_CommentGroup(d, &x); return x })
}
