From 54d3d47daf9190275bbdaf8703b84969a4593451 Mon Sep 17 00:00:00 2001 From: Corey Hulen Date: Fri, 24 Mar 2017 23:31:34 -0700 Subject: PLT-6076 Adding viper libs for config file changes (#5871) * Adding viper libs for config file changes * Removing the old fsnotify lib * updating some missing libs --- vendor/golang.org/x/text/message/catalog.go | 113 ++++++++++++++ vendor/golang.org/x/text/message/catalog_test.go | 98 ++++++++++++ vendor/golang.org/x/text/message/message.go | 185 +++++++++++++++++++++++ vendor/golang.org/x/text/message/message_test.go | 149 ++++++++++++++++++ 4 files changed, 545 insertions(+) create mode 100644 vendor/golang.org/x/text/message/catalog.go create mode 100644 vendor/golang.org/x/text/message/catalog_test.go create mode 100644 vendor/golang.org/x/text/message/message.go create mode 100644 vendor/golang.org/x/text/message/message_test.go (limited to 'vendor/golang.org/x/text/message') diff --git a/vendor/golang.org/x/text/message/catalog.go b/vendor/golang.org/x/text/message/catalog.go new file mode 100644 index 000000000..41c31f4c6 --- /dev/null +++ b/vendor/golang.org/x/text/message/catalog.go @@ -0,0 +1,113 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package message + +// TODO: some types in this file will need to be made public at some time. +// Documentation and method names will reflect this by using the exported name. + +import ( + "sync" + + "golang.org/x/text/internal" + "golang.org/x/text/internal/format" + "golang.org/x/text/language" +) + +// DefaultCatalog is used by SetString. +var DefaultCatalog *Catalog = newCatalog() + +// SetString calls SetString on the default Catalog. +func SetString(tag language.Tag, key string, msg string) error { + return DefaultCatalog.SetString(tag, key, msg) +} + +// TODO: +// // SetSelect is a shorthand for DefaultCatalog.SetSelect. +// func SetSelect(tag language.Tag, key string, s ...format.Statement) error { +// return DefaultCatalog.SetSelect(tag, key, s...) +// } + +type msgMap map[string]format.Statement + +// A Catalog holds translations for messages for supported languages. +type Catalog struct { + index map[language.Tag]msgMap + + mutex sync.Mutex // For locking all operations. +} + +// Printer creates a Printer that uses c. +func (c *Catalog) Printer(tag language.Tag) *Printer { + // TODO: pre-create indexes for tag lookup. + return &Printer{ + tag: tag, + cat: c, + } +} + +// NewCatalog returns a new Catalog. If a message is not present in a Catalog, +// the fallback Catalogs will be used in order as an alternative source. +func newCatalog(fallback ...*Catalog) *Catalog { + // TODO: implement fallback. + return &Catalog{ + index: map[language.Tag]msgMap{}, + } +} + +// Languages returns a slice of all languages for which the Catalog contains +// variants. +func (c *Catalog) Languages() []language.Tag { + c.mutex.Lock() + defer c.mutex.Unlock() + + tags := []language.Tag{} + for t, _ := range c.index { + tags = append(tags, t) + } + internal.SortTags(tags) + return tags +} + +// SetString sets the translation for the given language and key. +func (c *Catalog) SetString(tag language.Tag, key string, msg string) error { + return c.set(tag, key, format.String(msg)) +} + +func (c *Catalog) get(tag language.Tag, key string) (msg string, ok bool) { + c.mutex.Lock() + defer c.mutex.Unlock() + + for ; ; tag = tag.Parent() { + if msgs, ok := c.index[tag]; ok { + if statement, ok := msgs[key]; ok { + // TODO: use type switches when we implement selecting. + msg := string(statement.(format.String)) + return msg, true + } + } + if tag == language.Und { + break + } + } + return "", false +} + +func (c *Catalog) set(tag language.Tag, key string, s ...format.Statement) error { + if len(s) != 1 { + // TODO: handle errors properly when we process statement sequences. + panic("statement sequence should be of length 1") + } + + c.mutex.Lock() + defer c.mutex.Unlock() + + m := c.index[tag] + if m == nil { + m = map[string]format.Statement{} + c.index[tag] = m + } + m[key] = s[0] + return nil +} diff --git a/vendor/golang.org/x/text/message/catalog_test.go b/vendor/golang.org/x/text/message/catalog_test.go new file mode 100644 index 000000000..3b693c956 --- /dev/null +++ b/vendor/golang.org/x/text/message/catalog_test.go @@ -0,0 +1,98 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package message + +import ( + "reflect" + "testing" + + "golang.org/x/text/internal" + "golang.org/x/text/language" +) + +type entry struct{ tag, key, msg string } + +var testCases = []struct { + desc string + cat []entry + lookup []entry +}{{ + desc: "empty catalog", + lookup: []entry{ + {"en", "key", ""}, + {"en", "", ""}, + {"nl", "", ""}, + }, +}, { + desc: "one entry", + cat: []entry{ + {"en", "hello", "Hello!"}, + }, + lookup: []entry{ + {"und", "hello", ""}, + {"nl", "hello", ""}, + {"en", "hello", "Hello!"}, + {"en-US", "hello", "Hello!"}, + {"en-GB", "hello", "Hello!"}, + {"en-oxendict", "hello", "Hello!"}, + {"en-oxendict-u-ms-metric", "hello", "Hello!"}, + }, +}, { + desc: "hierarchical languages", + cat: []entry{ + {"en", "hello", "Hello!"}, + {"en-GB", "hello", "Hellø!"}, + {"en-US", "hello", "Howdy!"}, + {"en", "greetings", "Greetings!"}, + }, + lookup: []entry{ + {"und", "hello", ""}, + {"nl", "hello", ""}, + {"en", "hello", "Hello!"}, + {"en-US", "hello", "Howdy!"}, + {"en-GB", "hello", "Hellø!"}, + {"en-oxendict", "hello", "Hello!"}, + {"en-US-oxendict-u-ms-metric", "hello", "Howdy!"}, + + {"und", "greetings", ""}, + {"nl", "greetings", ""}, + {"en", "greetings", "Greetings!"}, + {"en-US", "greetings", "Greetings!"}, + {"en-GB", "greetings", "Greetings!"}, + {"en-oxendict", "greetings", "Greetings!"}, + {"en-US-oxendict-u-ms-metric", "greetings", "Greetings!"}, + }, +}} + +func initCat(entries []entry) (*Catalog, []language.Tag) { + tags := []language.Tag{} + cat := newCatalog() + for _, e := range entries { + tag := language.MustParse(e.tag) + tags = append(tags, tag) + cat.SetString(tag, e.key, e.msg) + } + return cat, internal.UniqueTags(tags) +} + +func TestCatalog(t *testing.T) { + for _, tc := range testCases { + cat, wantTags := initCat(tc.cat) + + // languages + if got := cat.Languages(); !reflect.DeepEqual(got, wantTags) { + t.Errorf("%s:Languages: got %v; want %v", tc.desc, got, wantTags) + } + + // Lookup + for _, e := range tc.lookup { + tag := language.MustParse(e.tag) + msg, ok := cat.get(tag, e.key) + if okWant := e.msg != ""; ok != okWant || msg != e.msg { + t.Errorf("%s:Lookup(%s, %s) = %s, %v; want %s, %v", tc.desc, tag, e.key, msg, ok, e.msg, okWant) + } + } + } +} diff --git a/vendor/golang.org/x/text/message/message.go b/vendor/golang.org/x/text/message/message.go new file mode 100644 index 000000000..32ff3ef90 --- /dev/null +++ b/vendor/golang.org/x/text/message/message.go @@ -0,0 +1,185 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package message implements formatted I/O for localized strings with functions +// analogous to the fmt's print functions. +// +// NOTE: Under construction. See https://golang.org/design/12750-localization +// and its corresponding proposal issue https://golang.org/issues/12750. +package message // import "golang.org/x/text/message" + +import ( + "fmt" + "io" + "strings" + + "golang.org/x/text/internal/format" + "golang.org/x/text/language" +) + +// A Printer implements language-specific formatted I/O analogous to the fmt +// package. Only one goroutine may use a Printer at the same time. +type Printer struct { + tag language.Tag + + cat *Catalog + + // NOTE: limiting one goroutine per Printer allows for many optimizations + // and simplifications. We can consider removing this restriction down the + // road if it the benefits do not seem to outweigh the disadvantages. +} + +// NewPrinter returns a Printer that formats messages tailored to language t. +func NewPrinter(t language.Tag) *Printer { + return DefaultCatalog.Printer(t) +} + +// Sprint is like fmt.Sprint, but using language-specific formatting. +func (p *Printer) Sprint(a ...interface{}) string { + return fmt.Sprint(p.bindArgs(a)...) +} + +// Fprint is like fmt.Fprint, but using language-specific formatting. +func (p *Printer) Fprint(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprint(w, p.bindArgs(a)...) +} + +// Print is like fmt.Print, but using language-specific formatting. +func (p *Printer) Print(a ...interface{}) (n int, err error) { + return fmt.Print(p.bindArgs(a)...) +} + +// Sprintln is like fmt.Sprintln, but using language-specific formatting. +func (p *Printer) Sprintln(a ...interface{}) string { + return fmt.Sprintln(p.bindArgs(a)...) +} + +// Fprintln is like fmt.Fprintln, but using language-specific formatting. +func (p *Printer) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprintln(w, p.bindArgs(a)...) +} + +// Println is like fmt.Println, but using language-specific formatting. +func (p *Printer) Println(a ...interface{}) (n int, err error) { + return fmt.Println(p.bindArgs(a)...) +} + +// Sprintf is like fmt.Sprintf, but using language-specific formatting. +func (p *Printer) Sprintf(key Reference, a ...interface{}) string { + msg, hasSub := p.lookup(key) + if !hasSub { + return fmt.Sprintf(msg) // work around limitation of fmt + } + return fmt.Sprintf(msg, p.bindArgs(a)...) +} + +// Fprintf is like fmt.Fprintf, but using language-specific formatting. +func (p *Printer) Fprintf(w io.Writer, key Reference, a ...interface{}) (n int, err error) { + msg, hasSub := p.lookup(key) + if !hasSub { + return fmt.Fprintf(w, msg) // work around limitation of fmt + } + return fmt.Fprintf(w, msg, p.bindArgs(a)...) +} + +// Printf is like fmt.Printf, but using language-specific formatting. +func (p *Printer) Printf(key Reference, a ...interface{}) (n int, err error) { + msg, hasSub := p.lookup(key) + if !hasSub { + return fmt.Printf(msg) // work around limitation of fmt + } + return fmt.Printf(msg, p.bindArgs(a)...) +} + +func (p *Printer) lookup(r Reference) (msg string, hasSub bool) { + var id string + switch v := r.(type) { + case string: + id, msg = v, v + case key: + id, msg = v.id, v.fallback + default: + panic("key argument is not a Reference") + } + if s, ok := p.cat.get(p.tag, id); ok { + msg = s + } + // fmt does not allow all arguments to be dropped in a format string. It + // only allows arguments to be dropped if at least one of the substitutions + // uses the positional marker (e.g. %[1]s). This hack works around this. + // TODO: This is only an approximation of the parsing of substitution + // patterns. Make more precise once we know if we can get by with fmt's + // formatting, which may not be the case. + for i := 0; i < len(msg)-1; i++ { + if msg[i] == '%' { + for i++; i < len(msg); i++ { + if strings.IndexByte("[]#+- *01234567890.", msg[i]) < 0 { + break + } + } + if i < len(msg) && msg[i] != '%' { + hasSub = true + break + } + } + } + return msg, hasSub +} + +// A Reference is a string or a message reference. +type Reference interface { +} + +// Key creates a message Reference for a message where the given id is used for +// message lookup and the fallback is returned when no matches are found. +func Key(id string, fallback string) Reference { + return key{id, fallback} +} + +type key struct { + id, fallback string +} + +// bindArgs wraps arguments with implementation of fmt.Formatter, if needed. +func (p *Printer) bindArgs(a []interface{}) []interface{} { + out := make([]interface{}, len(a)) + for i, x := range a { + switch v := x.(type) { + case fmt.Formatter: + // Wrap the value with a Formatter that augments the State with + // language-specific attributes. + out[i] = &value{v, p} + + // NOTE: as we use fmt.Formatter, we can't distinguish between + // regular and localized formatters, so we always need to wrap it. + + // TODO: handle + // - numbers + // - lists + // - time? + default: + out[i] = x + } + } + return out +} + +// state implements "golang.org/x/text/internal/format".State. +type state struct { + fmt.State + p *Printer +} + +func (s *state) Language() language.Tag { return s.p.tag } + +var _ format.State = &state{} + +type value struct { + x fmt.Formatter + p *Printer +} + +func (v *value) Format(s fmt.State, verb rune) { + v.x.Format(&state{s, v.p}, verb) +} diff --git a/vendor/golang.org/x/text/message/message_test.go b/vendor/golang.org/x/text/message/message_test.go new file mode 100644 index 000000000..f7dba8d06 --- /dev/null +++ b/vendor/golang.org/x/text/message/message_test.go @@ -0,0 +1,149 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package message + +import ( + "bytes" + "fmt" + "io" + "testing" + + "golang.org/x/text/internal/format" + "golang.org/x/text/language" +) + +type formatFunc func(s fmt.State, v rune) + +func (f formatFunc) Format(s fmt.State, v rune) { f(s, v) } + +func TestBinding(t *testing.T) { + testCases := []struct { + tag string + value interface{} + want string + }{ + {"en", 1, "1"}, + {"en", "2", "2"}, + { // Language is passed. + "en", + formatFunc(func(fs fmt.State, v rune) { + s := fs.(format.State) + io.WriteString(s, s.Language().String()) + }), + "en", + }, + } + for i, tc := range testCases { + p := NewPrinter(language.MustParse(tc.tag)) + if got := p.Sprint(tc.value); got != tc.want { + t.Errorf("%d:%s:Sprint(%v) = %q; want %q", i, tc.tag, tc.value, got, tc.want) + } + var buf bytes.Buffer + p.Fprint(&buf, tc.value) + if got := buf.String(); got != tc.want { + t.Errorf("%d:%s:Fprint(%v) = %q; want %q", i, tc.tag, tc.value, got, tc.want) + } + } +} + +func TestFormatSelection(t *testing.T) { + type test struct { + tag string + key Reference + args []interface{} + want string + } + empty := []interface{}{} + joe := []interface{}{"Joe"} + joeAndMary := []interface{}{"Joe", "Mary"} + + testCases := []struct { + desc string + cat []entry + test []test + }{{ + desc: "empty", + test: []test{ + {"en", "key", empty, "key"}, + {"en", "", empty, ""}, + {"nl", "", empty, ""}, + }, + }, { + desc: "hierarchical languages", + cat: []entry{ + {"en", "hello %s", "Hello %s!"}, + {"en-GB", "hello %s", "Hellø %s!"}, + {"en-US", "hello %s", "Howdy %s!"}, + {"en", "greetings %s and %s", "Greetings %s and %s!"}, + }, + test: []test{ + {"und", "hello %s", joe, "hello Joe"}, + {"nl", "hello %s", joe, "hello Joe"}, + {"en", "hello %s", joe, "Hello Joe!"}, + {"en-US", "hello %s", joe, "Howdy Joe!"}, + {"en-GB", "hello %s", joe, "Hellø Joe!"}, + {"en-oxendict", "hello %s", joe, "Hello Joe!"}, + {"en-US-oxendict-u-ms-metric", "hello %s", joe, "Howdy Joe!"}, + + {"und", "greetings %s and %s", joeAndMary, "greetings Joe and Mary"}, + {"nl", "greetings %s and %s", joeAndMary, "greetings Joe and Mary"}, + {"en", "greetings %s and %s", joeAndMary, "Greetings Joe and Mary!"}, + {"en-US", "greetings %s and %s", joeAndMary, "Greetings Joe and Mary!"}, + {"en-GB", "greetings %s and %s", joeAndMary, "Greetings Joe and Mary!"}, + {"en-oxendict", "greetings %s and %s", joeAndMary, "Greetings Joe and Mary!"}, + {"en-US-oxendict-u-ms-metric", "greetings %s and %s", joeAndMary, "Greetings Joe and Mary!"}, + }, + }, { + desc: "references", + cat: []entry{ + {"en", "hello", "Hello!"}, + }, + test: []test{ + {"en", "hello", empty, "Hello!"}, + {"en", Key("hello", "fallback"), empty, "Hello!"}, + {"en", Key("xxx", "fallback"), empty, "fallback"}, + {"und", Key("hello", "fallback"), empty, "fallback"}, + }, + }, { + desc: "zero substitution", // work around limitation of fmt + cat: []entry{ + {"en", "hello %s", "Hello!"}, + {"en", "hi %s and %s", "Hello %[2]s!"}, + }, + test: []test{ + {"en", "hello %s", joe, "Hello!"}, + {"en", "hello %s", joeAndMary, "Hello!"}, + {"en", "hi %s and %s", joeAndMary, "Hello Mary!"}, + // The following tests resolve to the fallback string. + {"und", "hello", joeAndMary, "hello"}, + {"und", "hello %%%%", joeAndMary, "hello %%"}, + {"und", "hello %#%%4.2% ", joeAndMary, "hello %% "}, + {"und", "hello %s", joeAndMary, "hello Joe%!(EXTRA string=Mary)"}, + {"und", "hello %+%%s", joeAndMary, "hello %Joe%!(EXTRA string=Mary)"}, + {"und", "hello %-42%%s ", joeAndMary, "hello %Joe %!(EXTRA string=Mary)"}, + }, + }} + + for _, tc := range testCases { + cat, _ := initCat(tc.cat) + + for i, pt := range tc.test { + p := cat.Printer(language.MustParse(pt.tag)) + + if got := p.Sprintf(pt.key, pt.args...); got != pt.want { + t.Errorf("%s:%d:Sprintf(%s, %v) = %s; want %s", + tc.desc, i, pt.key, pt.args, got, pt.want) + continue // Next error will likely be the same. + } + + w := &bytes.Buffer{} + p.Fprintf(w, pt.key, pt.args...) + if got := w.String(); got != pt.want { + t.Errorf("%s:%d:Fprintf(%s, %v) = %s; want %s", + tc.desc, i, pt.key, pt.args, got, pt.want) + } + } + } +} -- cgit v1.2.3-1-g7c22