// 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.gopackage compact// TODO: Remove above NOTE after:// - verifying that tables are dropped correctly (most notably matcher tables).import ()// 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.typeTagstruct {// NOTE: exported tags will become part of the public API. language ID locale ID full fullTag// always a language.Tag for now.}const _und = 0type fullTag interface { IsRoot() bool Parent() language.Tag}// Make a compact Tag from a fully specified internal language Tag.func ( language.Tag) ( Tag) {if := .TypeForKey("rg"); len() == 6 && [2:] == "zzzz" {if , := language.ParseRegion([:2]); == nil { := , _ = .SetTypeForKey("rg", "")// TODO: should we not consider "va" for the language tag?var , bool .language, = FromTag() .RegionID = .locale, = FromTag()if ! || ! { .full = }return } } , := FromTag() .language = .locale = if ! { .full = }return}// Tag returns an internal language Tag version of this tag.func ( Tag) () language.Tag {if .full != nil {return .full.(language.Tag) } := .language.Tag()if .language != .locale { := .locale.Tag() , _ = .SetTypeForKey("rg", strings.ToLower(.RegionID.String())+"zzzz") }return}// IsCompact reports whether this tag is fully defined in terms of ID.func ( *Tag) () bool {return .full == nil}// MayHaveVariants reports whether a tag may have variants. If it returns false// it is guaranteed the tag does not have variants.func ( Tag) () bool {return .full != nil || int(.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 ( Tag) () bool {return .full != nil ||int(.language) >= len(coreTags) || .language != .locale}// IsRoot returns true if t is equal to language "und".func ( Tag) () bool {if .full != nil {return .full.IsRoot() }return .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 ( Tag) () Tag {if .full != nil {returnMake(.full.Parent()) }if .language != .locale {// Simulate stripping -u-rg-xxxxxxreturnTag{language: .language, locale: .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))) , := FromTag(.language.Tag().Parent())returnTag{language: , locale: }}// nextToken returns token t and the rest of the string.func nextToken( string) (, string) { := strings.Index([1:], "-")if == -1 {return [1:], "" } ++return [1:], [:]}// 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 ( Tag) ( ID, bool) {return .language, .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 ( Tag) ( ID, bool) {return .locale, .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 ( Tag) () Tag {if .full == nil {returnTag{language: .language, locale: .language} } := .Tag() .SetTypeForKey("rg", "") .SetTypeForKey("va", "")returnMake()}// 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 ( Tag) () Tag { := Tag{language: .locale, locale: .locale}if .full == nil {return } := language.Builder{} := .Tag()// tag, _ = tag.SetTypeForKey("rg", "") .SetTag(.locale.Tag())if := .Variants(); != "" {for , := rangestrings.Split(, "-") { .AddVariant() } }for , := range .Extensions() { .AddExt() }return}// FromTag reports closest matching ID for an internal language Tag.func ( language.Tag) ( ID, 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. = true , , := .Raw()if .HasString() {if .IsPrivateUse() {// We have no entries for user-defined tags.return0, false } := falseif .HasVariants() {if .HasExtensions() { := language.Builder{} .SetTag(language.Tag{LangID: , ScriptID: , RegionID: }) .AddVariant(.Variants()) = false = .Make() } = true } elseif , := .Extension('u'); {// TODO: va may mean something else. Consider not considering it. // Strip all but the 'va' entry. := := .TypeForKey("va") = language.Tag{LangID: , ScriptID: , RegionID: }if != "" { , _ = .SetTypeForKey("va", ) = true } = == } else { = false }if {// We have some variants.for , := rangespecialTags {if == {returnID( + len(coreTags)), } } = false } }if , := getCoreIndex(); {return , } = falseif != 0 && == 0 {// Deal with cases where an extra script is inserted for the region. , := .Maximize()if , := getCoreIndex(); {return , } }for = .Parent(); != root; = .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 , := getCoreIndex(); {return , } }return0, }var root = language.Tag{}
The pages are generated with Goldsv0.6.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.