1// Copyright 2013 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//go:generate go run makexml.go -output xml.go
6
7// Package cldr provides a parser for LDML and related XML formats.
8//
9// This package is intended to be used by the table generation tools for the
10// various packages in x/text and is not internal for historical reasons.
11//
12// As the XML types are generated from the CLDR DTD, and as the CLDR standard is
13// periodically amended, this package may change considerably over time. This
14// mostly means that data may appear and disappear between versions. That is,
15// old code should keep compiling for newer versions, but data may have moved or
16// changed. CLDR version 22 is the first version supported by this package.
17// Older versions may not work.
18package cldr // import "golang.org/x/text/unicode/cldr"
19
20import (
21	"fmt"
22	"sort"
23)
24
25// CLDR provides access to parsed data of the Unicode Common Locale Data Repository.
26type CLDR struct {
27	parent   map[string][]string
28	locale   map[string]*LDML
29	resolved map[string]*LDML
30	bcp47    *LDMLBCP47
31	supp     *SupplementalData
32}
33
34func makeCLDR() *CLDR {
35	return &CLDR{
36		parent:   make(map[string][]string),
37		locale:   make(map[string]*LDML),
38		resolved: make(map[string]*LDML),
39		bcp47:    &LDMLBCP47{},
40		supp:     &SupplementalData{},
41	}
42}
43
44// BCP47 returns the parsed BCP47 LDML data. If no such data was parsed, nil is returned.
45func (cldr *CLDR) BCP47() *LDMLBCP47 {
46	return nil
47}
48
49// Draft indicates the draft level of an element.
50type Draft int
51
52const (
53	Approved Draft = iota
54	Contributed
55	Provisional
56	Unconfirmed
57)
58
59var drafts = []string{"unconfirmed", "provisional", "contributed", "approved", ""}
60
61// ParseDraft returns the Draft value corresponding to the given string. The
62// empty string corresponds to Approved.
63func ParseDraft(level string) (Draft, error) {
64	if level == "" {
65		return Approved, nil
66	}
67	for i, s := range drafts {
68		if level == s {
69			return Unconfirmed - Draft(i), nil
70		}
71	}
72	return Approved, fmt.Errorf("cldr: unknown draft level %q", level)
73}
74
75func (d Draft) String() string {
76	return drafts[len(drafts)-1-int(d)]
77}
78
79// SetDraftLevel sets which draft levels to include in the evaluated LDML.
80// Any draft element for which the draft level is higher than lev will be excluded.
81// If multiple draft levels are available for a single element, the one with the
82// lowest draft level will be selected, unless preferDraft is true, in which case
83// the highest draft will be chosen.
84// It is assumed that the underlying LDML is canonicalized.
85func (cldr *CLDR) SetDraftLevel(lev Draft, preferDraft bool) {
86	// TODO: implement
87	cldr.resolved = make(map[string]*LDML)
88}
89
90// RawLDML returns the LDML XML for id in unresolved form.
91// id must be one of the strings returned by Locales.
92func (cldr *CLDR) RawLDML(loc string) *LDML {
93	return cldr.locale[loc]
94}
95
96// LDML returns the fully resolved LDML XML for loc, which must be one of
97// the strings returned by Locales.
98//
99// Deprecated: Use RawLDML and implement inheritance manually or using the
100// internal cldrtree package.
101// Inheritance has changed quite a bit since the onset of this package and in
102// practice data often represented in a way where knowledge of how it was
103// inherited is relevant.
104func (cldr *CLDR) LDML(loc string) (*LDML, error) {
105	return cldr.resolve(loc)
106}
107
108// Supplemental returns the parsed supplemental data. If no such data was parsed,
109// nil is returned.
110func (cldr *CLDR) Supplemental() *SupplementalData {
111	return cldr.supp
112}
113
114// Locales returns the locales for which there exist files.
115// Valid sublocales for which there is no file are not included.
116// The root locale is always sorted first.
117func (cldr *CLDR) Locales() []string {
118	loc := []string{"root"}
119	hasRoot := false
120	for l, _ := range cldr.locale {
121		if l == "root" {
122			hasRoot = true
123			continue
124		}
125		loc = append(loc, l)
126	}
127	sort.Strings(loc[1:])
128	if !hasRoot {
129		return loc[1:]
130	}
131	return loc
132}
133
134// Get fills in the fields of x based on the XPath path.
135func Get(e Elem, path string) (res Elem, err error) {
136	return walkXPath(e, path)
137}
138