// 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.

// +build ignore

// Language tag table generator.
// Data read from the web.

package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"math"
	"reflect"
	"regexp"
	"sort"
	"strconv"
	"strings"

	"golang.org/x/text/cldr"
	"golang.org/x/text/internal/gen"
	"golang.org/x/text/internal/tag"
)

var (
	test = flag.Bool("test",
		false,
		"test existing tables; can be used to compare web data with package data.")
	outputFile = flag.String("output",
		"tables.go",
		"output file for generated tables")
)

var comment = []string{
	`
lang holds an alphabetically sorted list of ISO-639 language identifiers.
All entries are 4 bytes. The index of the identifier (divided by 4) is the language tag.
For 2-byte language identifiers, the two successive bytes have the following meaning:
    - if the first letter of the 2- and 3-letter ISO codes are the same:
      the second and third letter of the 3-letter ISO code.
    - otherwise: a 0 and a by 2 bits right-shifted index into altLangISO3.
For 3-byte language identifiers the 4th byte is 0.`,
	`
langNoIndex is a bit vector of all 3-letter language codes that are not used as an index
in lookup tables. The language ids for these language codes are derived directly
from the letters and are not consecutive.`,
	`
altLangISO3 holds an alphabetically sorted list of 3-letter language code alternatives
to 2-letter language codes that cannot be derived using the method described above.
Each 3-letter code is followed by its 1-byte langID.`,
	`
altLangIndex is used to convert indexes in altLangISO3 to langIDs.`,
	`
langAliasMap maps langIDs to their suggested replacements.`,
	`
script is an alphabetically sorted list of ISO 15924 codes. The index
of the script in the string, divided by 4, is the internal scriptID.`,
	`
isoRegionOffset needs to be added to the index of regionISO to obtain the regionID
for 2-letter ISO codes. (The first isoRegionOffset regionIDs are reserved for
the UN.M49 codes used for groups.)`,
	`
regionISO holds a list of alphabetically sorted 2-letter ISO region codes.
Each 2-letter codes is followed by two bytes with the following meaning:
    - [A-Z}{2}: the first letter of the 2-letter code plus these two 
                letters form the 3-letter ISO code.
    - 0, n:     index into altRegionISO3.`,
	`
regionTypes defines the status of a region for various standards.`,
	`
m49 maps regionIDs to UN.M49 codes. The first isoRegionOffset entries are
codes indicating collections of regions.`,
	`
m49Index gives indexes into fromM49 based on the three most significant bits
of a 10-bit UN.M49 code. To search an UN.M49 code in fromM49, search in
   fromM49[m49Index[msb39(code)]:m49Index[msb3(code)+1]]
for an entry where the first 7 bits match the 7 lsb of the UN.M49 code.
The region code is stored in the 9 lsb of the indexed value.`,
	`
fromM49 contains entries to map UN.M49 codes to regions. See m49Index for details.`,
	`
altRegionISO3 holds a list of 3-letter region codes that cannot be
mapped to 2-letter codes using the default algorithm. This is a short list.`,
	`
altRegionIDs holds a list of regionIDs the positions of which match those
of the 3-letter ISO codes in altRegionISO3.`,
	`
variantNumSpecialized is the number of specialized variants in variants.`,
	`
suppressScript is an index from langID to the dominant script for that language,
if it exists.  If a script is given, it should be suppressed from the language tag.`,
	`
likelyLang is a lookup table, indexed by langID, for the most likely
scripts and regions given incomplete information. If more entries exist for a
given language, region and script are the index and size respectively
of the list in likelyLangList.`,
	`
likelyLangList holds lists info associated with likelyLang.`,
	`
likelyRegion is a lookup table, indexed by regionID, for the most likely
languages and scripts given incomplete information. If more entries exist
for a given regionID, lang and script are the index and size respectively
of the list in likelyRegionList.
TODO: exclude containers and user-definable regions from the list.`,
	`
likelyRegionList holds lists info associated with likelyRegion.`,
	`
likelyScript is a lookup table, indexed by scriptID, for the most likely
languages and regions given a script.`,
	`
matchLang holds pairs of langIDs of base languages that are typically
mutually intelligible. Each pair is associated with a confidence and
whether the intelligibility goes one or both ways.`,
	`
matchScript holds pairs of scriptIDs where readers of one script
can typically also read the other. Each is associated with a confidence.`,
	`
nRegionGroups is the number of region groups.`,
	`
regionInclusion maps region identifiers to sets of regions in regionInclusionBits,
where each set holds all groupings that are directly connected in a region
containment graph.`,
	`
regionInclusionBits is an array of bit vectors where every vector represents
a set of region groupings.  These sets are used to compute the distance
between two regions for the purpose of language matching.`,
	`
regionInclusionNext marks, for each entry in regionInclusionBits, the set of
all groups that are reachable from the groups set in the respective entry.`,
}

// TODO: consider changing some of these structures to tries. This can reduce
// memory, but may increase the need for memory allocations. This could be
// mitigated if we can piggyback on language tags for common cases.

func failOnError(e error) {
	if e != nil {
		log.Panic(e)
	}
}

type setType int

const (
	Indexed setType = 1 + iota // all elements must be of same size
	Linear
)

type stringSet struct {
	s              []string
	sorted, frozen bool

	// We often need to update values after the creation of an index is completed.
	// We include a convenience map for keeping track of this.
	update map[string]string
	typ    setType // used for checking.
}

func (ss *stringSet) clone() stringSet {
	c := *ss
	c.s = append([]string(nil), c.s...)
	return c
}

func (ss *stringSet) setType(t setType) {
	if ss.typ != t && ss.typ != 0 {
		log.Panicf("type %d cannot be assigned as it was already %d", t, ss.typ)
	}
}

// parse parses a whitespace-separated string and initializes ss with its
// components.
func (ss *stringSet) parse(s string) {
	scan := bufio.NewScanner(strings.NewReader(s))
	scan.Split(bufio.ScanWords)
	for scan.Scan() {
		ss.add(scan.Text())
	}
}

func (ss *stringSet) assertChangeable() {
	if ss.frozen {
		log.Panic("attempt to modify a frozen stringSet")
	}
}

func (ss *stringSet) add(s string) {
	ss.assertChangeable()
	ss.s = append(ss.s, s)
	ss.sorted = ss.frozen
}

func (ss *stringSet) freeze() {
	ss.compact()
	ss.frozen = true
}

func (ss *stringSet) compact() {
	if ss.sorted {
		return
	}
	a := ss.s
	sort.Strings(a)
	k := 0
	for i := 1; i < len(a); i++ {
		if a[k] != a[i] {
			a[k+1] = a[i]
			k++
		}
	}
	ss.s = a[:k+1]
	ss.sorted = ss.frozen
}

type funcSorter struct {
	fn func(a, b string) bool
	sort.StringSlice
}

func (s funcSorter) Less(i, j int) bool {
	return s.fn(s.StringSlice[i], s.StringSlice[j])
}

func (ss *stringSet) sortFunc(f func(a, b string) bool) {
	ss.compact()
	sort.Sort(funcSorter{f, sort.StringSlice(ss.s)})
}

func (ss *stringSet) remove(s string) {
	ss.assertChangeable()
	if i, ok := ss.find(s); ok {
		copy(ss.s[i:], ss.s[i+1:])
		ss.s = ss.s[:len(ss.s)-1]
	}
}

func (ss *stringSet) replace(ol, nu string) {
	ss.s[ss.index(ol)] = nu
	ss.sorted = ss.frozen
}

func (ss *stringSet) index(s string) int {
	ss.setType(Indexed)
	i, ok := ss.find(s)
	if !ok {
		if i < len(ss.s) {
			log.Panicf("find: item %q is not in list. Closest match is %q.", s, ss.s[i])
		}
		log.Panicf("find: item %q is not in list", s)

	}
	return i
}

func (ss *stringSet) find(s string) (int, bool) {
	ss.compact()
	i := sort.SearchStrings(ss.s, s)
	return i, i != len(ss.s) && ss.s[i] == s
}

func (ss *stringSet) slice() []string {
	ss.compact()
	return ss.s
}

func (ss *stringSet) updateLater(v, key string) {
	if ss.update == nil {
		ss.update = map[string]string{}
	}
	ss.update[v] = key
}

// join joins the string and ensures that all entries are of the same length.
func (ss *stringSet) join() string {
	ss.setType(Indexed)
	n := len(ss.s[0])
	for _, s := range ss.s {
		if len(s) != n {
			log.Panicf("join: not all entries are of the same length: %q", s)
		}
	}
	ss.s = append(ss.s, strings.Repeat("\xff", n))
	return strings.Join(ss.s, "")
}

// ianaEntry holds information for an entry in the IANA Language Subtag Repository.
// All types use the same entry.
// See http://tools.ietf.org/html/bcp47#section-5.1 for a description of the various
// fields.
type ianaEntry struct {
	typ            string
	description    []string
	scope          string
	added          string
	preferred      string
	deprecated     string
	suppressScript string
	macro          string
	prefix         []string
}

type builder struct {
	w    *gen.CodeWriter
	hw   io.Writer // MultiWriter for w and w.Hash
	data *cldr.CLDR
	supp *cldr.SupplementalData

	// indices
	locale      stringSet // common locales
	lang        stringSet // canonical language ids (2 or 3 letter ISO codes) with data
	langNoIndex stringSet // 3-letter ISO codes with no associated data
	script      stringSet // 4-letter ISO codes
	region      stringSet // 2-letter ISO or 3-digit UN M49 codes
	variant     stringSet // 4-8-alphanumeric variant code.

	// Region codes that are groups with their corresponding group IDs.
	groups map[int]index

	// langInfo
	registry map[string]*ianaEntry
}

type index uint

func newBuilder(w *gen.CodeWriter) *builder {
	r := gen.OpenCLDRCoreZip()
	defer r.Close()
	d := &cldr.Decoder{}
	data, err := d.DecodeZip(r)
	failOnError(err)
	b := builder{
		w:    w,
		hw:   io.MultiWriter(w, w.Hash),
		data: data,
		supp: data.Supplemental(),
	}
	b.parseRegistry()
	return &b
}

func (b *builder) parseRegistry() {
	r := gen.OpenIANAFile("assignments/language-subtag-registry")
	defer r.Close()
	b.registry = make(map[string]*ianaEntry)

	scan := bufio.NewScanner(r)
	scan.Split(bufio.ScanWords)
	var record *ianaEntry
	for more := scan.Scan(); more; {
		key := scan.Text()
		more = scan.Scan()
		value := scan.Text()
		switch key {
		case "Type:":
			record = &ianaEntry{typ: value}
		case "Subtag:", "Tag:":
			if s := strings.SplitN(value, "..", 2); len(s) > 1 {
				for a := s[0]; a <= s[1]; a = inc(a) {
					b.addToRegistry(a, record)
				}
			} else {
				b.addToRegistry(value, record)
			}
		case "Suppress-Script:":
			record.suppressScript = value
		case "Added:":
			record.added = value
		case "Deprecated:":
			record.deprecated = value
		case "Macrolanguage:":
			record.macro = value
		case "Preferred-Value:":
			record.preferred = value
		case "Prefix:":
			record.prefix = append(record.prefix, value)
		case "Scope:":
			record.scope = value
		case "Description:":
			buf := []byte(value)
			for more = scan.Scan(); more; more = scan.Scan() {
				b := scan.Bytes()
				if b[0] == '%' || b[len(b)-1] == ':' {
					break
				}
				buf = append(buf, ' ')
				buf = append(buf, b...)
			}
			record.description = append(record.description, string(buf))
			continue
		default:
			continue
		}
		more = scan.Scan()
	}
	if scan.Err() != nil {
		log.Panic(scan.Err())
	}
}

func (b *builder) addToRegistry(key string, entry *ianaEntry) {
	if info, ok := b.registry[key]; ok {
		if info.typ != "language" || entry.typ != "extlang" {
			log.Fatalf("parseRegistry: tag %q already exists", key)
		}
	} else {
		b.registry[key] = entry
	}
}

var commentIndex = make(map[string]string)

func init() {
	for _, s := range comment {
		key := strings.TrimSpace(strings.SplitN(s, " ", 2)[0])
		commentIndex[key] = s
	}
}

func (b *builder) comment(name string) {
	if s := commentIndex[name]; len(s) > 0 {
		b.w.WriteComment(s)
	} else {
		fmt.Fprintln(b.w)
	}
}

func (b *builder) pf(f string, x ...interface{}) {
	fmt.Fprintf(b.hw, f, x...)
	fmt.Fprint(b.hw, "\n")
}

func (b *builder) p(x ...interface{}) {
	fmt.Fprintln(b.hw, x...)
}

func (b *builder) addSize(s int) {
	b.w.Size += s
	b.pf("// Size: %d bytes", s)
}

func (b *builder) writeConst(name string, x interface{}) {
	b.comment(name)
	b.w.WriteConst(name, x)
}

// writeConsts computes f(v) for all v in values and writes the results
// as constants named _v to a single constant block.
func (b *builder) writeConsts(f func(string) int, values ...string) {
	b.pf("const (")
	for _, v := range values {
		b.pf("\t_%s = %v", v, f(v))
	}
	b.pf(")")
}

// writeType writes the type of the given value, which must be a struct.
func (b *builder) writeType(value interface{}) {
	b.comment(reflect.TypeOf(value).Name())
	b.w.WriteType(value)
}

func (b *builder) writeSlice(name string, ss interface{}) {
	b.writeSliceAddSize(name, 0, ss)
}

func (b *builder) writeSliceAddSize(name string, extraSize int, ss interface{}) {
	b.comment(name)
	b.w.Size += extraSize
	v := reflect.ValueOf(ss)
	t := v.Type().Elem()
	b.pf("// Size: %d bytes, %d elements", v.Len()*int(t.Size())+extraSize, v.Len())

	fmt.Fprintf(b.w, "var %s = ", name)
	b.w.WriteArray(ss)
	b.p()
}

type fromTo struct {
	from, to uint16
}

func (b *builder) writeSortedMap(name string, ss *stringSet, index func(s string) uint16) {
	ss.sortFunc(func(a, b string) bool {
		return index(a) < index(b)
	})
	m := []fromTo{}
	for _, s := range ss.s {
		m = append(m, fromTo{index(s), index(ss.update[s])})
	}
	b.writeSlice(name, m)
}

const base = 'z' - 'a' + 1

func strToInt(s string) uint {
	v := uint(0)
	for i := 0; i < len(s); i++ {
		v *= base
		v += uint(s[i] - 'a')
	}
	return v
}

// converts the given integer to the original ASCII string passed to strToInt.
// len(s) must match the number of characters obtained.
func intToStr(v uint, s []byte) {
	for i := len(s) - 1; i >= 0; i-- {
		s[i] = byte(v%base) + 'a'
		v /= base
	}
}

func (b *builder) writeBitVector(name string, ss []string) {
	vec := make([]uint8, int(math.Ceil(math.Pow(base, float64(len(ss[0])))/8)))
	for _, s := range ss {
		v := strToInt(s)
		vec[v/8] |= 1 << (v % 8)
	}
	b.writeSlice(name, vec)
}

// TODO: convert this type into a list or two-stage trie.
func (b *builder) writeMapFunc(name string, m map[string]string, f func(string) uint16) {
	b.comment(name)
	v := reflect.ValueOf(m)
	sz := v.Len() * (2 + int(v.Type().Key().Size()))
	for _, k := range m {
		sz += len(k)
	}
	b.addSize(sz)
	keys := []string{}
	b.pf(`var %s = map[string]uint16{`, name)
	for k := range m {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		b.pf("\t%q: %v,", k, f(m[k]))
	}
	b.p("}")
}

func (b *builder) writeMap(name string, m interface{}) {
	b.comment(name)
	v := reflect.ValueOf(m)
	sz := v.Len() * (2 + int(v.Type().Key().Size()) + int(v.Type().Elem().Size()))
	b.addSize(sz)
	f := strings.FieldsFunc(fmt.Sprintf("%#v", m), func(r rune) bool {
		return strings.IndexRune("{}, ", r) != -1
	})
	sort.Strings(f[1:])
	b.pf(`var %s = %s{`, name, f[0])
	for _, kv := range f[1:] {
		b.pf("\t%s,", kv)
	}
	b.p("}")
}

func (b *builder) langIndex(s string) uint16 {
	if s == "und" {
		return 0
	}
	if i, ok := b.lang.find(s); ok {
		return uint16(i)
	}
	return uint16(strToInt(s)) + uint16(len(b.lang.s))
}

// inc advances the string to its lexicographical successor.
func inc(s string) string {
	const maxTagLength = 4
	var buf [maxTagLength]byte
	intToStr(strToInt(strings.ToLower(s))+1, buf[:len(s)])
	for i := 0; i < len(s); i++ {
		if s[i] <= 'Z' {
			buf[i] -= 'a' - 'A'
		}
	}
	return string(buf[:len(s)])
}

func (b *builder) parseIndices() {
	meta := b.supp.Metadata

	for k, v := range b.registry {
		var ss *stringSet
		switch v.typ {
		case "language":
			if len(k) == 2 || v.suppressScript != "" || v.scope == "special" {
				b.lang.add(k)
				continue
			} else {
				ss = &b.langNoIndex
			}
		case "region":
			ss = &b.region
		case "script":
			ss = &b.script
		case "variant":
			ss = &b.variant
		default:
			continue
		}
		ss.add(k)
	}
	// Include any language for which there is data.
	for _, lang := range b.data.Locales() {
		if x := b.data.RawLDML(lang); false ||
			x.LocaleDisplayNames != nil ||
			x.Characters != nil ||
			x.Delimiters != nil ||
			x.Measurement != nil ||
			x.Dates != nil ||
			x.Numbers != nil ||
			x.Units != nil ||
			x.ListPatterns != nil ||
			x.Collations != nil ||
			x.Segmentations != nil ||
			x.Rbnf != nil ||
			x.Annotations != nil ||
			x.Metadata != nil {

			from := strings.Split(lang, "_")
			if lang := from[0]; lang != "root" {
				b.lang.add(lang)
			}
		}
	}
	// Include languages in likely subtags.
	for _, m := range b.supp.LikelySubtags.LikelySubtag {
		from := strings.Split(m.From, "_")
		b.lang.add(from[0])
	}
	// Include ISO-639 alpha-3 bibliographic entries.
	for _, a := range meta.Alias.LanguageAlias {
		if a.Reason == "bibliographic" {
			b.langNoIndex.add(a.Type)
		}
	}
	// Include regions in territoryAlias (not all are in the IANA registry!)
	for _, reg := range b.supp.Metadata.Alias.TerritoryAlias {
		if len(reg.Type) == 2 {
			b.region.add(reg.Type)
		}
	}

	for _, s := range b.lang.s {
		if len(s) == 3 {
			b.langNoIndex.remove(s)
		}
	}
	b.writeConst("numLanguages", len(b.lang.slice())+len(b.langNoIndex.slice()))
	b.writeConst("numScripts", len(b.script.slice()))
	b.writeConst("numRegions", len(b.region.slice()))

	// Add dummy codes at the start of each list to represent "unspecified".
	b.lang.add("---")
	b.script.add("----")
	b.region.add("---")

	// common locales
	b.locale.parse(meta.DefaultContent.Locales)
}

func (b *builder) computeRegionGroups() {
	b.groups = make(map[int]index)

	// Create group indices.
	for i := 1; b.region.s[i][0] < 'A'; i++ { // Base M49 indices on regionID.
		b.groups[i] = index(len(b.groups))
	}
	for _, g := range b.supp.TerritoryContainment.Group {
		group := b.region.index(g.Type)
		if _, ok := b.groups[group]; !ok {
			b.groups[group] = index(len(b.groups))
		}
	}
	if len(b.groups) > 32 {
		log.Fatalf("only 32 groups supported, found %d", len(b.groups))
	}
	b.writeConst("nRegionGroups", len(b.groups))
}

var langConsts = []string{
	"af", "am", "ar", "az", "bg", "bn", "ca", "cs", "da", "de", "el", "en", "es",
	"et", "fa", "fi", "fil", "fr", "gu", "he", "hi", "hr", "hu", "hy", "id", "is",
	"it", "ja", "ka", "kk", "km", "kn", "ko", "ky", "lo", "lt", "lv", "mk", "ml",
	"mn", "mo", "mr", "ms", "mul", "my", "nb", "ne", "nl", "no", "pa", "pl", "pt",
	"ro", "ru", "sh", "si", "sk", "sl", "sq", "sr", "sv", "sw", "ta", "te", "th",
	"tl", "tn", "tr", "uk", "ur", "uz", "vi", "zh", "zu",

	// constants for grandfathered tags (if not already defined)
	"jbo", "ami", "bnn", "hak", "tlh", "lb", "nv", "pwn", "tao", "tay", "tsu",
	"nn", "sfb", "vgt", "sgg", "cmn", "nan", "hsn",
}

// writeLanguage generates all tables needed for language canonicalization.
func (b *builder) writeLanguage() {
	meta := b.supp.Metadata

	b.writeConst("nonCanonicalUnd", b.lang.index("und"))
	b.writeConsts(func(s string) int { return int(b.langIndex(s)) }, langConsts...)
	b.writeConst("langPrivateStart", b.langIndex("qaa"))
	b.writeConst("langPrivateEnd", b.langIndex("qtz"))

	// Get language codes that need to be mapped (overlong 3-letter codes,
	// deprecated 2-letter codes, legacy and grandfathered tags.)
	langAliasMap := stringSet{}
	aliasTypeMap := map[string]langAliasType{}

	// altLangISO3 get the alternative ISO3 names that need to be mapped.
	altLangISO3 := stringSet{}
	// Add dummy start to avoid the use of index 0.
	altLangISO3.add("---")
	altLangISO3.updateLater("---", "aa")

	lang := b.lang.clone()
	for _, a := range meta.Alias.LanguageAlias {
		if a.Replacement == "" {
			a.Replacement = "und"
		}
		// TODO: support mapping to tags
		repl := strings.SplitN(a.Replacement, "_", 2)[0]
		if a.Reason == "overlong" {
			if len(a.Replacement) == 2 && len(a.Type) == 3 {
				lang.updateLater(a.Replacement, a.Type)
			}
		} else if len(a.Type) <= 3 {
			switch a.Reason {
			case "macrolanguage":
				aliasTypeMap[a.Type] = langMacro
			case "deprecated":
				// handled elsewhere
				continue
			case "bibliographic", "legacy":
				if a.Type == "no" {
					continue
				}
				aliasTypeMap[a.Type] = langLegacy
			default:
				log.Fatalf("new %s alias: %s", a.Reason, a.Type)
			}
			langAliasMap.add(a.Type)
			langAliasMap.updateLater(a.Type, repl)
		}
	}
	// Manually add the mapping of "nb" (Norwegian) to its macro language.
	// This can be removed if CLDR adopts this change.
	langAliasMap.add("nb")
	langAliasMap.updateLater("nb", "no")
	aliasTypeMap["nb"] = langMacro

	for k, v := range b.registry {
		// Also add deprecated values for 3-letter ISO codes, which CLDR omits.
		if v.typ == "language" && v.deprecated != "" && v.preferred != "" {
			langAliasMap.add(k)
			langAliasMap.updateLater(k, v.preferred)
			aliasTypeMap[k] = langDeprecated
		}
	}
	// Fix CLDR mappings.
	lang.updateLater("tl", "tgl")
	lang.updateLater("sh", "hbs")
	lang.updateLater("mo", "mol")
	lang.updateLater("no", "nor")
	lang.updateLater("tw", "twi")
	lang.updateLater("nb", "nob")
	lang.updateLater("ak", "aka")

	// Ensure that each 2-letter code is matched with a 3-letter code.
	for _, v := range lang.s[1:] {
		s, ok := lang.update[v]
		if !ok {
			if s, ok = lang.update[langAliasMap.update[v]]; !ok {
				continue
			}
			lang.update[v] = s
		}
		if v[0] != s[0] {
			altLangISO3.add(s)
			altLangISO3.updateLater(s, v)
		}
	}

	// Complete canonialized language tags.
	lang.freeze()
	for i, v := range lang.s {
		// We can avoid these manual entries by using the IANI registry directly.
		// Seems easier to update the list manually, as changes are rare.
		// The panic in this loop will trigger if we miss an entry.
		add := ""
		if s, ok := lang.update[v]; ok {
			if s[0] == v[0] {
				add = s[1:]
			} else {
				add = string([]byte{0, byte(altLangISO3.index(s))})
			}
		} else if len(v) == 3 {
			add = "\x00"
		} else {
			log.Panicf("no data for long form of %q", v)
		}
		lang.s[i] += add
	}
	b.writeConst("lang", tag.Index(lang.join()))

	b.writeConst("langNoIndexOffset", len(b.lang.s))

	// space of all valid 3-letter language identifiers.
	b.writeBitVector("langNoIndex", b.langNoIndex.slice())

	altLangIndex := []uint16{}
	for i, s := range altLangISO3.slice() {
		altLangISO3.s[i] += string([]byte{byte(len(altLangIndex))})
		if i > 0 {
			idx := b.lang.index(altLangISO3.update[s])
			altLangIndex = append(altLangIndex, uint16(idx))
		}
	}
	b.writeConst("altLangISO3", tag.Index(altLangISO3.join()))
	b.writeSlice("altLangIndex", altLangIndex)

	b.writeSortedMap("langAliasMap", &langAliasMap, b.langIndex)
	types := make([]langAliasType, len(langAliasMap.s))
	for i, s := range langAliasMap.s {
		types[i] = aliasTypeMap[s]
	}
	b.writeSlice("langAliasTypes", types)
}

var scriptConsts = []string{
	"Latn", "Hani", "Hans", "Hant", "Qaaa", "Qaai", "Qabx", "Zinh", "Zyyy",
	"Zzzz",
}

func (b *builder) writeScript() {
	b.writeConsts(b.script.index, scriptConsts...)
	b.writeConst("script", tag.Index(b.script.join()))

	supp := make([]uint8, len(b.lang.slice()))
	for i, v := range b.lang.slice()[1:] {
		if sc := b.registry[v].suppressScript; sc != "" {
			supp[i+1] = uint8(b.script.index(sc))
		}
	}
	b.writeSlice("suppressScript", supp)

	// There is only one deprecated script in CLDR. This value is hard-coded.
	// We check here if the code must be updated.
	for _, a := range b.supp.Metadata.Alias.ScriptAlias {
		if a.Type != "Qaai" {
			log.Panicf("unexpected deprecated stript %q", a.Type)
		}
	}
}

func parseM49(s string) int16 {
	if len(s) == 0 {
		return 0
	}
	v, err := strconv.ParseUint(s, 10, 10)
	failOnError(err)
	return int16(v)
}

var regionConsts = []string{
	"001", "419", "BR", "CA", "ES", "GB", "MD", "PT", "UK", "US",
	"ZZ", "XA", "XC", "XK", // Unofficial tag for Kosovo.
}

func (b *builder) writeRegion() {
	b.writeConsts(b.region.index, regionConsts...)

	isoOffset := b.region.index("AA")
	m49map := make([]int16, len(b.region.slice()))
	fromM49map := make(map[int16]int)
	altRegionISO3 := ""
	altRegionIDs := []uint16{}

	b.writeConst("isoRegionOffset", isoOffset)

	// 2-letter region lookup and mapping to numeric codes.
	regionISO := b.region.clone()
	regionISO.s = regionISO.s[isoOffset:]
	regionISO.sorted = false

	regionTypes := make([]byte, len(b.region.s))

	// Is the region valid BCP 47?
	for s, e := range b.registry {
		if len(s) == 2 && s == strings.ToUpper(s) {
			i := b.region.index(s)
			for _, d := range e.description {
				if strings.Contains(d, "Private use") {
					regionTypes[i] = iso3166UserAssgined
				}
			}
			regionTypes[i] |= bcp47Region
		}
	}

	// Is the region a valid ccTLD?
	r := gen.OpenIANAFile("domains/root/db")
	defer r.Close()

	buf, err := ioutil.ReadAll(r)
	failOnError(err)
	re := regexp.MustCompile(`"/domains/root/db/([a-z]{2}).html"`)
	for _, m := range re.FindAllSubmatch(buf, -1) {
		i := b.region.index(strings.ToUpper(string(m[1])))
		regionTypes[i] |= ccTLD
	}

	b.writeSlice("regionTypes", regionTypes)

	iso3Set := make(map[string]int)
	update := func(iso2, iso3 string) {
		i := regionISO.index(iso2)
		if j, ok := iso3Set[iso3]; !ok && iso3[0] == iso2[0] {
			regionISO.s[i] += iso3[1:]
			iso3Set[iso3] = -1
		} else {
			if ok && j >= 0 {
				regionISO.s[i] += string([]byte{0, byte(j)})
			} else {
				iso3Set[iso3] = len(altRegionISO3)
				regionISO.s[i] += string([]byte{0, byte(len(altRegionISO3))})
				altRegionISO3 += iso3
				altRegionIDs = append(altRegionIDs, uint16(isoOffset+i))
			}
		}
	}
	for _, tc := range b.supp.CodeMappings.TerritoryCodes {
		i := regionISO.index(tc.Type) + isoOffset
		if d := m49map[i]; d != 0 {
			log.Panicf("%s found as a duplicate UN.M49 code of %03d", tc.Numeric, d)
		}
		m49 := parseM49(tc.Numeric)
		m49map[i] = m49
		if r := fromM49map[m49]; r == 0 {
			fromM49map[m49] = i
		} else if r != i {
			dep := b.registry[regionISO.s[r-isoOffset]].deprecated
			if t := b.registry[tc.Type]; t != nil && dep != "" && (t.deprecated == "" || t.deprecated > dep) {
				fromM49map[m49] = i
			}
		}
	}
	for _, ta := range b.supp.Metadata.Alias.TerritoryAlias {
		if len(ta.Type) == 3 && ta.Type[0] <= '9' && len(ta.Replacement) == 2 {
			from := parseM49(ta.Type)
			if r := fromM49map[from]; r == 0 {
				fromM49map[from] = regionISO.index(ta.Replacement) + isoOffset
			}
		}
	}
	for _, tc := range b.supp.CodeMappings.TerritoryCodes {
		if len(tc.Alpha3) == 3 {
			update(tc.Type, tc.Alpha3)
		}
	}
	// This entries are not included in territoryCodes. Mostly 3-letter variants
	// of deleted codes and an entry for QU.
	for _, m := range []struct{ iso2, iso3 string }{
		{"CT", "CTE"},
		{"DY", "DHY"},
		{"HV", "HVO"},
		{"JT", "JTN"},
		{"MI", "MID"},
		{"NH", "NHB"},
		{"NQ", "ATN"},
		{"PC", "PCI"},
		{"PU", "PUS"},
		{"PZ", "PCZ"},
		{"RH", "RHO"},
		{"VD", "VDR"},
		{"WK", "WAK"},
		// These three-letter codes are used for others as well.
		{"FQ", "ATF"},
	} {
		update(m.iso2, m.iso3)
	}
	for i, s := range regionISO.s {
		if len(s) != 4 {
			regionISO.s[i] = s + "  "
		}
	}
	b.writeConst("regionISO", tag.Index(regionISO.join()))
	b.writeConst("altRegionISO3", altRegionISO3)
	b.writeSlice("altRegionIDs", altRegionIDs)

	// Create list of deprecated regions.
	// TODO: consider inserting SF -> FI. Not included by CLDR, but is the only
	// Transitionally-reserved mapping not included.
	regionOldMap := stringSet{}
	// Include regions in territoryAlias (not all are in the IANA registry!)
	for _, reg := range b.supp.Metadata.Alias.TerritoryAlias {
		if len(reg.Type) == 2 && reg.Reason == "deprecated" && len(reg.Replacement) == 2 {
			regionOldMap.add(reg.Type)
			regionOldMap.updateLater(reg.Type, reg.Replacement)
			i, _ := regionISO.find(reg.Type)
			j, _ := regionISO.find(reg.Replacement)
			if k := m49map[i+isoOffset]; k == 0 {
				m49map[i+isoOffset] = m49map[j+isoOffset]
			}
		}
	}
	b.writeSortedMap("regionOldMap", &regionOldMap, func(s string) uint16 {
		return uint16(b.region.index(s))
	})
	// 3-digit region lookup, groupings.
	for i := 1; i < isoOffset; i++ {
		m := parseM49(b.region.s[i])
		m49map[i] = m
		fromM49map[m] = i
	}
	b.writeSlice("m49", m49map)

	const (
		searchBits = 7
		regionBits = 9
	)
	if len(m49map) >= 1<<regionBits {
		log.Fatalf("Maximum number of regions exceeded: %d > %d", len(m49map), 1<<regionBits)
	}
	m49Index := [9]int16{}
	fromM49 := []uint16{}
	m49 := []int{}
	for k, _ := range fromM49map {
		m49 = append(m49, int(k))
	}
	sort.Ints(m49)
	for _, k := range m49[1:] {
		val := (k & (1<<searchBits - 1)) << regionBits
		fromM49 = append(fromM49, uint16(val|fromM49map[int16(k)]))
		m49Index[1:][k>>searchBits] = int16(len(fromM49))
	}
	b.writeSlice("m49Index", m49Index)
	b.writeSlice("fromM49", fromM49)
}

const (
	// TODO: put these lists in regionTypes as user data? Could be used for
	// various optimizations and refinements and could be exposed in the API.
	iso3166Except = "AC CP DG EA EU FX IC SU TA UK"
	iso3166Trans  = "AN BU CS NT TP YU ZR" // SF is not in our set of Regions.
	// DY and RH are actually not deleted, but indeterminately reserved.
	iso3166DelCLDR = "CT DD DY FQ HV JT MI NH NQ PC PU PZ RH VD WK YD"
)

const (
	iso3166UserAssgined = 1 << iota
	ccTLD
	bcp47Region
)

func find(list []string, s string) int {
	for i, t := range list {
		if t == s {
			return i
		}
	}
	return -1
}

// writeVariants generates per-variant information and creates a map from variant
// name to index value. We assign index values such that sorting multiple
// variants by index value will result in the correct order.
// There are two types of variants: specialized and general. Specialized variants
// are only applicable to certain language or language-script pairs. Generalized
// variants apply to any language. Generalized variants always sort after
// specialized variants.  We will therefore always assign a higher index value
// to a generalized variant than any other variant. Generalized variants are
// sorted alphabetically among themselves.
// Specialized variants may also sort after other specialized variants. Such
// variants will be ordered after any of the variants they may follow.
// We assume that if a variant x is followed by a variant y, then for any prefix
// p of x, p-x is a prefix of y. This allows us to order tags based on the
// maximum of the length of any of its prefixes.
// TODO: it is possible to define a set of Prefix values on variants such that
// a total order cannot be defined to the point that this algorithm breaks.
// In other words, we cannot guarantee the same order of variants for the
// future using the same algorithm or for non-compliant combinations of
// variants. For this reason, consider using simple alphabetic sorting
// of variants and ignore Prefix restrictions altogether.
func (b *builder) writeVariant() {
	generalized := stringSet{}
	specialized := stringSet{}
	specializedExtend := stringSet{}
	// Collate the variants by type and check assumptions.
	for _, v := range b.variant.slice() {
		e := b.registry[v]
		if len(e.prefix) == 0 {
			generalized.add(v)
			continue
		}
		c := strings.Split(e.prefix[0], "-")
		hasScriptOrRegion := false
		if len(c) > 1 {
			_, hasScriptOrRegion = b.script.find(c[1])
			if !hasScriptOrRegion {
				_, hasScriptOrRegion = b.region.find(c[1])

			}
		}
		if len(c) == 1 || len(c) == 2 && hasScriptOrRegion {
			// Variant is preceded by a language.
			specialized.add(v)
			continue
		}
		// Variant is preceded by another variant.
		specializedExtend.add(v)
		prefix := c[0] + "-"
		if hasScriptOrRegion {
			prefix += c[1]
		}
		for _, p := range e.prefix {
			// Verify that the prefix minus the last element is a prefix of the
			// predecessor element.
			i := strings.LastIndex(p, "-")
			pred := b.registry[p[i+1:]]
			if find(pred.prefix, p[:i]) < 0 {
				log.Fatalf("prefix %q for variant %q not consistent with predecessor spec", p, v)
			}
			// The sorting used below does not work in the general case. It works
			// if we assume that variants that may be followed by others only have
			// prefixes of the same length. Verify this.
			count := strings.Count(p[:i], "-")
			for _, q := range pred.prefix {
				if c := strings.Count(q, "-"); c != count {
					log.Fatalf("variant %q preceding %q has a prefix %q of size %d; want %d", p[i+1:], v, q, c, count)
				}
			}
			if !strings.HasPrefix(p, prefix) {
				log.Fatalf("prefix %q of variant %q should start with %q", p, v, prefix)
			}
		}
	}

	// Sort extended variants.
	a := specializedExtend.s
	less := func(v, w string) bool {
		// Sort by the maximum number of elements.
		maxCount := func(s string) (max int) {
			for _, p := range b.registry[s].prefix {
				if c := strings.Count(p, "-"); c > max {
					max = c
				}
			}
			return
		}
		if cv, cw := maxCount(v), maxCount(w); cv != cw {
			return cv < cw
		}
		// Sort by name as tie breaker.
		return v < w
	}
	sort.Sort(funcSorter{less, sort.StringSlice(a)})
	specializedExtend.frozen = true

	// Create index from variant name to index.
	variantIndex := make(map[string]uint8)
	add := func(s []string) {
		for _, v := range s {
			variantIndex[v] = uint8(len(variantIndex))
		}
	}
	add(specialized.slice())
	add(specializedExtend.s)
	numSpecialized := len(variantIndex)
	add(generalized.slice())
	if n := len(variantIndex); n > 255 {
		log.Fatalf("maximum number of variants exceeded: was %d; want <= 255", n)
	}
	b.writeMap("variantIndex", variantIndex)
	b.writeConst("variantNumSpecialized", numSpecialized)
}

func (b *builder) writeLanguageInfo() {
}

// writeLikelyData writes tables that are used both for finding parent relations and for
// language matching.  Each entry contains additional bits to indicate the status of the
// data to know when it cannot be used for parent relations.
func (b *builder) writeLikelyData() {
	const (
		isList = 1 << iota
		scriptInFrom
		regionInFrom
	)
	type ( // generated types
		likelyScriptRegion struct {
			region uint16
			script uint8
			flags  uint8
		}
		likelyLangScript struct {
			lang   uint16
			script uint8
			flags  uint8
		}
		likelyLangRegion struct {
			lang   uint16
			region uint16
		}
		// likelyTag is used for getting likely tags for group regions, where
		// the likely region might be a region contained in the group.
		likelyTag struct {
			lang   uint16
			region uint16
			script uint8
		}
	)
	var ( // generated variables
		likelyRegionGroup = make([]likelyTag, len(b.groups))
		likelyLang        = make([]likelyScriptRegion, len(b.lang.s))
		likelyRegion      = make([]likelyLangScript, len(b.region.s))
		likelyScript      = make([]likelyLangRegion, len(b.script.s))
		likelyLangList    = []likelyScriptRegion{}
		likelyRegionList  = []likelyLangScript{}
	)
	type fromTo struct {
		from, to []string
	}
	langToOther := map[int][]fromTo{}
	regionToOther := map[int][]fromTo{}
	for _, m := range b.supp.LikelySubtags.LikelySubtag {
		from := strings.Split(m.From, "_")
		to := strings.Split(m.To, "_")
		if len(to) != 3 {
			log.Fatalf("invalid number of subtags in %q: found %d, want 3", m.To, len(to))
		}
		if len(from) > 3 {
			log.Fatalf("invalid number of subtags: found %d, want 1-3", len(from))
		}
		if from[0] != to[0] && from[0] != "und" {
			log.Fatalf("unexpected language change in expansion: %s -> %s", from, to)
		}
		if len(from) == 3 {
			if from[2] != to[2] {
				log.Fatalf("unexpected region change in expansion: %s -> %s", from, to)
			}
			if from[0] != "und" {
				log.Fatalf("unexpected fully specified from tag: %s -> %s", from, to)
			}
		}
		if len(from) == 1 || from[0] != "und" {
			id := 0
			if from[0] != "und" {
				id = b.lang.index(from[0])
			}
			langToOther[id] = append(langToOther[id], fromTo{from, to})
		} else if len(from) == 2 && len(from[1]) == 4 {
			sid := b.script.index(from[1])
			likelyScript[sid].lang = uint16(b.langIndex(to[0]))
			likelyScript[sid].region = uint16(b.region.index(to[2]))
		} else {
			r := b.region.index(from[len(from)-1])
			if id, ok := b.groups[r]; ok {
				if from[0] != "und" {
					log.Fatalf("region changed unexpectedly: %s -> %s", from, to)
				}
				likelyRegionGroup[id].lang = uint16(b.langIndex(to[0]))
				likelyRegionGroup[id].script = uint8(b.script.index(to[1]))
				likelyRegionGroup[id].region = uint16(b.region.index(to[2]))
			} else {
				regionToOther[r] = append(regionToOther[r], fromTo{from, to})
			}
		}
	}
	b.writeType(likelyLangRegion{})
	b.writeSlice("likelyScript", likelyScript)

	for id := range b.lang.s {
		list := langToOther[id]
		if len(list) == 1 {
			likelyLang[id].region = uint16(b.region.index(list[0].to[2]))
			likelyLang[id].script = uint8(b.script.index(list[0].to[1]))
		} else if len(list) > 1 {
			likelyLang[id].flags = isList
			likelyLang[id].region = uint16(len(likelyLangList))
			likelyLang[id].script = uint8(len(list))
			for _, x := range list {
				flags := uint8(0)
				if len(x.from) > 1 {
					if x.from[1] == x.to[2] {
						flags = regionInFrom
					} else {
						flags = scriptInFrom
					}
				}
				likelyLangList = append(likelyLangList, likelyScriptRegion{
					region: uint16(b.region.index(x.to[2])),
					script: uint8(b.script.index(x.to[1])),
					flags:  flags,
				})
			}
		}
	}
	// TODO: merge suppressScript data with this table.
	b.writeType(likelyScriptRegion{})
	b.writeSlice("likelyLang", likelyLang)
	b.writeSlice("likelyLangList", likelyLangList)

	for id := range b.region.s {
		list := regionToOther[id]
		if len(list) == 1 {
			likelyRegion[id].lang = uint16(b.langIndex(list[0].to[0]))
			likelyRegion[id].script = uint8(b.script.index(list[0].to[1]))
			if len(list[0].from) > 2 {
				likelyRegion[id].flags = scriptInFrom
			}
		} else if len(list) > 1 {
			likelyRegion[id].flags = isList
			likelyRegion[id].lang = uint16(len(likelyRegionList))
			likelyRegion[id].script = uint8(len(list))
			for i, x := range list {
				if len(x.from) == 2 && i != 0 || i > 0 && len(x.from) != 3 {
					log.Fatalf("unspecified script must be first in list: %v at %d", x.from, i)
				}
				x := likelyLangScript{
					lang:   uint16(b.langIndex(x.to[0])),
					script: uint8(b.script.index(x.to[1])),
				}
				if len(list[0].from) > 2 {
					x.flags = scriptInFrom
				}
				likelyRegionList = append(likelyRegionList, x)
			}
		}
	}
	b.writeType(likelyLangScript{})
	b.writeSlice("likelyRegion", likelyRegion)
	b.writeSlice("likelyRegionList", likelyRegionList)

	b.writeType(likelyTag{})
	b.writeSlice("likelyRegionGroup", likelyRegionGroup)
}

type mutualIntelligibility struct {
	want, have uint16
	conf       uint8
	oneway     bool
}

type scriptIntelligibility struct {
	lang       uint16 // langID or 0 if *
	want, have uint8
	conf       uint8
}

type sortByConf []mutualIntelligibility

func (l sortByConf) Less(a, b int) bool {
	return l[a].conf > l[b].conf
}

func (l sortByConf) Swap(a, b int) {
	l[a], l[b] = l[b], l[a]
}

func (l sortByConf) Len() int {
	return len(l)
}

// toConf converts a percentage value [0, 100] to a confidence class.
func toConf(pct uint8) uint8 {
	switch {
	case pct == 100:
		return 3 // Exact
	case pct >= 90:
		return 2 // High
	case pct > 50:
		return 1 // Low
	default:
		return 0 // No
	}
}

// writeMatchData writes tables with languages and scripts for which there is
// mutual intelligibility. The data is based on CLDR's languageMatching data.
// Note that we use a different algorithm than the one defined by CLDR and that
// we slightly modify the data. For example, we convert scores to confidence levels.
// We also drop all region-related data as we use a different algorithm to
// determine region equivalence.
func (b *builder) writeMatchData() {
	b.writeType(mutualIntelligibility{})
	b.writeType(scriptIntelligibility{})
	lm := b.supp.LanguageMatching.LanguageMatches
	cldr.MakeSlice(&lm).SelectAnyOf("type", "written")

	matchLang := []mutualIntelligibility{}
	matchScript := []scriptIntelligibility{}
	// Convert the languageMatch entries in lists keyed by desired language.
	for _, m := range lm[0].LanguageMatch {
		// Different versions of CLDR use different separators.
		desired := strings.Replace(m.Desired, "-", "_", -1)
		supported := strings.Replace(m.Supported, "-", "_", -1)
		d := strings.Split(desired, "_")
		s := strings.Split(supported, "_")
		if len(d) != len(s) || len(d) > 2 {
			// Skip all entries with regions and work around CLDR bug.
			continue
		}
		pct, _ := strconv.ParseInt(m.Percent, 10, 8)
		if len(d) == 2 && d[0] == s[0] && len(d[1]) == 4 {
			// language-script pair.
			lang := uint16(0)
			if d[0] != "*" {
				lang = uint16(b.langIndex(d[0]))
			}
			matchScript = append(matchScript, scriptIntelligibility{
				lang: lang,
				want: uint8(b.script.index(d[1])),
				have: uint8(b.script.index(s[1])),
				conf: toConf(uint8(pct)),
			})
			if m.Oneway != "true" {
				matchScript = append(matchScript, scriptIntelligibility{
					lang: lang,
					want: uint8(b.script.index(s[1])),
					have: uint8(b.script.index(d[1])),
					conf: toConf(uint8(pct)),
				})
			}
		} else if len(d) == 1 && d[0] != "*" {
			if pct == 100 {
				// nb == no is already handled by macro mapping. Check there
				// really is only this case.
				if d[0] != "no" || s[0] != "nb" {
					log.Fatalf("unhandled equivalence %s == %s", s[0], d[0])
				}
				continue
			}
			matchLang = append(matchLang, mutualIntelligibility{
				want:   uint16(b.langIndex(d[0])),
				have:   uint16(b.langIndex(s[0])),
				conf:   uint8(pct),
				oneway: m.Oneway == "true",
			})
		} else {
			// TODO: Handle the es_MX -> es_419 mapping. This does not seem to
			// make much sense for our purposes, though.
			a := []string{"*;*", "*_*;*_*", "es_MX;es_419"}
			s := strings.Join([]string{desired, supported}, ";")
			if i := sort.SearchStrings(a, s); i == len(a) || a[i] != s {
				log.Fatalf("%q not handled", s)
			}
		}
	}
	sort.Sort(sortByConf(matchLang))
	// collapse percentage into confidence classes
	for i, m := range matchLang {
		matchLang[i].conf = toConf(m.conf)
	}
	b.writeSlice("matchLang", matchLang)
	b.writeSlice("matchScript", matchScript)
}

func (b *builder) writeRegionInclusionData() {
	var (
		// mm holds for each group the set of groups with a distance of 1.
		mm = make(map[int][]index)

		// containment holds for each group the transitive closure of
		// containment of other groups.
		containment = make(map[index][]index)
	)
	for _, g := range b.supp.TerritoryContainment.Group {
		group := b.region.index(g.Type)
		groupIdx := b.groups[group]
		for _, mem := range strings.Split(g.Contains, " ") {
			r := b.region.index(mem)
			mm[r] = append(mm[r], groupIdx)
			if g, ok := b.groups[r]; ok {
				mm[group] = append(mm[group], g)
				containment[groupIdx] = append(containment[groupIdx], g)
			}
		}
	}

	regionContainment := make([]uint32, len(b.groups))
	for _, g := range b.groups {
		l := containment[g]

		// Compute the transitive closure of containment.
		for i := 0; i < len(l); i++ {
			l = append(l, containment[l[i]]...)
		}

		// Compute the bitmask.
		regionContainment[g] = 1 << g
		for _, v := range l {
			regionContainment[g] |= 1 << v
		}
		// log.Printf("%d: %X", g, regionContainment[g])
	}
	b.writeSlice("regionContainment", regionContainment)

	regionInclusion := make([]uint8, len(b.region.s))
	bvs := make(map[uint32]index)
	// Make the first bitvector positions correspond with the groups.
	for r, i := range b.groups {
		bv := uint32(1 << i)
		for _, g := range mm[r] {
			bv |= 1 << g
		}
		bvs[bv] = i
		regionInclusion[r] = uint8(bvs[bv])
	}
	for r := 1; r < len(b.region.s); r++ {
		if _, ok := b.groups[r]; !ok {
			bv := uint32(0)
			for _, g := range mm[r] {
				bv |= 1 << g
			}
			if bv == 0 {
				// Pick the world for unspecified regions.
				bv = 1 << b.groups[b.region.index("001")]
			}
			if _, ok := bvs[bv]; !ok {
				bvs[bv] = index(len(bvs))
			}
			regionInclusion[r] = uint8(bvs[bv])
		}
	}
	b.writeSlice("regionInclusion", regionInclusion)
	regionInclusionBits := make([]uint32, len(bvs))
	for k, v := range bvs {
		regionInclusionBits[v] = uint32(k)
	}
	// Add bit vectors for increasingly large distances until a fixed point is reached.
	regionInclusionNext := []uint8{}
	for i := 0; i < len(regionInclusionBits); i++ {
		bits := regionInclusionBits[i]
		next := bits
		for i := uint(0); i < uint(len(b.groups)); i++ {
			if bits&(1<<i) != 0 {
				next |= regionInclusionBits[i]
			}
		}
		if _, ok := bvs[next]; !ok {
			bvs[next] = index(len(bvs))
			regionInclusionBits = append(regionInclusionBits, next)
		}
		regionInclusionNext = append(regionInclusionNext, uint8(bvs[next]))
	}
	b.writeSlice("regionInclusionBits", regionInclusionBits)
	b.writeSlice("regionInclusionNext", regionInclusionNext)
}

type parentRel struct {
	lang       uint16
	script     uint8
	maxScript  uint8
	toRegion   uint16
	fromRegion []uint16
}

func (b *builder) writeParents() {
	b.writeType(parentRel{})

	parents := []parentRel{}

	// Construct parent overrides.
	n := 0
	for _, p := range b.data.Supplemental().ParentLocales.ParentLocale {
		// Skipping non-standard scripts to root is implemented using addTags.
		if p.Parent == "root" {
			continue
		}

		sub := strings.Split(p.Parent, "_")
		parent := parentRel{lang: b.langIndex(sub[0])}
		if len(sub) == 2 {
			// TODO: check that all undefined scripts are indeed Latn in these
			// cases.
			parent.maxScript = uint8(b.script.index("Latn"))
			parent.toRegion = uint16(b.region.index(sub[1]))
		} else {
			parent.script = uint8(b.script.index(sub[1]))
			parent.maxScript = parent.script
			parent.toRegion = uint16(b.region.index(sub[2]))
		}
		for _, c := range strings.Split(p.Locales, " ") {
			region := b.region.index(c[strings.LastIndex(c, "_")+1:])
			parent.fromRegion = append(parent.fromRegion, uint16(region))
		}
		parents = append(parents, parent)
		n += len(parent.fromRegion)
	}
	b.writeSliceAddSize("parents", n*2, parents)
}

func main() {
	gen.Init()

	gen.Repackage("gen_common.go", "common.go", "language")

	w := gen.NewCodeWriter()
	defer w.WriteGoFile("tables.go", "language")

	fmt.Fprintln(w, `import "golang.org/x/text/internal/tag"`)

	b := newBuilder(w)
	gen.WriteCLDRVersion(w)

	b.parseIndices()
	b.writeType(fromTo{})
	b.writeLanguage()
	b.writeScript()
	b.writeRegion()
	b.writeVariant()
	// TODO: b.writeLocale()
	b.computeRegionGroups()
	b.writeLikelyData()
	b.writeMatchData()
	b.writeRegionInclusionData()
	b.writeParents()
}
