func (pp *primitiveParser) gatherFields(reachable map[string]*data, s *ast.StructType, visible bool) (bool, uint8, []field) {
	fields := []field{}

	immutable := false
	var version uint8
	if s == nil {
		return immutable, version, fields
	}

	for _, f := range s.Fields.List {
		var typeName string
		switch t := f.Type.(type) {
		case *ast.Ident:
			typeName = t.Name
		case *ast.StarExpr:
			if i, ok := t.X.(*ast.Ident); ok {
				typeName = i.Name
			}
		}
		if len(f.Names) == 0 {
			switch typeName {
			case "immutable":
				immutable = true
			case "v1Schema":
				version = 1
			case "v2Schema":
				version = 2
			}
			embedded := pp.structmap[typeName]
			embImmutable, embVersion, embeddedFields := pp.gatherFields(reachable, embedded, visible || immutable)
			immutable = immutable || embImmutable
			visible = visible || immutable
			if version == 0 {
				version = embVersion
			}
			fields = append(fields, embeddedFields...)
			continue
		}

		// This isn't an embedded struct, but it might be our own struct
		// that is now reachable. we need to create a MarshalJSON func for
		// it if so.
		if _, ok := pp.structmap[typeName]; ok {
			pp.visitStruct(reachable, typeName, visible)
		}

		for _, n := range f.Names {
			name := n.Name
			if f.Tag != nil {
				tname := parseJSONTag(f.Tag.Value)
				if tname != "" {
					name = tname
				}
			}
			fields = append(fields, field{
				Name:  name,
				Field: n.Name,
			})
		}
	}

	return immutable, version, fields
}
// gatherFields is used by visitStruct to gather the fields for a struct.
// embedded struct fields are hoisted up to the enclosing struct for JSON
// representation.
// referenced structs will in turn be visited.
//
// gatherFields transfers visibility from immutable structs, or any already
// known visible structs, to structs that they reference.
// visibility determines if we should create a MarshalJSON func for the struct.
gatherFields is used by visitStruct to gather the fields for a struct.
embedded struct fields are hoisted up to the enclosing struct for JSON
representation.
referenced structs will in turn be visited.

gatherFields transfers visibility from immutable structs, or any already
known visible structs, to structs that they reference.
visibility determines if we should create a MarshalJSON func for the struct.
// gatherFields is used by visitStruct to gather the fields for a struct . // embedded struct fields are hoisted up to the enclosing struct for JSON // representation . // referenced structs will in turn be visited . // // gatherFields transfers visibility from immutable structs or any already // known visible structs to structs that they reference . // visibility determines if we should create a MarshalJSON func for the struct .
func (pp *primitiveParser) gatherFields(reachable map[string]*data, s *ast.StructType, visible bool) (bool, uint8, []field) {
	fields := []field{}
	immutable := false
	var version uint8
	if s == nil {
		return immutable, version, fields
	}
	for _, f := range s.Fields.List {
		var typeName string
		switch t := f.Type.(type) {
		case *ast.Ident:
			typeName = t.Name
		case *ast.StarExpr:
			if i, ok := t.X.(*ast.Ident); ok {
				typeName = i.Name
			}
		}
		if len(f.Names) == 0 {
			switch typeName {
			case "immutable":
				immutable = true
			case "v1Schema":
				version = 1
			case "v2Schema":
				version = 2
			}
			embedded := pp.structmap[typeName]
			embImmutable, embVersion, embeddedFields := pp.gatherFields(reachable, embedded, visible || immutable)
			immutable = immutable || embImmutable
			visible = visible || immutable
			if version == 0 {
				version = embVersion
			}
			fields = append(fields, embeddedFields...)
			continue
		}
		if _, ok := pp.structmap[typeName]; ok {
			pp.visitStruct(reachable, typeName, visible)
		}
		for _, n := range f.Names {
			name := n.Name
			if f.Tag != nil {
				tname := parseJSONTag(f.Tag.Value)
				if tname != "" {
					name = tname
				}
			}
			fields = append(fields, field{
				Name:  name,
				Field: n.Name,
			})
		}
	}
	return immutable, version, fields
}
func ( pp * primitiveParser ) gatherFields ( reachable map [ string ] * data , s * ast . StructType , visible bool ) ( bool , uint8 , [ ] field ) { fields := [ ] field { } immutable := false var version uint8 if s == nil { return immutable , version , fields } for _ , f := range s . Fields . List { var typeName string switch t := f . Type . ( type ) { case * ast . Ident : typeName = t . Name case * ast . StarExpr : if i , ok := t . X . ( * ast . Ident ) ; ok { typeName = i . Name } } if len ( f . Names ) == 0 { switch typeName { case " " : immutable = true case " " : version = 1 case " " : version = 2 } embedded := pp . structmap [ typeName ] embImmutable , embVersion , embeddedFields := pp . gatherFields ( reachable , embedded , visible || immutable ) immutable = immutable || embImmutable visible = visible || immutable if version == 0 { version = embVersion } fields = append ( fields , embeddedFields ... ) continue } if _ , ok := pp . structmap [ typeName ] ; ok { pp . visitStruct ( reachable , typeName , visible ) } for _ , n := range f . Names { name := n . Name if f . Tag != nil { tname := parseJSONTag ( f . Tag . Value ) if tname != " " { name = tname } } fields = append ( fields , field { Name : name , Field : n . Name , } ) } } return immutable , version , fields }
gatherFields is used by visitStruct to gather the fields for a struct.
gatherFields is used by visitStruct to gather the fields for a struct .
// This isn't an embedded struct, but it might be our own struct // that is now reachable. we need to create a MarshalJSON func for // it if so.