// 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 interface{}) { encode_ast_ArrayType(e, x.(*ast.ArrayType)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_AssignStmt(e, x.(*ast.AssignStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_BadDecl(e, x.(*ast.BadDecl)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_BadExpr(e, x.(*ast.BadExpr)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_BadStmt(e, x.(*ast.BadStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_BasicLit(e, x.(*ast.BasicLit)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_BinaryExpr(e, x.(*ast.BinaryExpr)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_BlockStmt(e, x.(*ast.BlockStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_BranchStmt(e, x.(*ast.BranchStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_CallExpr(e, x.(*ast.CallExpr)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_CaseClause(e, x.(*ast.CaseClause)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_ChanType(e, x.(*ast.ChanType)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_CommClause(e, x.(*ast.CommClause)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_CommentGroup(e, x.(*ast.CommentGroup)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_Comment(e, x.(*ast.Comment)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_CompositeLit(e, x.(*ast.CompositeLit)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_DeclStmt(e, x.(*ast.DeclStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_DeferStmt(e, x.(*ast.DeferStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_Ellipsis(e, x.(*ast.Ellipsis)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_EmptyStmt(e, x.(*ast.EmptyStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_ExprStmt(e, x.(*ast.ExprStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_FieldList(e, x.(*ast.FieldList)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_Field(e, x.(*ast.Field)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_ForStmt(e, x.(*ast.ForStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_FuncDecl(e, x.(*ast.FuncDecl)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_FuncLit(e, x.(*ast.FuncLit)) },
		func(d *codec.Decoder) interface{} {
			var x *ast.FuncLit
			decode_ast_FuncLit(d, &x)
			return x
		})
}

// Fields of ast_FuncType: Func Params Results

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)
	}
	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)
		default:
			d.UnknownField("ast.FuncType", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.FuncType{},
		func(e *codec.Encoder, x interface{}) { encode_ast_FuncType(e, x.(*ast.FuncType)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_GenDecl(e, x.(*ast.GenDecl)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_GoStmt(e, x.(*ast.GoStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_Ident(e, x.(*ast.Ident)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_IfStmt(e, x.(*ast.IfStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_ImportSpec(e, x.(*ast.ImportSpec)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_IncDecStmt(e, x.(*ast.IncDecStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_IndexExpr(e, x.(*ast.IndexExpr)) },
		func(d *codec.Decoder) interface{} {
			var x *ast.IndexExpr
			decode_ast_IndexExpr(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 interface{}) { encode_ast_InterfaceType(e, x.(*ast.InterfaceType)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_KeyValueExpr(e, x.(*ast.KeyValueExpr)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_LabeledStmt(e, x.(*ast.LabeledStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_MapType(e, x.(*ast.MapType)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_ParenExpr(e, x.(*ast.ParenExpr)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_RangeStmt(e, x.(*ast.RangeStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_ReturnStmt(e, x.(*ast.ReturnStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_Scope(e, x.(*ast.Scope)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_SelectStmt(e, x.(*ast.SelectStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_SelectorExpr(e, x.(*ast.SelectorExpr)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_SendStmt(e, x.(*ast.SendStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_SliceExpr(e, x.(*ast.SliceExpr)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_StarExpr(e, x.(*ast.StarExpr)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_StructType(e, x.(*ast.StructType)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_SwitchStmt(e, x.(*ast.SwitchStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_TypeAssertExpr(e, x.(*ast.TypeAssertExpr)) },
		func(d *codec.Decoder) interface{} {
			var x *ast.TypeAssertExpr
			decode_ast_TypeAssertExpr(d, &x)
			return x
		})
}

// Fields of ast_TypeSpec: Doc Name Assign Type Comment

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)
	}
	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)
		default:
			d.UnknownField("ast.TypeSpec", n)
		}
		*p = &x
	}
}

func init() {
	codec.Register(&ast.TypeSpec{},
		func(e *codec.Encoder, x interface{}) { encode_ast_TypeSpec(e, x.(*ast.TypeSpec)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_TypeSwitchStmt(e, x.(*ast.TypeSwitchStmt)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_UnaryExpr(e, x.(*ast.UnaryExpr)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_ValueSpec(e, x.(*ast.ValueSpec)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_encPackage(e, x.(*encPackage)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_slice_ast_Expr(e, x.([]ast.Expr)) },
		func(d *codec.Decoder) interface{} { 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 interface{}) { encode_slice_ast_Stmt(e, x.([]ast.Stmt)) },
		func(d *codec.Decoder) interface{} { 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 interface{}) { encode_slice_ast_Comment(e, x.([]*ast.Comment)) },
		func(d *codec.Decoder) interface{} { 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 interface{}) { encode_slice_ast_Field(e, x.([]*ast.Field)) },
		func(d *codec.Decoder) interface{} { 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 interface{}) { encode_slice_ast_Ident(e, x.([]*ast.Ident)) },
		func(d *codec.Decoder) interface{} { 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 interface{}) { encode_slice_ast_Spec(e, x.([]ast.Spec)) },
		func(d *codec.Decoder) interface{} { 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 interface{}) { encode_ast_Object(e, x.(*ast.Object)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_map_string_ast_Object(e, x.(map[string]*ast.Object)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_slice_File(e, x.([]*File)) },
		func(d *codec.Decoder) interface{} { 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 interface{}) { encode_map_string_bool(e, x.(map[string]bool)) },
		func(d *codec.Decoder) interface{} { 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 interface{}) { encode_File(e, x.(*File)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_ast_File(e, x.(*ast.File)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_slice_ast_Decl(e, x.([]ast.Decl)) },
		func(d *codec.Decoder) interface{} { 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 interface{}) { encode_slice_ast_ImportSpec(e, x.([]*ast.ImportSpec)) },
		func(d *codec.Decoder) interface{} {
			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 interface{}) { encode_slice_ast_CommentGroup(e, x.([]*ast.CommentGroup)) },
		func(d *codec.Decoder) interface{} {
			var x []*ast.CommentGroup
			decode_slice_ast_CommentGroup(d, &x)
			return x
		})
}
