Package renderer renders the given AST to certain formats.
package renderer

import (
	
	
	

	
	
)
A Config struct is a data structure that holds configuration of the Renderer.
type Config struct {
	Options       map[OptionName]interface{}
	NodeRenderers util.PrioritizedSlice
}
NewConfig returns a new Config
func () *Config {
	return &Config{
		Options:       map[OptionName]interface{}{},
		NodeRenderers: util.PrioritizedSlice{},
	}
}
An OptionName is a name of the option.
An Option interface is a functional option type for the Renderer.
type Option interface {
	SetConfig(*Config)
}

type withNodeRenderers struct {
	value []util.PrioritizedValue
}

func ( *withNodeRenderers) ( *Config) {
	.NodeRenderers = append(.NodeRenderers, .value...)
}
WithNodeRenderers is a functional option that allow you to add NodeRenderers to the renderer.
func ( ...util.PrioritizedValue) Option {
	return &withNodeRenderers{}
}

type withOption struct {
	name  OptionName
	value interface{}
}

func ( *withOption) ( *Config) {
	.Options[.name] = .value
}
WithOption is a functional option that allow you to set an arbitrary option to the parser.
func ( OptionName,  interface{}) Option {
	return &withOption{, }
}
A SetOptioner interface sets given option to the object.
SetOption sets given option to the object. Unacceptable options may be passed. Thus implementations must ignore unacceptable options.
	SetOption(name OptionName, value interface{})
}
NodeRendererFunc is a function that renders a given node.
type NodeRendererFunc func(writer util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error)
A NodeRenderer interface offers NodeRendererFuncs.
RendererFuncs registers NodeRendererFuncs to given NodeRendererFuncRegisterer.
	RegisterFuncs(NodeRendererFuncRegisterer)
}
A NodeRendererFuncRegisterer registers
Register registers given NodeRendererFunc to this object.
A Renderer interface renders given AST node to given writer with given Renderer.
type Renderer interface {
	Render(w io.Writer, source []byte, n ast.Node) error
AddOptions adds given option to this renderer.
NewRenderer returns a new Renderer with given options.
func ( ...Option) Renderer {
	 := NewConfig()
	for ,  := range  {
		.SetConfig()
	}

	 := &renderer{
		options:              map[OptionName]interface{}{},
		config:               ,
		nodeRendererFuncsTmp: map[ast.NodeKind]NodeRendererFunc{},
	}

	return 
}

func ( *renderer) ( ...Option) {
	for ,  := range  {
		.SetConfig(.config)
	}
}

func ( *renderer) ( ast.NodeKind,  NodeRendererFunc) {
	.nodeRendererFuncsTmp[] = 
	if int() > .maxKind {
		.maxKind = int()
	}
}
Render renders the given AST node to the given writer with the given Renderer.
func ( *renderer) ( io.Writer,  []byte,  ast.Node) error {
	.initSync.Do(func() {
		.options = .config.Options
		.config.NodeRenderers.Sort()
		 := len(.config.NodeRenderers)
		for  :=  - 1;  >= 0; -- {
			 := .config.NodeRenderers[]
			,  := .Value.(NodeRenderer)
			if ,  := .Value.(SetOptioner);  {
				for ,  := range .options {
					.SetOption(, )
				}
			}
			.RegisterFuncs()
		}
		.nodeRendererFuncs = make([]NodeRendererFunc, .maxKind+1)
		for ,  := range .nodeRendererFuncsTmp {
			.nodeRendererFuncs[] = 
		}
		.config = nil
		.nodeRendererFuncsTmp = nil
	})
	,  := .(util.BufWriter)
	if ! {
		 = bufio.NewWriter()
	}
	 := ast.Walk(, func( ast.Node,  bool) (ast.WalkStatus, error) {
		 := ast.WalkStatus(ast.WalkContinue)
		var  error
		 := .nodeRendererFuncs[.Kind()]
		if  != nil {
			,  = (, , , )
		}
		return , 
	})
	if  != nil {
		return 
	}
	return .Flush()