...

Source file src/golang.org/x/text/date/gen.go

Documentation: golang.org/x/text/date

     1  // Copyright 2017 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:build ignore
     6  
     7  package main
     8  
     9  import (
    10  	"flag"
    11  	"log"
    12  	"strconv"
    13  	"strings"
    14  
    15  	"golang.org/x/text/internal/cldrtree"
    16  	"golang.org/x/text/internal/gen"
    17  	"golang.org/x/text/language"
    18  	"golang.org/x/text/unicode/cldr"
    19  )
    20  
    21  var (
    22  	draft = flag.String("draft",
    23  		"contributed",
    24  		`Minimal draft requirements (approved, contributed, provisional, unconfirmed).`)
    25  )
    26  
    27  // TODO:
    28  // - Compile format patterns.
    29  // - Compress the large amount of redundancy in metazones.
    30  // - Split trees (with shared buckets) with data that is enough for default
    31  //   formatting of Go Time values and tables that are needed for larger
    32  //   variants.
    33  // - zone to metaZone mappings (in supplemental)
    34  // - Add more enum values and also some key maps for some of the elements.
    35  
    36  func main() {
    37  	gen.Init()
    38  
    39  	r := gen.OpenCLDRCoreZip()
    40  	defer r.Close()
    41  
    42  	d := &cldr.Decoder{}
    43  	d.SetDirFilter("supplemental", "main")
    44  	d.SetSectionFilter("dates")
    45  	data, err := d.DecodeZip(r)
    46  	if err != nil {
    47  		log.Fatalf("DecodeZip: %v", err)
    48  	}
    49  
    50  	dates := cldrtree.New("dates")
    51  	buildCLDRTree(data, dates)
    52  
    53  	w := gen.NewCodeWriter()
    54  	if err := dates.Gen(w); err != nil {
    55  		log.Fatal(err)
    56  	}
    57  	gen.WriteCLDRVersion(w)
    58  	w.WriteGoFile("tables.go", "date")
    59  
    60  	w = gen.NewCodeWriter()
    61  	if err := dates.GenTestData(w); err != nil {
    62  		log.Fatal(err)
    63  	}
    64  	w.WriteGoFile("data_test.go", "date")
    65  }
    66  
    67  func buildCLDRTree(data *cldr.CLDR, dates *cldrtree.Builder) {
    68  	context := cldrtree.Enum("context")
    69  	widthMap := func(s string) string {
    70  		// Align era with width values.
    71  		if r, ok := map[string]string{
    72  			"eraAbbr":   "abbreviated",
    73  			"eraNarrow": "narrow",
    74  			"eraNames":  "wide",
    75  		}[s]; ok {
    76  			s = r
    77  		}
    78  		// Prefix width to disambiguate with some overlapping length values.
    79  		return "width" + strings.Title(s)
    80  	}
    81  	width := cldrtree.EnumFunc("width", widthMap, "abbreviated", "narrow", "wide")
    82  	length := cldrtree.Enum("length", "short", "long")
    83  	month := cldrtree.Enum("month", "leap7")
    84  	relTime := cldrtree.EnumFunc("relTime", func(s string) string {
    85  		x, err := strconv.ParseInt(s, 10, 8)
    86  		if err != nil {
    87  			log.Fatal("Invalid number:", err)
    88  		}
    89  		return []string{
    90  			"before2",
    91  			"before1",
    92  			"current",
    93  			"after1",
    94  			"after2",
    95  			"after3",
    96  		}[x+2]
    97  	})
    98  	// Disambiguate keys like 'months' and 'sun'.
    99  	cycleType := cldrtree.EnumFunc("cycleType", func(s string) string {
   100  		return s + "CycleType"
   101  	})
   102  	field := cldrtree.EnumFunc("field", func(s string) string {
   103  		return s + "Field"
   104  	})
   105  	timeType := cldrtree.EnumFunc("timeType", func(s string) string {
   106  		if s == "" {
   107  			return "genericTime"
   108  		}
   109  		return s + "Time"
   110  	}, "generic")
   111  
   112  	zoneType := []cldrtree.Option{cldrtree.SharedType(), timeType}
   113  	metaZoneType := []cldrtree.Option{cldrtree.SharedType(), timeType}
   114  
   115  	for _, lang := range data.Locales() {
   116  		tag := language.Make(lang)
   117  		ldml := data.RawLDML(lang)
   118  		if ldml.Dates == nil {
   119  			continue
   120  		}
   121  		x := dates.Locale(tag)
   122  		if x := x.Index(ldml.Dates.Calendars); x != nil {
   123  			for _, cal := range ldml.Dates.Calendars.Calendar {
   124  				x := x.IndexFromType(cal)
   125  				if x := x.Index(cal.Months); x != nil {
   126  					for _, mc := range cal.Months.MonthContext {
   127  						x := x.IndexFromType(mc, context)
   128  						for _, mw := range mc.MonthWidth {
   129  							x := x.IndexFromType(mw, width)
   130  							for _, m := range mw.Month {
   131  								x.SetValue(m.Yeartype+m.Type, m, month)
   132  							}
   133  						}
   134  					}
   135  				}
   136  				if x := x.Index(cal.MonthPatterns); x != nil {
   137  					for _, mc := range cal.MonthPatterns.MonthPatternContext {
   138  						x := x.IndexFromType(mc, context)
   139  						for _, mw := range mc.MonthPatternWidth {
   140  							// Value is always leap, so no need to create a
   141  							// subindex.
   142  							for _, m := range mw.MonthPattern {
   143  								x.SetValue(mw.Type, m, width)
   144  							}
   145  						}
   146  					}
   147  				}
   148  				if x := x.Index(cal.CyclicNameSets); x != nil {
   149  					for _, cns := range cal.CyclicNameSets.CyclicNameSet {
   150  						x := x.IndexFromType(cns, cycleType)
   151  						for _, cc := range cns.CyclicNameContext {
   152  							x := x.IndexFromType(cc, context)
   153  							for _, cw := range cc.CyclicNameWidth {
   154  								x := x.IndexFromType(cw, width)
   155  								for _, c := range cw.CyclicName {
   156  									x.SetValue(c.Type, c)
   157  								}
   158  							}
   159  						}
   160  					}
   161  				}
   162  				if x := x.Index(cal.Days); x != nil {
   163  					for _, dc := range cal.Days.DayContext {
   164  						x := x.IndexFromType(dc, context)
   165  						for _, dw := range dc.DayWidth {
   166  							x := x.IndexFromType(dw, width)
   167  							for _, d := range dw.Day {
   168  								x.SetValue(d.Type, d)
   169  							}
   170  						}
   171  					}
   172  				}
   173  				if x := x.Index(cal.Quarters); x != nil {
   174  					for _, qc := range cal.Quarters.QuarterContext {
   175  						x := x.IndexFromType(qc, context)
   176  						for _, qw := range qc.QuarterWidth {
   177  							x := x.IndexFromType(qw, width)
   178  							for _, q := range qw.Quarter {
   179  								x.SetValue(q.Type, q)
   180  							}
   181  						}
   182  					}
   183  				}
   184  				if x := x.Index(cal.DayPeriods); x != nil {
   185  					for _, dc := range cal.DayPeriods.DayPeriodContext {
   186  						x := x.IndexFromType(dc, context)
   187  						for _, dw := range dc.DayPeriodWidth {
   188  							x := x.IndexFromType(dw, width)
   189  							for _, d := range dw.DayPeriod {
   190  								x.IndexFromType(d).SetValue(d.Alt, d)
   191  							}
   192  						}
   193  					}
   194  				}
   195  				if x := x.Index(cal.Eras); x != nil {
   196  					opts := []cldrtree.Option{width, cldrtree.SharedType()}
   197  					if x := x.Index(cal.Eras.EraNames, opts...); x != nil {
   198  						for _, e := range cal.Eras.EraNames.Era {
   199  							x.IndexFromAlt(e).SetValue(e.Type, e)
   200  						}
   201  					}
   202  					if x := x.Index(cal.Eras.EraAbbr, opts...); x != nil {
   203  						for _, e := range cal.Eras.EraAbbr.Era {
   204  							x.IndexFromAlt(e).SetValue(e.Type, e)
   205  						}
   206  					}
   207  					if x := x.Index(cal.Eras.EraNarrow, opts...); x != nil {
   208  						for _, e := range cal.Eras.EraNarrow.Era {
   209  							x.IndexFromAlt(e).SetValue(e.Type, e)
   210  						}
   211  					}
   212  				}
   213  				if x := x.Index(cal.DateFormats); x != nil {
   214  					for _, dfl := range cal.DateFormats.DateFormatLength {
   215  						x := x.IndexFromType(dfl, length)
   216  						for _, df := range dfl.DateFormat {
   217  							for _, p := range df.Pattern {
   218  								x.SetValue(p.Alt, p)
   219  							}
   220  						}
   221  					}
   222  				}
   223  				if x := x.Index(cal.TimeFormats); x != nil {
   224  					for _, tfl := range cal.TimeFormats.TimeFormatLength {
   225  						x := x.IndexFromType(tfl, length)
   226  						for _, tf := range tfl.TimeFormat {
   227  							for _, p := range tf.Pattern {
   228  								x.SetValue(p.Alt, p)
   229  							}
   230  						}
   231  					}
   232  				}
   233  				if x := x.Index(cal.DateTimeFormats); x != nil {
   234  					for _, dtfl := range cal.DateTimeFormats.DateTimeFormatLength {
   235  						x := x.IndexFromType(dtfl, length)
   236  						for _, dtf := range dtfl.DateTimeFormat {
   237  							for _, p := range dtf.Pattern {
   238  								x.SetValue(p.Alt, p)
   239  							}
   240  						}
   241  					}
   242  					// TODO:
   243  					// - appendItems
   244  					// - intervalFormats
   245  				}
   246  			}
   247  		}
   248  		// TODO: this is a lot of data and is probably relatively little used.
   249  		// Store this somewhere else.
   250  		if x := x.Index(ldml.Dates.Fields); x != nil {
   251  			for _, f := range ldml.Dates.Fields.Field {
   252  				x := x.IndexFromType(f, field)
   253  				for _, d := range f.DisplayName {
   254  					x.Index(d).SetValue(d.Alt, d)
   255  				}
   256  				for _, r := range f.Relative {
   257  					x.Index(r).SetValue(r.Type, r, relTime)
   258  				}
   259  				for _, rt := range f.RelativeTime {
   260  					x := x.Index(rt).IndexFromType(rt)
   261  					for _, p := range rt.RelativeTimePattern {
   262  						x.SetValue(p.Count, p)
   263  					}
   264  				}
   265  				for _, rp := range f.RelativePeriod {
   266  					x.Index(rp).SetValue(rp.Alt, rp)
   267  				}
   268  			}
   269  		}
   270  		if x := x.Index(ldml.Dates.TimeZoneNames); x != nil {
   271  			format := x.IndexWithName("zoneFormat")
   272  			for _, h := range ldml.Dates.TimeZoneNames.HourFormat {
   273  				format.SetValue(h.Element(), h)
   274  			}
   275  			for _, g := range ldml.Dates.TimeZoneNames.GmtFormat {
   276  				format.SetValue(g.Element(), g)
   277  			}
   278  			for _, g := range ldml.Dates.TimeZoneNames.GmtZeroFormat {
   279  				format.SetValue(g.Element(), g)
   280  			}
   281  			for _, r := range ldml.Dates.TimeZoneNames.RegionFormat {
   282  				x.Index(r).SetValue(r.Type, r, timeType)
   283  			}
   284  
   285  			set := func(x *cldrtree.Index, e []*cldr.Common, zone string) {
   286  				for _, n := range e {
   287  					x.Index(n, zoneType...).SetValue(zone, n)
   288  				}
   289  			}
   290  			zoneWidth := []cldrtree.Option{length, cldrtree.SharedType()}
   291  			zs := x.IndexWithName("zone")
   292  			for _, z := range ldml.Dates.TimeZoneNames.Zone {
   293  				for _, l := range z.Long {
   294  					x := zs.Index(l, zoneWidth...)
   295  					set(x, l.Generic, z.Type)
   296  					set(x, l.Standard, z.Type)
   297  					set(x, l.Daylight, z.Type)
   298  				}
   299  				for _, s := range z.Short {
   300  					x := zs.Index(s, zoneWidth...)
   301  					set(x, s.Generic, z.Type)
   302  					set(x, s.Standard, z.Type)
   303  					set(x, s.Daylight, z.Type)
   304  				}
   305  			}
   306  			set = func(x *cldrtree.Index, e []*cldr.Common, zone string) {
   307  				for _, n := range e {
   308  					x.Index(n, metaZoneType...).SetValue(zone, n)
   309  				}
   310  			}
   311  			zoneWidth = []cldrtree.Option{length, cldrtree.SharedType()}
   312  			zs = x.IndexWithName("metaZone")
   313  			for _, z := range ldml.Dates.TimeZoneNames.Metazone {
   314  				for _, l := range z.Long {
   315  					x := zs.Index(l, zoneWidth...)
   316  					set(x, l.Generic, z.Type)
   317  					set(x, l.Standard, z.Type)
   318  					set(x, l.Daylight, z.Type)
   319  				}
   320  				for _, s := range z.Short {
   321  					x := zs.Index(s, zoneWidth...)
   322  					set(x, s.Generic, z.Type)
   323  					set(x, s.Standard, z.Type)
   324  					set(x, s.Daylight, z.Type)
   325  				}
   326  			}
   327  		}
   328  	}
   329  }
   330  

View as plain text