選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 

481 行
15 KiB

  1. // Copyright 2016 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Package fields provides a view of the fields of a struct that follows the Go
  15. // rules, amended to consider tags and case insensitivity.
  16. //
  17. // Usage
  18. //
  19. // First define a function that interprets tags:
  20. //
  21. // func parseTag(st reflect.StructTag) (name string, keep bool, other interface{}, err error) { ... }
  22. //
  23. // The function's return values describe whether to ignore the field
  24. // completely or provide an alternate name, as well as other data from the
  25. // parse that is stored to avoid re-parsing.
  26. //
  27. // Then define a function to validate the type:
  28. //
  29. // func validate(t reflect.Type) error { ... }
  30. //
  31. // Then, if necessary, define a function to specify leaf types - types
  32. // which should be considered one field and not be recursed into:
  33. //
  34. // func isLeafType(t reflect.Type) bool { ... }
  35. //
  36. // eg:
  37. //
  38. // func isLeafType(t reflect.Type) bool {
  39. // return t == reflect.TypeOf(time.Time{})
  40. // }
  41. //
  42. // Next, construct a Cache, passing your functions. As its name suggests, a
  43. // Cache remembers validation and field information for a type, so subsequent
  44. // calls with the same type are very fast.
  45. //
  46. // cache := fields.NewCache(parseTag, validate, isLeafType)
  47. //
  48. // To get the fields of a struct type as determined by the above rules, call
  49. // the Fields method:
  50. //
  51. // fields, err := cache.Fields(reflect.TypeOf(MyStruct{}))
  52. //
  53. // The return value can be treated as a slice of Fields.
  54. //
  55. // Given a string, such as a key or column name obtained during unmarshalling,
  56. // call Match on the list of fields to find a field whose name is the best
  57. // match:
  58. //
  59. // field := fields.Match(name)
  60. //
  61. // Match looks for an exact match first, then falls back to a case-insensitive
  62. // comparison.
  63. package fields
  64. import (
  65. "bytes"
  66. "errors"
  67. "reflect"
  68. "sort"
  69. "strings"
  70. "sync"
  71. )
  72. // A Field records information about a struct field.
  73. type Field struct {
  74. Name string // effective field name
  75. NameFromTag bool // did Name come from a tag?
  76. Type reflect.Type // field type
  77. Index []int // index sequence, for reflect.Value.FieldByIndex
  78. ParsedTag interface{} // third return value of the parseTag function
  79. nameBytes []byte
  80. equalFold func(s, t []byte) bool
  81. }
  82. // ParseTagFunc is a function that accepts a struct tag and returns four values: an alternative name for the field
  83. // extracted from the tag, a boolean saying whether to keep the field or ignore it, additional data that is stored
  84. // with the field information to avoid having to parse the tag again, and an error.
  85. type ParseTagFunc func(reflect.StructTag) (name string, keep bool, other interface{}, err error)
  86. // ValidateFunc is a function that accepts a reflect.Type and returns an error if the struct type is invalid in any
  87. // way.
  88. type ValidateFunc func(reflect.Type) error
  89. // LeafTypesFunc is a function that accepts a reflect.Type and returns true if the struct type a leaf, or false if not.
  90. // TODO(deklerk) is this description accurate?
  91. type LeafTypesFunc func(reflect.Type) bool
  92. // A Cache records information about the fields of struct types.
  93. //
  94. // A Cache is safe for use by multiple goroutines.
  95. type Cache struct {
  96. parseTag ParseTagFunc
  97. validate ValidateFunc
  98. leafTypes LeafTypesFunc
  99. cache sync.Map // from reflect.Type to cacheValue
  100. }
  101. // NewCache constructs a Cache.
  102. //
  103. // Its first argument should be a function that accepts
  104. // a struct tag and returns four values: an alternative name for the field
  105. // extracted from the tag, a boolean saying whether to keep the field or ignore
  106. // it, additional data that is stored with the field information to avoid
  107. // having to parse the tag again, and an error.
  108. //
  109. // Its second argument should be a function that accepts a reflect.Type and
  110. // returns an error if the struct type is invalid in any way. For example, it
  111. // may check that all of the struct field tags are valid, or that all fields
  112. // are of an appropriate type.
  113. func NewCache(parseTag ParseTagFunc, validate ValidateFunc, leafTypes LeafTypesFunc) *Cache {
  114. if parseTag == nil {
  115. parseTag = func(reflect.StructTag) (string, bool, interface{}, error) {
  116. return "", true, nil, nil
  117. }
  118. }
  119. if validate == nil {
  120. validate = func(reflect.Type) error {
  121. return nil
  122. }
  123. }
  124. if leafTypes == nil {
  125. leafTypes = func(reflect.Type) bool {
  126. return false
  127. }
  128. }
  129. return &Cache{
  130. parseTag: parseTag,
  131. validate: validate,
  132. leafTypes: leafTypes,
  133. }
  134. }
  135. // A fieldScan represents an item on the fieldByNameFunc scan work list.
  136. type fieldScan struct {
  137. typ reflect.Type
  138. index []int
  139. }
  140. // Fields returns all the exported fields of t, which must be a struct type. It
  141. // follows the standard Go rules for embedded fields, modified by the presence
  142. // of tags. The result is sorted lexicographically by index.
  143. //
  144. // These rules apply in the absence of tags:
  145. // Anonymous struct fields are treated as if their inner exported fields were
  146. // fields in the outer struct (embedding). The result includes all fields that
  147. // aren't shadowed by fields at higher level of embedding. If more than one
  148. // field with the same name exists at the same level of embedding, it is
  149. // excluded. An anonymous field that is not of struct type is treated as having
  150. // its type as its name.
  151. //
  152. // Tags modify these rules as follows:
  153. // A field's tag is used as its name.
  154. // An anonymous struct field with a name given in its tag is treated as
  155. // a field having that name, rather than an embedded struct (the struct's
  156. // fields will not be returned).
  157. // If more than one field with the same name exists at the same level of embedding,
  158. // but exactly one of them is tagged, then the tagged field is reported and the others
  159. // are ignored.
  160. func (c *Cache) Fields(t reflect.Type) (List, error) {
  161. if t.Kind() != reflect.Struct {
  162. panic("fields: Fields of non-struct type")
  163. }
  164. return c.cachedTypeFields(t)
  165. }
  166. // A List is a list of Fields.
  167. type List []Field
  168. // Match returns the field in the list whose name best matches the supplied
  169. // name, nor nil if no field does. If there is a field with the exact name, it
  170. // is returned. Otherwise the first field (sorted by index) whose name matches
  171. // case-insensitively is returned.
  172. func (l List) Match(name string) *Field {
  173. return l.MatchBytes([]byte(name))
  174. }
  175. // MatchBytes is identical to Match, except that the argument is a byte slice.
  176. func (l List) MatchBytes(name []byte) *Field {
  177. var f *Field
  178. for i := range l {
  179. ff := &l[i]
  180. if bytes.Equal(ff.nameBytes, name) {
  181. return ff
  182. }
  183. if f == nil && ff.equalFold(ff.nameBytes, name) {
  184. f = ff
  185. }
  186. }
  187. return f
  188. }
  189. type cacheValue struct {
  190. fields List
  191. err error
  192. }
  193. // cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
  194. // This code has been copied and modified from
  195. // https://go.googlesource.com/go/+/go1.7.3/src/encoding/json/encode.go.
  196. func (c *Cache) cachedTypeFields(t reflect.Type) (List, error) {
  197. var cv cacheValue
  198. x, ok := c.cache.Load(t)
  199. if ok {
  200. cv = x.(cacheValue)
  201. } else {
  202. if err := c.validate(t); err != nil {
  203. cv = cacheValue{nil, err}
  204. } else {
  205. f, err := c.typeFields(t)
  206. cv = cacheValue{List(f), err}
  207. }
  208. c.cache.Store(t, cv)
  209. }
  210. return cv.fields, cv.err
  211. }
  212. func (c *Cache) typeFields(t reflect.Type) ([]Field, error) {
  213. fields, err := c.listFields(t)
  214. if err != nil {
  215. return nil, err
  216. }
  217. sort.Sort(byName(fields))
  218. // Delete all fields that are hidden by the Go rules for embedded fields.
  219. // The fields are sorted in primary order of name, secondary order of field
  220. // index length. So the first field with a given name is the dominant one.
  221. var out []Field
  222. for advance, i := 0, 0; i < len(fields); i += advance {
  223. // One iteration per name.
  224. // Find the sequence of fields with the name of this first field.
  225. fi := fields[i]
  226. name := fi.Name
  227. for advance = 1; i+advance < len(fields); advance++ {
  228. fj := fields[i+advance]
  229. if fj.Name != name {
  230. break
  231. }
  232. }
  233. // Find the dominant field, if any, out of all fields that have the same name.
  234. dominant, ok := dominantField(fields[i : i+advance])
  235. if ok {
  236. out = append(out, dominant)
  237. }
  238. }
  239. sort.Sort(byIndex(out))
  240. return out, nil
  241. }
  242. func (c *Cache) listFields(t reflect.Type) ([]Field, error) {
  243. // This uses the same condition that the Go language does: there must be a unique instance
  244. // of the match at a given depth level. If there are multiple instances of a match at the
  245. // same depth, they annihilate each other and inhibit any possible match at a lower level.
  246. // The algorithm is breadth first search, one depth level at a time.
  247. // The current and next slices are work queues:
  248. // current lists the fields to visit on this depth level,
  249. // and next lists the fields on the next lower level.
  250. current := []fieldScan{}
  251. next := []fieldScan{{typ: t}}
  252. // nextCount records the number of times an embedded type has been
  253. // encountered and considered for queueing in the 'next' slice.
  254. // We only queue the first one, but we increment the count on each.
  255. // If a struct type T can be reached more than once at a given depth level,
  256. // then it annihilates itself and need not be considered at all when we
  257. // process that next depth level.
  258. var nextCount map[reflect.Type]int
  259. // visited records the structs that have been considered already.
  260. // Embedded pointer fields can create cycles in the graph of
  261. // reachable embedded types; visited avoids following those cycles.
  262. // It also avoids duplicated effort: if we didn't find the field in an
  263. // embedded type T at level 2, we won't find it in one at level 4 either.
  264. visited := map[reflect.Type]bool{}
  265. var fields []Field // Fields found.
  266. for len(next) > 0 {
  267. current, next = next, current[:0]
  268. count := nextCount
  269. nextCount = nil
  270. // Process all the fields at this depth, now listed in 'current'.
  271. // The loop queues embedded fields found in 'next', for processing during the next
  272. // iteration. The multiplicity of the 'current' field counts is recorded
  273. // in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'.
  274. for _, scan := range current {
  275. t := scan.typ
  276. if visited[t] {
  277. // We've looked through this type before, at a higher level.
  278. // That higher level would shadow the lower level we're now at,
  279. // so this one can't be useful to us. Ignore it.
  280. continue
  281. }
  282. visited[t] = true
  283. for i := 0; i < t.NumField(); i++ {
  284. f := t.Field(i)
  285. exported := (f.PkgPath == "")
  286. // If a named field is unexported, ignore it. An anonymous
  287. // unexported field is processed, because it may contain
  288. // exported fields, which are visible.
  289. if !exported && !f.Anonymous {
  290. continue
  291. }
  292. // Examine the tag.
  293. tagName, keep, other, err := c.parseTag(f.Tag)
  294. if err != nil {
  295. return nil, err
  296. }
  297. if !keep {
  298. continue
  299. }
  300. if c.leafTypes(f.Type) {
  301. fields = append(fields, newField(f, tagName, other, scan.index, i))
  302. continue
  303. }
  304. var ntyp reflect.Type
  305. if f.Anonymous {
  306. // Anonymous field of type T or *T.
  307. ntyp = f.Type
  308. if ntyp.Kind() == reflect.Ptr {
  309. ntyp = ntyp.Elem()
  310. }
  311. }
  312. // Record fields with a tag name, non-anonymous fields, or
  313. // anonymous non-struct fields.
  314. if tagName != "" || ntyp == nil || ntyp.Kind() != reflect.Struct {
  315. if !exported {
  316. continue
  317. }
  318. fields = append(fields, newField(f, tagName, other, scan.index, i))
  319. if count[t] > 1 {
  320. // If there were multiple instances, add a second,
  321. // so that the annihilation code will see a duplicate.
  322. fields = append(fields, fields[len(fields)-1])
  323. }
  324. continue
  325. }
  326. // Queue embedded struct fields for processing with next level,
  327. // but only if the embedded types haven't already been queued.
  328. if nextCount[ntyp] > 0 {
  329. nextCount[ntyp] = 2 // exact multiple doesn't matter
  330. continue
  331. }
  332. if nextCount == nil {
  333. nextCount = map[reflect.Type]int{}
  334. }
  335. nextCount[ntyp] = 1
  336. if count[t] > 1 {
  337. nextCount[ntyp] = 2 // exact multiple doesn't matter
  338. }
  339. var index []int
  340. index = append(index, scan.index...)
  341. index = append(index, i)
  342. next = append(next, fieldScan{ntyp, index})
  343. }
  344. }
  345. }
  346. return fields, nil
  347. }
  348. func newField(f reflect.StructField, tagName string, other interface{}, index []int, i int) Field {
  349. name := tagName
  350. if name == "" {
  351. name = f.Name
  352. }
  353. sf := Field{
  354. Name: name,
  355. NameFromTag: tagName != "",
  356. Type: f.Type,
  357. ParsedTag: other,
  358. nameBytes: []byte(name),
  359. }
  360. sf.equalFold = foldFunc(sf.nameBytes)
  361. sf.Index = append(sf.Index, index...)
  362. sf.Index = append(sf.Index, i)
  363. return sf
  364. }
  365. // byName sorts fields using the following criteria, in order:
  366. // 1. name
  367. // 2. embedding depth
  368. // 3. tag presence (preferring a tagged field)
  369. // 4. index sequence.
  370. type byName []Field
  371. func (x byName) Len() int { return len(x) }
  372. func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
  373. func (x byName) Less(i, j int) bool {
  374. if x[i].Name != x[j].Name {
  375. return x[i].Name < x[j].Name
  376. }
  377. if len(x[i].Index) != len(x[j].Index) {
  378. return len(x[i].Index) < len(x[j].Index)
  379. }
  380. if x[i].NameFromTag != x[j].NameFromTag {
  381. return x[i].NameFromTag
  382. }
  383. return byIndex(x).Less(i, j)
  384. }
  385. // byIndex sorts field by index sequence.
  386. type byIndex []Field
  387. func (x byIndex) Len() int { return len(x) }
  388. func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
  389. func (x byIndex) Less(i, j int) bool {
  390. xi := x[i].Index
  391. xj := x[j].Index
  392. ln := len(xi)
  393. if l := len(xj); l < ln {
  394. ln = l
  395. }
  396. for k := 0; k < ln; k++ {
  397. if xi[k] != xj[k] {
  398. return xi[k] < xj[k]
  399. }
  400. }
  401. return len(xi) < len(xj)
  402. }
  403. // dominantField looks through the fields, all of which are known to have the
  404. // same name, to find the single field that dominates the others using Go's
  405. // embedding rules, modified by the presence of tags. If there are multiple
  406. // top-level fields, the boolean will be false: This condition is an error in
  407. // Go and we skip all the fields.
  408. func dominantField(fs []Field) (Field, bool) {
  409. // The fields are sorted in increasing index-length order, then by presence of tag.
  410. // That means that the first field is the dominant one. We need only check
  411. // for error cases: two fields at top level, either both tagged or neither tagged.
  412. if len(fs) > 1 && len(fs[0].Index) == len(fs[1].Index) && fs[0].NameFromTag == fs[1].NameFromTag {
  413. return Field{}, false
  414. }
  415. return fs[0], true
  416. }
  417. // ParseStandardTag extracts the sub-tag named by key, then parses it using the
  418. // de facto standard format introduced in encoding/json:
  419. // "-" means "ignore this tag". It must occur by itself. (parseStandardTag returns an error
  420. // in this case, whereas encoding/json accepts the "-" even if it is not alone.)
  421. // "<name>" provides an alternative name for the field
  422. // "<name>,opt1,opt2,..." specifies options after the name.
  423. // The options are returned as a []string.
  424. func ParseStandardTag(key string, t reflect.StructTag) (name string, keep bool, options []string, err error) {
  425. s := t.Get(key)
  426. parts := strings.Split(s, ",")
  427. if parts[0] == "-" {
  428. if len(parts) > 1 {
  429. return "", false, nil, errors.New(`"-" field tag with options`)
  430. }
  431. return "", false, nil, nil
  432. }
  433. if len(parts) > 1 {
  434. options = parts[1:]
  435. }
  436. return parts[0], true, options, nil
  437. }