OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / text / message / catalog / dict.go
1 // Copyright 2017 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
5 package catalog
6
7 import (
8         "sync"
9
10         "golang.org/x/text/internal"
11         "golang.org/x/text/internal/catmsg"
12         "golang.org/x/text/language"
13 )
14
15 // TODO:
16 // Dictionary returns a Dictionary that returns the first Message, using the
17 // given language tag, that matches:
18 //   1. the last one registered by one of the Set methods
19 //   2. returned by one of the Loaders
20 //   3. repeat from 1. using the parent language
21 // This approach allows messages to be underspecified.
22 // func (c *Catalog) Dictionary(tag language.Tag) (Dictionary, error) {
23 //      // TODO: verify dictionary exists.
24 //      return &dict{&c.index, tag}, nil
25 // }
26
27 type dict struct {
28         s   *store
29         tag language.Tag // TODO: make compact tag.
30 }
31
32 func (d *dict) Lookup(key string) (data string, ok bool) {
33         return d.s.lookup(d.tag, key)
34 }
35
36 func (c *Catalog) set(tag language.Tag, key string, s *store, msg ...Message) error {
37         data, err := catmsg.Compile(tag, &dict{&c.macros, tag}, firstInSequence(msg))
38
39         s.mutex.Lock()
40         defer s.mutex.Unlock()
41
42         m := s.index[tag]
43         if m == nil {
44                 m = msgMap{}
45                 if s.index == nil {
46                         s.index = map[language.Tag]msgMap{}
47                 }
48                 s.index[tag] = m
49         }
50
51         m[key] = data
52         return err
53 }
54
55 type store struct {
56         mutex sync.RWMutex
57         index map[language.Tag]msgMap
58 }
59
60 type msgMap map[string]string
61
62 func (s *store) lookup(tag language.Tag, key string) (data string, ok bool) {
63         s.mutex.RLock()
64         defer s.mutex.RUnlock()
65
66         for ; ; tag = tag.Parent() {
67                 if msgs, ok := s.index[tag]; ok {
68                         if msg, ok := msgs[key]; ok {
69                                 return msg, true
70                         }
71                 }
72                 if tag == language.Und {
73                         break
74                 }
75         }
76         return "", false
77 }
78
79 // Languages returns all languages for which the store contains variants.
80 func (s *store) languages() []language.Tag {
81         s.mutex.RLock()
82         defer s.mutex.RUnlock()
83
84         tags := make([]language.Tag, 0, len(s.index))
85         for t := range s.index {
86                 tags = append(tags, t)
87         }
88         internal.SortTags(tags)
89         return tags
90 }