vendor/github.com/pelletier/go-toml/v2/unmarshaler.go
changeset 262 8d3354485fc3
parent 260 445e01aede7e
child 265 05c40b36d3b2
equal deleted inserted replaced
261:270cc4dda0c5 262:8d3354485fc3
   121 	// If set to true, calling nextExpr will not actually pull a new expression
   121 	// If set to true, calling nextExpr will not actually pull a new expression
   122 	// but turn off the flag instead.
   122 	// but turn off the flag instead.
   123 	stashedExpr bool
   123 	stashedExpr bool
   124 
   124 
   125 	// Skip expressions until a table is found. This is set to true when a
   125 	// Skip expressions until a table is found. This is set to true when a
   126 	// table could not be create (missing field in map), so all KV expressions
   126 	// table could not be created (missing field in map), so all KV expressions
   127 	// need to be skipped.
   127 	// need to be skipped.
   128 	skipUntilTable bool
   128 	skipUntilTable bool
   129 
   129 
   130 	// Tracks position in Go arrays.
   130 	// Tracks position in Go arrays.
   131 	// This is used when decoding [[array tables]] into Go arrays. Given array
   131 	// This is used when decoding [[array tables]] into Go arrays. Given array
   481 		}
   481 		}
   482 		t := v.Type()
   482 		t := v.Type()
   483 		d.errorContext.Struct = t
   483 		d.errorContext.Struct = t
   484 		d.errorContext.Field = path
   484 		d.errorContext.Field = path
   485 
   485 
   486 		f := v.FieldByIndex(path)
   486 		f := fieldByIndex(v, path)
   487 		x, err := nextFn(key, f)
   487 		x, err := nextFn(key, f)
   488 		if err != nil || d.skipUntilTable {
   488 		if err != nil || d.skipUntilTable {
   489 			return reflect.Value{}, err
   489 			return reflect.Value{}, err
   490 		}
   490 		}
   491 		if x.IsValid() {
   491 		if x.IsValid() {
  1069 		}
  1069 		}
  1070 		t := v.Type()
  1070 		t := v.Type()
  1071 		d.errorContext.Struct = t
  1071 		d.errorContext.Struct = t
  1072 		d.errorContext.Field = path
  1072 		d.errorContext.Field = path
  1073 
  1073 
  1074 		f := v.FieldByIndex(path)
  1074 		f := fieldByIndex(v, path)
  1075 		x, err := d.handleKeyValueInner(key, value, f)
  1075 		x, err := d.handleKeyValueInner(key, value, f)
  1076 		if err != nil {
  1076 		if err != nil {
  1077 			return reflect.Value{}, err
  1077 			return reflect.Value{}, err
  1078 		}
  1078 		}
  1079 
  1079 
  1133 	}
  1133 	}
  1134 	elem = v.Elem()
  1134 	elem = v.Elem()
  1135 	return elem
  1135 	return elem
  1136 }
  1136 }
  1137 
  1137 
       
  1138 // Same as reflect.Value.FieldByIndex, but creates pointers if needed.
       
  1139 func fieldByIndex(v reflect.Value, path []int) reflect.Value {
       
  1140 	for i, x := range path {
       
  1141 		v = v.Field(x)
       
  1142 
       
  1143 		if i < len(path)-1 && v.Kind() == reflect.Ptr {
       
  1144 			if v.IsNil() {
       
  1145 				v.Set(reflect.New(v.Type().Elem()))
       
  1146 			}
       
  1147 			v = v.Elem()
       
  1148 		}
       
  1149 	}
       
  1150 	return v
       
  1151 }
       
  1152 
  1138 type fieldPathsMap = map[string][]int
  1153 type fieldPathsMap = map[string][]int
  1139 
  1154 
  1140 var globalFieldPathsCache atomic.Value // map[danger.TypeID]fieldPathsMap
  1155 var globalFieldPathsCache atomic.Value // map[danger.TypeID]fieldPathsMap
  1141 
  1156 
  1142 func structFieldPath(v reflect.Value, name string) ([]int, bool) {
  1157 func structFieldPath(v reflect.Value, name string) ([]int, bool) {
  1190 		if i := strings.IndexByte(name, ','); i >= 0 {
  1205 		if i := strings.IndexByte(name, ','); i >= 0 {
  1191 			name = name[:i]
  1206 			name = name[:i]
  1192 		}
  1207 		}
  1193 
  1208 
  1194 		if f.Anonymous && name == "" {
  1209 		if f.Anonymous && name == "" {
  1195 			forEachField(f.Type, fieldPath, do)
  1210 			t2 := f.Type
       
  1211 			if t2.Kind() == reflect.Ptr {
       
  1212 				t2 = t2.Elem()
       
  1213 			}
       
  1214 
       
  1215 			if t2.Kind() == reflect.Struct {
       
  1216 				forEachField(t2, fieldPath, do)
       
  1217 			}
  1196 			continue
  1218 			continue
  1197 		}
  1219 		}
  1198 
  1220 
  1199 		if name == "" {
  1221 		if name == "" {
  1200 			name = f.Name
  1222 			name = f.Name