<commit_before>package factory

import (
	"errors"
	"reflect"
	"strconv"
	"sync/atomic"
)

var (
	TagName = "factory"
)

type Factory struct {
	model        interface{}
	numField     int
	rt           reflect.Type
	rv           *reflect.Value
	attrGens     []*attrGenerator
	nameIndexMap map[string]int // pair for attribute name and field index.
	isPtr        bool
}

type Args interface {
	Instance() interface{}
	Parent() Args
	pipeline(int) *pipeline
}

type argsStruct struct {
	rv *reflect.Value
	pl *pipeline
}

func (args *argsStruct) Instance() interface{} {
	return args.rv.Interface()
}

func (args *argsStruct) Parent() Args {
	return args.pl.parent
}

func (args *argsStruct) pipeline(num int) *pipeline {
	if args.pl == nil {
		return newPipeline(num)
	}
	return args.pl
}

type Stacks []*int64

func (st *Stacks) Size(idx int) int64 {
	return *(*st)[idx]
}

// Set method is not goroutine safe.
func (st *Stacks) Set(idx, val int) {
	var ini int64 = 0
	(*st)[idx] = &ini
	atomic.StoreInt64((*st)[idx], int64(val))
}

func (st *Stacks) Push(idx, delta int) {
	atomic.AddInt64((*st)[idx], int64(delta))
}

func (st *Stacks) Pop(idx, delta int) {
	atomic.AddInt64((*st)[idx], -int64(delta))
}

func (st *Stacks) Next(idx int) bool {
	st.Pop(idx, 1)
	return *(*st)[idx] >= 0
}

func (st *Stacks) Has(idx int) bool {
	return (*st)[idx] != nil
}

type pipeline struct {
	stacks Stacks
	parent Args
}

func newPipeline(size int) *pipeline {
	return &pipeline{stacks: make(Stacks, size)}
}

func (pl *pipeline) Next(args Args) *pipeline {
	npl := &pipeline{}
	npl.parent = args
	npl.stacks = make(Stacks, len(pl.stacks))
	for i, sptr := range pl.stacks {
		if sptr != nil {
			stack := *sptr
			npl.stacks[i] = &stack
		}
	}
	return npl
}

func NewFactory(model interface{}) *Factory {
	fa := &Factory{}
	fa.model = model
	fa.nameIndexMap = make(map[string]int)

	fa.init()
	return fa
}

type attrGenerator struct {
	genFunc func(Args) (interface{}, error)
	key     string
	value   interface{}
	isNil   bool<commit_msg>add document on initialization order of attribute values (#6)<commit_after>package factory

import (
	"errors"
	"reflect"
	"strconv"
	"sync/atomic"
)

var (
	TagName = "factory"
)

type Factory struct {
	model        interface{}
	numField     int
	rt           reflect.Type
	rv           *reflect.Value
	attrGens     []*attrGenerator
	nameIndexMap map[string]int // pair for attribute name and field index.
	isPtr        bool
}

type Args interface {
	Instance() interface{}
	Parent() Args
	pipeline(int) *pipeline
}

type argsStruct struct {
	rv *reflect.Value
	pl *pipeline
}

// Instance returns a object to which the generator declared just before is applied
func (args *argsStruct) Instance() interface{} {
	return args.rv.Interface()
}

// Parent returns a parent argument if current factory is a subfactory of parent
func (args *argsStruct) Parent() Args {
	return args.pl.parent
}

func (args *argsStruct) pipeline(num int) *pipeline {
	if args.pl == nil {
		return newPipeline(num)
	}
	return args.pl
}

type Stacks []*int64

func (st *Stacks) Size(idx int) int64 {
	return *(*st)[idx]
}

// Set method is not goroutine safe.
func (st *Stacks) Set(idx, val int) {
	var ini int64 = 0
	(*st)[idx] = &ini
	atomic.StoreInt64((*st)[idx], int64(val))
}

func (st *Stacks) Push(idx, delta int) {
	atomic.AddInt64((*st)[idx], int64(delta))
}

func (st *Stacks) Pop(idx, delta int) {
	atomic.AddInt64((*st)[idx], -int64(delta))
}

func (st *Stacks) Next(idx int) bool {
	st.Pop(idx, 1)
	return *(*st)[idx] >= 0
}

func (st *Stacks) Has(idx int) bool {
	return (*st)[idx] != nil
}

type pipeline struct {
	stacks Stacks
	parent Args
}

func newPipeline(size int) *pipeline {
	return &pipeline{stacks: make(Stacks, size)}
}

func (pl *pipeline) Next(args Args) *pipeline {
	npl := &pipeline{}
	npl.parent = args
	npl.stacks = make(Stacks, len(pl.stacks))
	for i, sptr := range pl.stacks {
		if sptr != nil {
			stack := *sptr
			npl.stacks[i] = &stack
		}
	}
	return npl
}

// NewFactory returns a new factory for specified model class
// Each generator is applied in the order in which they are declared
func NewFactory(model interface{}) *Factory {
	fa := &Factory{}
	fa.model = model
	fa.nameIndexMap = make(map[string]int)

	fa.init()
	return fa
}

type attrGenerator struct {
	genFunc func(Args) (interface{}, error)
	key     string
	value   interface{}
	isNil   bool
{'fraction_non_alphanumeric': 0.13626023657870792, 'fraction_numerical': 0.009781619654231119, 'mean_word_length': 3.7077087794432546, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '611778', 'n_tokens_mistral': 1623, 'n_tokens_neox': 1607, 'n_words': 478}