barometer: update DMA's vendoring packages
[barometer.git] / src / dma / vendor / golang.org / x / text / internal / language / compact / language.go
diff --git a/src/dma/vendor/golang.org/x/text/internal/language/compact/language.go b/src/dma/vendor/golang.org/x/text/internal/language/compact/language.go
new file mode 100644 (file)
index 0000000..83816a7
--- /dev/null
@@ -0,0 +1,260 @@
+// Copyright 2013 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.
+
+//go:generate go run gen.go gen_index.go -output tables.go
+//go:generate go run gen_parents.go
+
+package compact
+
+// TODO: Remove above NOTE after:
+// - verifying that tables are dropped correctly (most notably matcher tables).
+
+import (
+       "strings"
+
+       "golang.org/x/text/internal/language"
+)
+
+// Tag represents a BCP 47 language tag. It is used to specify an instance of a
+// specific language or locale. All language tag values are guaranteed to be
+// well-formed.
+type Tag struct {
+       // NOTE: exported tags will become part of the public API.
+       language ID
+       locale   ID
+       full     fullTag // always a language.Tag for now.
+}
+
+const _und = 0
+
+type fullTag interface {
+       IsRoot() bool
+       Parent() language.Tag
+}
+
+// Make a compact Tag from a fully specified internal language Tag.
+func Make(t language.Tag) (tag Tag) {
+       if region := t.TypeForKey("rg"); len(region) == 6 && region[2:] == "zzzz" {
+               if r, err := language.ParseRegion(region[:2]); err == nil {
+                       tFull := t
+                       t, _ = t.SetTypeForKey("rg", "")
+                       // TODO: should we not consider "va" for the language tag?
+                       var exact1, exact2 bool
+                       tag.language, exact1 = FromTag(t)
+                       t.RegionID = r
+                       tag.locale, exact2 = FromTag(t)
+                       if !exact1 || !exact2 {
+                               tag.full = tFull
+                       }
+                       return tag
+               }
+       }
+       lang, ok := FromTag(t)
+       tag.language = lang
+       tag.locale = lang
+       if !ok {
+               tag.full = t
+       }
+       return tag
+}
+
+// Tag returns an internal language Tag version of this tag.
+func (t Tag) Tag() language.Tag {
+       if t.full != nil {
+               return t.full.(language.Tag)
+       }
+       tag := t.language.Tag()
+       if t.language != t.locale {
+               loc := t.locale.Tag()
+               tag, _ = tag.SetTypeForKey("rg", strings.ToLower(loc.RegionID.String())+"zzzz")
+       }
+       return tag
+}
+
+// IsCompact reports whether this tag is fully defined in terms of ID.
+func (t *Tag) IsCompact() bool {
+       return t.full == nil
+}
+
+// MayHaveVariants reports whether a tag may have variants. If it returns false
+// it is guaranteed the tag does not have variants.
+func (t Tag) MayHaveVariants() bool {
+       return t.full != nil || int(t.language) >= len(coreTags)
+}
+
+// MayHaveExtensions reports whether a tag may have extensions. If it returns
+// false it is guaranteed the tag does not have them.
+func (t Tag) MayHaveExtensions() bool {
+       return t.full != nil ||
+               int(t.language) >= len(coreTags) ||
+               t.language != t.locale
+}
+
+// IsRoot returns true if t is equal to language "und".
+func (t Tag) IsRoot() bool {
+       if t.full != nil {
+               return t.full.IsRoot()
+       }
+       return t.language == _und
+}
+
+// Parent returns the CLDR parent of t. In CLDR, missing fields in data for a
+// specific language are substituted with fields from the parent language.
+// The parent for a language may change for newer versions of CLDR.
+func (t Tag) Parent() Tag {
+       if t.full != nil {
+               return Make(t.full.Parent())
+       }
+       if t.language != t.locale {
+               // Simulate stripping -u-rg-xxxxxx
+               return Tag{language: t.language, locale: t.language}
+       }
+       // TODO: use parent lookup table once cycle from internal package is
+       // removed. Probably by internalizing the table and declaring this fast
+       // enough.
+       // lang := compactID(internal.Parent(uint16(t.language)))
+       lang, _ := FromTag(t.language.Tag().Parent())
+       return Tag{language: lang, locale: lang}
+}
+
+// returns token t and the rest of the string.
+func nextToken(s string) (t, tail string) {
+       p := strings.Index(s[1:], "-")
+       if p == -1 {
+               return s[1:], ""
+       }
+       p++
+       return s[1:p], s[p:]
+}
+
+// LanguageID returns an index, where 0 <= index < NumCompactTags, for tags
+// for which data exists in the text repository.The index will change over time
+// and should not be stored in persistent storage. If t does not match a compact
+// index, exact will be false and the compact index will be returned for the
+// first match after repeatedly taking the Parent of t.
+func LanguageID(t Tag) (id ID, exact bool) {
+       return t.language, t.full == nil
+}
+
+// RegionalID returns the ID for the regional variant of this tag. This index is
+// used to indicate region-specific overrides, such as default currency, default
+// calendar and week data, default time cycle, and default measurement system
+// and unit preferences.
+//
+// For instance, the tag en-GB-u-rg-uszzzz specifies British English with US
+// settings for currency, number formatting, etc. The CompactIndex for this tag
+// will be that for en-GB, while the RegionalID will be the one corresponding to
+// en-US.
+func RegionalID(t Tag) (id ID, exact bool) {
+       return t.locale, t.full == nil
+}
+
+// LanguageTag returns t stripped of regional variant indicators.
+//
+// At the moment this means it is stripped of a regional and variant subtag "rg"
+// and "va" in the "u" extension.
+func (t Tag) LanguageTag() Tag {
+       if t.full == nil {
+               return Tag{language: t.language, locale: t.language}
+       }
+       tt := t.Tag()
+       tt.SetTypeForKey("rg", "")
+       tt.SetTypeForKey("va", "")
+       return Make(tt)
+}
+
+// RegionalTag returns the regional variant of the tag.
+//
+// At the moment this means that the region is set from the regional subtag
+// "rg" in the "u" extension.
+func (t Tag) RegionalTag() Tag {
+       rt := Tag{language: t.locale, locale: t.locale}
+       if t.full == nil {
+               return rt
+       }
+       b := language.Builder{}
+       tag := t.Tag()
+       // tag, _ = tag.SetTypeForKey("rg", "")
+       b.SetTag(t.locale.Tag())
+       if v := tag.Variants(); v != "" {
+               for _, v := range strings.Split(v, "-") {
+                       b.AddVariant(v)
+               }
+       }
+       for _, e := range tag.Extensions() {
+               b.AddExt(e)
+       }
+       return t
+}
+
+// FromTag reports closest matching ID for an internal language Tag.
+func FromTag(t language.Tag) (id ID, exact bool) {
+       // TODO: perhaps give more frequent tags a lower index.
+       // TODO: we could make the indexes stable. This will excluded some
+       //       possibilities for optimization, so don't do this quite yet.
+       exact = true
+
+       b, s, r := t.Raw()
+       if t.HasString() {
+               if t.IsPrivateUse() {
+                       // We have no entries for user-defined tags.
+                       return 0, false
+               }
+               hasExtra := false
+               if t.HasVariants() {
+                       if t.HasExtensions() {
+                               build := language.Builder{}
+                               build.SetTag(language.Tag{LangID: b, ScriptID: s, RegionID: r})
+                               build.AddVariant(t.Variants())
+                               exact = false
+                               t = build.Make()
+                       }
+                       hasExtra = true
+               } else if _, ok := t.Extension('u'); ok {
+                       // TODO: va may mean something else. Consider not considering it.
+                       // Strip all but the 'va' entry.
+                       old := t
+                       variant := t.TypeForKey("va")
+                       t = language.Tag{LangID: b, ScriptID: s, RegionID: r}
+                       if variant != "" {
+                               t, _ = t.SetTypeForKey("va", variant)
+                               hasExtra = true
+                       }
+                       exact = old == t
+               } else {
+                       exact = false
+               }
+               if hasExtra {
+                       // We have some variants.
+                       for i, s := range specialTags {
+                               if s == t {
+                                       return ID(i + len(coreTags)), exact
+                               }
+                       }
+                       exact = false
+               }
+       }
+       if x, ok := getCoreIndex(t); ok {
+               return x, exact
+       }
+       exact = false
+       if r != 0 && s == 0 {
+               // Deal with cases where an extra script is inserted for the region.
+               t, _ := t.Maximize()
+               if x, ok := getCoreIndex(t); ok {
+                       return x, exact
+               }
+       }
+       for t = t.Parent(); t != root; t = t.Parent() {
+               // No variants specified: just compare core components.
+               // The key has the form lllssrrr, where l, s, and r are nibbles for
+               // respectively the langID, scriptID, and regionID.
+               if x, ok := getCoreIndex(t); ok {
+                       return x, exact
+               }
+       }
+       return 0, exact
+}
+
+var root = language.Tag{}