in message/pipeline/generate.go [89:202]
func (s *State) generate() (*gen.CodeWriter, error) {
// Build up index of translations and original messages.
translations := map[language.Tag]map[string]Message{}
languages := []language.Tag{}
usedKeys := map[string]int{}
for _, loc := range s.Messages {
tag := loc.Language
if _, ok := translations[tag]; !ok {
translations[tag] = map[string]Message{}
languages = append(languages, tag)
}
for _, m := range loc.Messages {
if !m.Translation.IsEmpty() {
for _, id := range m.ID {
if _, ok := translations[tag][id]; ok {
warnf("Duplicate translation in locale %q for message %q", tag, id)
}
translations[tag][id] = m
}
}
}
}
// Verify completeness and register keys.
internal.SortTags(languages)
langVars := []string{}
for _, tag := range languages {
langVars = append(langVars, strings.Replace(tag.String(), "-", "_", -1))
dict := translations[tag]
for _, msg := range s.Extracted.Messages {
for _, id := range msg.ID {
if trans, ok := dict[id]; ok && !trans.Translation.IsEmpty() {
if _, ok := usedKeys[msg.Key]; !ok {
usedKeys[msg.Key] = len(usedKeys)
}
break
}
// TODO: log missing entry.
warnf("%s: Missing entry for %q.", tag, id)
}
}
}
cw := gen.NewCodeWriter()
x := &struct {
Fallback language.Tag
Languages []string
}{
Fallback: s.Extracted.Language,
Languages: langVars,
}
if err := lookup.Execute(cw, x); err != nil {
return nil, wrap(err, "error")
}
keyToIndex := []string{}
for k := range usedKeys {
keyToIndex = append(keyToIndex, k)
}
sort.Strings(keyToIndex)
fmt.Fprint(cw, "var messageKeyToIndex = map[string]int{\n")
for _, k := range keyToIndex {
fmt.Fprintf(cw, "%q: %d,\n", k, usedKeys[k])
}
fmt.Fprint(cw, "}\n\n")
for i, tag := range languages {
dict := translations[tag]
a := make([]string, len(usedKeys))
for _, msg := range s.Extracted.Messages {
for _, id := range msg.ID {
if trans, ok := dict[id]; ok && !trans.Translation.IsEmpty() {
m, err := assemble(&msg, &trans.Translation)
if err != nil {
return nil, wrap(err, "error")
}
_, leadWS, trailWS := trimWS(msg.Key)
if leadWS != "" || trailWS != "" {
m = catmsg.Affix{
Message: m,
Prefix: leadWS,
Suffix: trailWS,
}
}
// TODO: support macros.
data, err := catmsg.Compile(tag, nil, m)
if err != nil {
return nil, wrap(err, "error")
}
key := usedKeys[msg.Key]
if d := a[key]; d != "" && d != data {
warnf("Duplicate non-consistent translation for key %q, picking the one for message %q", msg.Key, id)
}
a[key] = string(data)
break
}
}
}
index := []uint32{0}
p := 0
for _, s := range a {
p += len(s)
index = append(index, uint32(p))
}
cw.WriteVar(langVars[i]+"Index", index)
cw.WriteConst(langVars[i]+"Data", strings.Join(a, ""))
}
return cw, nil
}