You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

603 lines
15 KiB

  1. // Copyright 2013 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package cldr
  5. // This file implements the various inheritance constructs defined by LDML.
  6. // See https://www.unicode.org/reports/tr35/#Inheritance_and_Validity
  7. // for more details.
  8. import (
  9. "fmt"
  10. "log"
  11. "reflect"
  12. "regexp"
  13. "sort"
  14. "strings"
  15. )
  16. // fieldIter iterates over fields in a struct. It includes
  17. // fields of embedded structs.
  18. type fieldIter struct {
  19. v reflect.Value
  20. index, n []int
  21. }
  22. func iter(v reflect.Value) fieldIter {
  23. if v.Kind() != reflect.Struct {
  24. log.Panicf("value %v must be a struct", v)
  25. }
  26. i := fieldIter{
  27. v: v,
  28. index: []int{0},
  29. n: []int{v.NumField()},
  30. }
  31. i.descent()
  32. return i
  33. }
  34. func (i *fieldIter) descent() {
  35. for f := i.field(); f.Anonymous && f.Type.NumField() > 0; f = i.field() {
  36. i.index = append(i.index, 0)
  37. i.n = append(i.n, f.Type.NumField())
  38. }
  39. }
  40. func (i *fieldIter) done() bool {
  41. return len(i.index) == 1 && i.index[0] >= i.n[0]
  42. }
  43. func skip(f reflect.StructField) bool {
  44. return !f.Anonymous && (f.Name[0] < 'A' || f.Name[0] > 'Z')
  45. }
  46. func (i *fieldIter) next() {
  47. for {
  48. k := len(i.index) - 1
  49. i.index[k]++
  50. if i.index[k] < i.n[k] {
  51. if !skip(i.field()) {
  52. break
  53. }
  54. } else {
  55. if k == 0 {
  56. return
  57. }
  58. i.index = i.index[:k]
  59. i.n = i.n[:k]
  60. }
  61. }
  62. i.descent()
  63. }
  64. func (i *fieldIter) value() reflect.Value {
  65. return i.v.FieldByIndex(i.index)
  66. }
  67. func (i *fieldIter) field() reflect.StructField {
  68. return i.v.Type().FieldByIndex(i.index)
  69. }
  70. type visitor func(v reflect.Value) error
  71. var stopDescent = fmt.Errorf("do not recurse")
  72. func (f visitor) visit(x interface{}) error {
  73. return f.visitRec(reflect.ValueOf(x))
  74. }
  75. // visit recursively calls f on all nodes in v.
  76. func (f visitor) visitRec(v reflect.Value) error {
  77. if v.Kind() == reflect.Ptr {
  78. if v.IsNil() {
  79. return nil
  80. }
  81. return f.visitRec(v.Elem())
  82. }
  83. if err := f(v); err != nil {
  84. if err == stopDescent {
  85. return nil
  86. }
  87. return err
  88. }
  89. switch v.Kind() {
  90. case reflect.Struct:
  91. for i := iter(v); !i.done(); i.next() {
  92. if err := f.visitRec(i.value()); err != nil {
  93. return err
  94. }
  95. }
  96. case reflect.Slice:
  97. for i := 0; i < v.Len(); i++ {
  98. if err := f.visitRec(v.Index(i)); err != nil {
  99. return err
  100. }
  101. }
  102. }
  103. return nil
  104. }
  105. // getPath is used for error reporting purposes only.
  106. func getPath(e Elem) string {
  107. if e == nil {
  108. return "<nil>"
  109. }
  110. if e.enclosing() == nil {
  111. return e.GetCommon().name
  112. }
  113. if e.GetCommon().Type == "" {
  114. return fmt.Sprintf("%s.%s", getPath(e.enclosing()), e.GetCommon().name)
  115. }
  116. return fmt.Sprintf("%s.%s[type=%s]", getPath(e.enclosing()), e.GetCommon().name, e.GetCommon().Type)
  117. }
  118. // xmlName returns the xml name of the element or attribute
  119. func xmlName(f reflect.StructField) (name string, attr bool) {
  120. tags := strings.Split(f.Tag.Get("xml"), ",")
  121. for _, s := range tags {
  122. attr = attr || s == "attr"
  123. }
  124. return tags[0], attr
  125. }
  126. func findField(v reflect.Value, key string) (reflect.Value, error) {
  127. v = reflect.Indirect(v)
  128. for i := iter(v); !i.done(); i.next() {
  129. if n, _ := xmlName(i.field()); n == key {
  130. return i.value(), nil
  131. }
  132. }
  133. return reflect.Value{}, fmt.Errorf("cldr: no field %q in element %#v", key, v.Interface())
  134. }
  135. var xpathPart = regexp.MustCompile(`(\pL+)(?:\[@(\pL+)='([\w-]+)'\])?`)
  136. func walkXPath(e Elem, path string) (res Elem, err error) {
  137. for _, c := range strings.Split(path, "/") {
  138. if c == ".." {
  139. if e = e.enclosing(); e == nil {
  140. panic("path ..")
  141. return nil, fmt.Errorf(`cldr: ".." moves past root in path %q`, path)
  142. }
  143. continue
  144. } else if c == "" {
  145. continue
  146. }
  147. m := xpathPart.FindStringSubmatch(c)
  148. if len(m) == 0 || len(m[0]) != len(c) {
  149. return nil, fmt.Errorf("cldr: syntax error in path component %q", c)
  150. }
  151. v, err := findField(reflect.ValueOf(e), m[1])
  152. if err != nil {
  153. return nil, err
  154. }
  155. switch v.Kind() {
  156. case reflect.Slice:
  157. i := 0
  158. if m[2] != "" || v.Len() > 1 {
  159. if m[2] == "" {
  160. m[2] = "type"
  161. if m[3] = e.GetCommon().Default(); m[3] == "" {
  162. return nil, fmt.Errorf("cldr: type selector or default value needed for element %s", m[1])
  163. }
  164. }
  165. for ; i < v.Len(); i++ {
  166. vi := v.Index(i)
  167. key, err := findField(vi.Elem(), m[2])
  168. if err != nil {
  169. return nil, err
  170. }
  171. key = reflect.Indirect(key)
  172. if key.Kind() == reflect.String && key.String() == m[3] {
  173. break
  174. }
  175. }
  176. }
  177. if i == v.Len() || v.Index(i).IsNil() {
  178. return nil, fmt.Errorf("no %s found with %s==%s", m[1], m[2], m[3])
  179. }
  180. e = v.Index(i).Interface().(Elem)
  181. case reflect.Ptr:
  182. if v.IsNil() {
  183. return nil, fmt.Errorf("cldr: element %q not found within element %q", m[1], e.GetCommon().name)
  184. }
  185. var ok bool
  186. if e, ok = v.Interface().(Elem); !ok {
  187. return nil, fmt.Errorf("cldr: %q is not an XML element", m[1])
  188. } else if m[2] != "" || m[3] != "" {
  189. return nil, fmt.Errorf("cldr: no type selector allowed for element %s", m[1])
  190. }
  191. default:
  192. return nil, fmt.Errorf("cldr: %q is not an XML element", m[1])
  193. }
  194. }
  195. return e, nil
  196. }
  197. const absPrefix = "//ldml/"
  198. func (cldr *CLDR) resolveAlias(e Elem, src, path string) (res Elem, err error) {
  199. if src != "locale" {
  200. if !strings.HasPrefix(path, absPrefix) {
  201. return nil, fmt.Errorf("cldr: expected absolute path, found %q", path)
  202. }
  203. path = path[len(absPrefix):]
  204. if e, err = cldr.resolve(src); err != nil {
  205. return nil, err
  206. }
  207. }
  208. return walkXPath(e, path)
  209. }
  210. func (cldr *CLDR) resolveAndMergeAlias(e Elem) error {
  211. alias := e.GetCommon().Alias
  212. if alias == nil {
  213. return nil
  214. }
  215. a, err := cldr.resolveAlias(e, alias.Source, alias.Path)
  216. if err != nil {
  217. return fmt.Errorf("%v: error evaluating path %q: %v", getPath(e), alias.Path, err)
  218. }
  219. // Ensure alias node was already evaluated. TODO: avoid double evaluation.
  220. err = cldr.resolveAndMergeAlias(a)
  221. v := reflect.ValueOf(e).Elem()
  222. for i := iter(reflect.ValueOf(a).Elem()); !i.done(); i.next() {
  223. if vv := i.value(); vv.Kind() != reflect.Ptr || !vv.IsNil() {
  224. if _, attr := xmlName(i.field()); !attr {
  225. v.FieldByIndex(i.index).Set(vv)
  226. }
  227. }
  228. }
  229. return err
  230. }
  231. func (cldr *CLDR) aliasResolver() visitor {
  232. return func(v reflect.Value) (err error) {
  233. if e, ok := v.Addr().Interface().(Elem); ok {
  234. err = cldr.resolveAndMergeAlias(e)
  235. if err == nil && blocking[e.GetCommon().name] {
  236. return stopDescent
  237. }
  238. }
  239. return err
  240. }
  241. }
  242. // elements within blocking elements do not inherit.
  243. // Taken from CLDR's supplementalMetaData.xml.
  244. var blocking = map[string]bool{
  245. "identity": true,
  246. "supplementalData": true,
  247. "cldrTest": true,
  248. "collation": true,
  249. "transform": true,
  250. }
  251. // Distinguishing attributes affect inheritance; two elements with different
  252. // distinguishing attributes are treated as different for purposes of inheritance,
  253. // except when such attributes occur in the indicated elements.
  254. // Taken from CLDR's supplementalMetaData.xml.
  255. var distinguishing = map[string][]string{
  256. "key": nil,
  257. "request_id": nil,
  258. "id": nil,
  259. "registry": nil,
  260. "alt": nil,
  261. "iso4217": nil,
  262. "iso3166": nil,
  263. "mzone": nil,
  264. "from": nil,
  265. "to": nil,
  266. "type": []string{
  267. "abbreviationFallback",
  268. "default",
  269. "mapping",
  270. "measurementSystem",
  271. "preferenceOrdering",
  272. },
  273. "numberSystem": nil,
  274. }
  275. func in(set []string, s string) bool {
  276. for _, v := range set {
  277. if v == s {
  278. return true
  279. }
  280. }
  281. return false
  282. }
  283. // attrKey computes a key based on the distinguishable attributes of
  284. // an element and its values.
  285. func attrKey(v reflect.Value, exclude ...string) string {
  286. parts := []string{}
  287. ename := v.Interface().(Elem).GetCommon().name
  288. v = v.Elem()
  289. for i := iter(v); !i.done(); i.next() {
  290. if name, attr := xmlName(i.field()); attr {
  291. if except, ok := distinguishing[name]; ok && !in(exclude, name) && !in(except, ename) {
  292. v := i.value()
  293. if v.Kind() == reflect.Ptr {
  294. v = v.Elem()
  295. }
  296. if v.IsValid() {
  297. parts = append(parts, fmt.Sprintf("%s=%s", name, v.String()))
  298. }
  299. }
  300. }
  301. }
  302. sort.Strings(parts)
  303. return strings.Join(parts, ";")
  304. }
  305. // Key returns a key for e derived from all distinguishing attributes
  306. // except those specified by exclude.
  307. func Key(e Elem, exclude ...string) string {
  308. return attrKey(reflect.ValueOf(e), exclude...)
  309. }
  310. // linkEnclosing sets the enclosing element as well as the name
  311. // for all sub-elements of child, recursively.
  312. func linkEnclosing(parent, child Elem) {
  313. child.setEnclosing(parent)
  314. v := reflect.ValueOf(child).Elem()
  315. for i := iter(v); !i.done(); i.next() {
  316. vf := i.value()
  317. if vf.Kind() == reflect.Slice {
  318. for j := 0; j < vf.Len(); j++ {
  319. linkEnclosing(child, vf.Index(j).Interface().(Elem))
  320. }
  321. } else if vf.Kind() == reflect.Ptr && !vf.IsNil() && vf.Elem().Kind() == reflect.Struct {
  322. linkEnclosing(child, vf.Interface().(Elem))
  323. }
  324. }
  325. }
  326. func setNames(e Elem, name string) {
  327. e.setName(name)
  328. v := reflect.ValueOf(e).Elem()
  329. for i := iter(v); !i.done(); i.next() {
  330. vf := i.value()
  331. name, _ = xmlName(i.field())
  332. if vf.Kind() == reflect.Slice {
  333. for j := 0; j < vf.Len(); j++ {
  334. setNames(vf.Index(j).Interface().(Elem), name)
  335. }
  336. } else if vf.Kind() == reflect.Ptr && !vf.IsNil() && vf.Elem().Kind() == reflect.Struct {
  337. setNames(vf.Interface().(Elem), name)
  338. }
  339. }
  340. }
  341. // deepCopy copies elements of v recursively. All elements of v that may
  342. // be modified by inheritance are explicitly copied.
  343. func deepCopy(v reflect.Value) reflect.Value {
  344. switch v.Kind() {
  345. case reflect.Ptr:
  346. if v.IsNil() || v.Elem().Kind() != reflect.Struct {
  347. return v
  348. }
  349. nv := reflect.New(v.Elem().Type())
  350. nv.Elem().Set(v.Elem())
  351. deepCopyRec(nv.Elem(), v.Elem())
  352. return nv
  353. case reflect.Slice:
  354. nv := reflect.MakeSlice(v.Type(), v.Len(), v.Len())
  355. for i := 0; i < v.Len(); i++ {
  356. deepCopyRec(nv.Index(i), v.Index(i))
  357. }
  358. return nv
  359. }
  360. panic("deepCopy: must be called with pointer or slice")
  361. }
  362. // deepCopyRec is only called by deepCopy.
  363. func deepCopyRec(nv, v reflect.Value) {
  364. if v.Kind() == reflect.Struct {
  365. t := v.Type()
  366. for i := 0; i < v.NumField(); i++ {
  367. if name, attr := xmlName(t.Field(i)); name != "" && !attr {
  368. deepCopyRec(nv.Field(i), v.Field(i))
  369. }
  370. }
  371. } else {
  372. nv.Set(deepCopy(v))
  373. }
  374. }
  375. // newNode is used to insert a missing node during inheritance.
  376. func (cldr *CLDR) newNode(v, enc reflect.Value) reflect.Value {
  377. n := reflect.New(v.Type())
  378. for i := iter(v); !i.done(); i.next() {
  379. if name, attr := xmlName(i.field()); name == "" || attr {
  380. n.Elem().FieldByIndex(i.index).Set(i.value())
  381. }
  382. }
  383. n.Interface().(Elem).GetCommon().setEnclosing(enc.Addr().Interface().(Elem))
  384. return n
  385. }
  386. // v, parent must be pointers to struct
  387. func (cldr *CLDR) inheritFields(v, parent reflect.Value) (res reflect.Value, err error) {
  388. t := v.Type()
  389. nv := reflect.New(t)
  390. nv.Elem().Set(v)
  391. for i := iter(v); !i.done(); i.next() {
  392. vf := i.value()
  393. f := i.field()
  394. name, attr := xmlName(f)
  395. if name == "" || attr {
  396. continue
  397. }
  398. pf := parent.FieldByIndex(i.index)
  399. if blocking[name] {
  400. if vf.IsNil() {
  401. vf = pf
  402. }
  403. nv.Elem().FieldByIndex(i.index).Set(deepCopy(vf))
  404. continue
  405. }
  406. switch f.Type.Kind() {
  407. case reflect.Ptr:
  408. if f.Type.Elem().Kind() == reflect.Struct {
  409. if !vf.IsNil() {
  410. if vf, err = cldr.inheritStructPtr(vf, pf); err != nil {
  411. return reflect.Value{}, err
  412. }
  413. vf.Interface().(Elem).setEnclosing(nv.Interface().(Elem))
  414. nv.Elem().FieldByIndex(i.index).Set(vf)
  415. } else if !pf.IsNil() {
  416. n := cldr.newNode(pf.Elem(), v)
  417. if vf, err = cldr.inheritStructPtr(n, pf); err != nil {
  418. return reflect.Value{}, err
  419. }
  420. vf.Interface().(Elem).setEnclosing(nv.Interface().(Elem))
  421. nv.Elem().FieldByIndex(i.index).Set(vf)
  422. }
  423. }
  424. case reflect.Slice:
  425. vf, err := cldr.inheritSlice(nv.Elem(), vf, pf)
  426. if err != nil {
  427. return reflect.Zero(t), err
  428. }
  429. nv.Elem().FieldByIndex(i.index).Set(vf)
  430. }
  431. }
  432. return nv, nil
  433. }
  434. func root(e Elem) *LDML {
  435. for ; e.enclosing() != nil; e = e.enclosing() {
  436. }
  437. return e.(*LDML)
  438. }
  439. // inheritStructPtr first merges possible aliases in with v and then inherits
  440. // any underspecified elements from parent.
  441. func (cldr *CLDR) inheritStructPtr(v, parent reflect.Value) (r reflect.Value, err error) {
  442. if !v.IsNil() {
  443. e := v.Interface().(Elem).GetCommon()
  444. alias := e.Alias
  445. if alias == nil && !parent.IsNil() {
  446. alias = parent.Interface().(Elem).GetCommon().Alias
  447. }
  448. if alias != nil {
  449. a, err := cldr.resolveAlias(v.Interface().(Elem), alias.Source, alias.Path)
  450. if a != nil {
  451. if v, err = cldr.inheritFields(v.Elem(), reflect.ValueOf(a).Elem()); err != nil {
  452. return reflect.Value{}, err
  453. }
  454. }
  455. }
  456. if !parent.IsNil() {
  457. return cldr.inheritFields(v.Elem(), parent.Elem())
  458. }
  459. } else if parent.IsNil() {
  460. panic("should not reach here")
  461. }
  462. return v, nil
  463. }
  464. // Must be slice of struct pointers.
  465. func (cldr *CLDR) inheritSlice(enc, v, parent reflect.Value) (res reflect.Value, err error) {
  466. t := v.Type()
  467. index := make(map[string]reflect.Value)
  468. if !v.IsNil() {
  469. for i := 0; i < v.Len(); i++ {
  470. vi := v.Index(i)
  471. key := attrKey(vi)
  472. index[key] = vi
  473. }
  474. }
  475. if !parent.IsNil() {
  476. for i := 0; i < parent.Len(); i++ {
  477. vi := parent.Index(i)
  478. key := attrKey(vi)
  479. if w, ok := index[key]; ok {
  480. index[key], err = cldr.inheritStructPtr(w, vi)
  481. } else {
  482. n := cldr.newNode(vi.Elem(), enc)
  483. index[key], err = cldr.inheritStructPtr(n, vi)
  484. }
  485. index[key].Interface().(Elem).setEnclosing(enc.Addr().Interface().(Elem))
  486. if err != nil {
  487. return v, err
  488. }
  489. }
  490. }
  491. keys := make([]string, 0, len(index))
  492. for k, _ := range index {
  493. keys = append(keys, k)
  494. }
  495. sort.Strings(keys)
  496. sl := reflect.MakeSlice(t, len(index), len(index))
  497. for i, k := range keys {
  498. sl.Index(i).Set(index[k])
  499. }
  500. return sl, nil
  501. }
  502. func parentLocale(loc string) string {
  503. parts := strings.Split(loc, "_")
  504. if len(parts) == 1 {
  505. return "root"
  506. }
  507. parts = parts[:len(parts)-1]
  508. key := strings.Join(parts, "_")
  509. return key
  510. }
  511. func (cldr *CLDR) resolve(loc string) (res *LDML, err error) {
  512. if r := cldr.resolved[loc]; r != nil {
  513. return r, nil
  514. }
  515. x := cldr.RawLDML(loc)
  516. if x == nil {
  517. return nil, fmt.Errorf("cldr: unknown locale %q", loc)
  518. }
  519. var v reflect.Value
  520. if loc == "root" {
  521. x = deepCopy(reflect.ValueOf(x)).Interface().(*LDML)
  522. linkEnclosing(nil, x)
  523. err = cldr.aliasResolver().visit(x)
  524. } else {
  525. key := parentLocale(loc)
  526. var parent *LDML
  527. for ; cldr.locale[key] == nil; key = parentLocale(key) {
  528. }
  529. if parent, err = cldr.resolve(key); err != nil {
  530. return nil, err
  531. }
  532. v, err = cldr.inheritFields(reflect.ValueOf(x).Elem(), reflect.ValueOf(parent).Elem())
  533. x = v.Interface().(*LDML)
  534. linkEnclosing(nil, x)
  535. }
  536. if err != nil {
  537. return nil, err
  538. }
  539. cldr.resolved[loc] = x
  540. return x, err
  541. }
  542. // finalize finalizes the initialization of the raw LDML structs. It also
  543. // removed unwanted fields, as specified by filter, so that they will not
  544. // be unnecessarily evaluated.
  545. func (cldr *CLDR) finalize(filter []string) {
  546. for _, x := range cldr.locale {
  547. if filter != nil {
  548. v := reflect.ValueOf(x).Elem()
  549. t := v.Type()
  550. for i := 0; i < v.NumField(); i++ {
  551. f := t.Field(i)
  552. name, _ := xmlName(f)
  553. if name != "" && name != "identity" && !in(filter, name) {
  554. v.Field(i).Set(reflect.Zero(f.Type))
  555. }
  556. }
  557. }
  558. linkEnclosing(nil, x) // for resolving aliases and paths
  559. setNames(x, "ldml")
  560. }
  561. }