github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/text/message/catalog.go (about) 1 // Copyright 2015 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 message 6 7 // TODO: some types in this file will need to be made public at some time. 8 // Documentation and method names will reflect this by using the exported name. 9 10 import ( 11 "sync" 12 13 "golang.org/x/text/internal" 14 "golang.org/x/text/internal/format" 15 "golang.org/x/text/language" 16 ) 17 18 // DefaultCatalog is used by SetString. 19 var DefaultCatalog *Catalog = newCatalog() 20 21 // SetString calls SetString on the default Catalog. 22 func SetString(tag language.Tag, key string, msg string) error { 23 return DefaultCatalog.SetString(tag, key, msg) 24 } 25 26 // TODO: 27 // // SetSelect is a shorthand for DefaultCatalog.SetSelect. 28 // func SetSelect(tag language.Tag, key string, s ...format.Statement) error { 29 // return DefaultCatalog.SetSelect(tag, key, s...) 30 // } 31 32 type msgMap map[string]format.Statement 33 34 // A Catalog holds translations for messages for supported languages. 35 type Catalog struct { 36 index map[language.Tag]msgMap 37 38 mutex sync.Mutex // For locking all operations. 39 } 40 41 // Printer creates a Printer that uses c. 42 func (c *Catalog) Printer(tag language.Tag) *Printer { 43 // TODO: pre-create indexes for tag lookup. 44 return &Printer{ 45 tag: tag, 46 cat: c, 47 } 48 } 49 50 // NewCatalog returns a new Catalog. If a message is not present in a Catalog, 51 // the fallback Catalogs will be used in order as an alternative source. 52 func newCatalog(fallback ...*Catalog) *Catalog { 53 // TODO: implement fallback. 54 return &Catalog{ 55 index: map[language.Tag]msgMap{}, 56 } 57 } 58 59 // Languages returns a slice of all languages for which the Catalog contains 60 // variants. 61 func (c *Catalog) Languages() []language.Tag { 62 c.mutex.Lock() 63 defer c.mutex.Unlock() 64 65 tags := []language.Tag{} 66 for t, _ := range c.index { 67 tags = append(tags, t) 68 } 69 internal.SortTags(tags) 70 return tags 71 } 72 73 // SetString sets the translation for the given language and key. 74 func (c *Catalog) SetString(tag language.Tag, key string, msg string) error { 75 return c.set(tag, key, format.String(msg)) 76 } 77 78 func (c *Catalog) get(tag language.Tag, key string) (msg string, ok bool) { 79 c.mutex.Lock() 80 defer c.mutex.Unlock() 81 82 for ; ; tag = tag.Parent() { 83 if msgs, ok := c.index[tag]; ok { 84 if statement, ok := msgs[key]; ok { 85 // TODO: use type switches when we implement selecting. 86 msg := string(statement.(format.String)) 87 return msg, true 88 } 89 } 90 if tag == language.Und { 91 break 92 } 93 } 94 return "", false 95 } 96 97 func (c *Catalog) set(tag language.Tag, key string, s ...format.Statement) error { 98 if len(s) != 1 { 99 // TODO: handle errors properly when we process statement sequences. 100 panic("statement sequence should be of length 1") 101 } 102 103 c.mutex.Lock() 104 defer c.mutex.Unlock() 105 106 m := c.index[tag] 107 if m == nil { 108 m = map[string]format.Statement{} 109 c.index[tag] = m 110 } 111 m[key] = s[0] 112 return nil 113 }