in cmd/buildmetadata/main.go [175:295]
func buildPrefixMetadata(srcDir, varName, dstFile string) error {
// get our top level language directories
dirs, err := filepath.Glob(fmt.Sprintf("_build/%s/*", srcDir))
if err != nil {
return err
}
// for each directory
languageMappings := make(map[string]map[int]string)
for _, dir := range dirs {
fi, _ := os.Stat(dir) // only look at directories
if !fi.IsDir() {
continue
}
// build a map for that directory
mappings, err := readMappingsForDir(dir)
if err != nil {
return fmt.Errorf("error reading mappings for %s: %w", dir, err)
}
// save it for our language
languageMappings[filepath.Base(dir)] = mappings
}
output := bytes.Buffer{}
output.WriteString("package gen\n\n")
output.WriteString(fmt.Sprintf("var %s = map[string]string {\n", varName))
langs := maps.Keys(languageMappings)
sort.Strings(langs)
for _, lang := range langs {
mappings := languageMappings[lang]
// iterate through our map, creating our full set of values and prefixes
prefixes := make([]int, 0, len(mappings))
seenValues := make(map[string]bool)
values := make([]string, 0, 255)
for prefix, value := range mappings {
prefixes = append(prefixes, prefix)
_, seen := seenValues[value]
if !seen {
values = append(values, value)
seenValues[value] = true
}
}
// make sure we won't overrun uint16s
if len(values) > math.MaxUint16 {
return fmt.Errorf("too many values to represent in uint16")
}
// need sorted prefixes for our diff writing to work
sort.Ints(prefixes)
// sorted values compress better
sort.Strings(values)
// build our reverse mapping from value to offset
internMappings := make(map[string]uint16)
for i, value := range values {
internMappings[value] = uint16(i)
}
// write our map
data := &bytes.Buffer{}
// first write our values, as length of string and raw bytes
joinedValues := strings.Join(values, "\n")
if err = binary.Write(data, binary.LittleEndian, uint32(len(joinedValues))); err != nil {
return err
}
if err = binary.Write(data, binary.LittleEndian, []byte(joinedValues)); err != nil {
return err
}
// then then number of prefix / value pairs
if err = binary.Write(data, binary.LittleEndian, uint32(len(prefixes))); err != nil {
return err
}
// we write our prefix / value pairs as a varint of the difference of the previous prefix
// and a uint16 of the value index
last := 0
intBuf := make([]byte, 6)
for _, prefix := range prefixes {
value := mappings[prefix]
valueIntern := internMappings[value]
diff := prefix - last
l := binary.PutUvarint(intBuf, uint64(diff))
if err = binary.Write(data, binary.LittleEndian, intBuf[:l]); err != nil {
return err
}
if err = binary.Write(data, binary.LittleEndian, uint16(valueIntern)); err != nil {
return err
}
last = prefix
}
var compressed bytes.Buffer
w := gzip.NewWriter(&compressed)
w.Write(data.Bytes())
w.Close()
c := base64.StdEncoding.EncodeToString(compressed.Bytes())
output.WriteString("\t")
output.WriteString(strconv.Quote(lang))
output.WriteString(": ")
output.WriteString(strconv.Quote(c))
output.WriteString(",\n")
}
output.WriteString("}")
if err := os.WriteFile("gen/"+dstFile, output.Bytes(), os.FileMode(0664)); err != nil {
return fmt.Errorf("error writing %s: %w", dstFile, err)
}
return nil
}