in aggregators/internal/protohash/generate/main.go [17:119]
func main() {
const pkgpath = "github.com/elastic/apm-aggregation/aggregationpb"
cfg := &packages.Config{Mode: packages.NeedTypes | packages.NeedTypesInfo}
pkgs, err := packages.Load(cfg, pkgpath)
if err != nil {
log.Fatal(err)
}
f, err := os.Create("generated.go")
if err != nil {
log.Fatal(err)
}
defer f.Close()
fmt.Fprintln(f, `
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License 2.0;
// you may not use this file except in compliance with the Elastic License 2.0.
// Code generated by protohash/generate. DO NOT EDIT.
package protohash
import (
"encoding/binary"
"github.com/cespare/xxhash/v2"
"github.com/elastic/apm-aggregation/aggregationpb"
)
func writeUint32(h *xxhash.Digest, v uint32) {
var buf [4]byte
binary.LittleEndian.PutUint32(buf[:], v)
h.Write(buf[:])
}
func writeUint64(h *xxhash.Digest, v uint64) {
var buf [8]byte
binary.LittleEndian.PutUint64(buf[:], v)
h.Write(buf[:])
}
`[1:])
pkg := pkgs[0]
pkgscope := pkg.Types.Scope()
for _, name := range pkgscope.Names() {
if !strings.HasSuffix(name, "Key") {
continue
}
typeName, ok := pkgscope.Lookup(name).(*types.TypeName)
if !ok || !typeName.Exported() {
continue
}
named := typeName.Type().(*types.Named)
structType, ok := named.Underlying().(*types.Struct)
if !ok {
continue
}
fmt.Fprintf(f, "func Hash%[1]s(h xxhash.Digest, k *aggregationpb.%[1]s) xxhash.Digest {\n", name)
for i := 0; i < structType.NumFields(); i++ {
field := structType.Field(i)
if !field.Exported() {
continue
}
var unhandled bool
switch fieldType := field.Type().(type) {
case *types.Basic:
switch kind := fieldType.Kind(); kind {
case types.Bool:
fmt.Fprintf(f, " if k.%s {\n h.WriteString(\"1\")\n }\n", field.Name())
case types.String:
fmt.Fprintf(f, " h.WriteString(k.%s)\n", field.Name())
case types.Uint32:
fmt.Fprintf(f, " writeUint32(&h, k.%s)\n", field.Name())
case types.Uint64:
fmt.Fprintf(f, " writeUint64(&h, k.%s)\n", field.Name())
default:
unhandled = true
}
case *types.Slice:
switch elemType := fieldType.Elem().(type) {
case *types.Basic:
if elemType.Kind() != types.Byte {
unhandled = true
break
}
fmt.Fprintf(f, " h.Write(k.%s)\n", field.Name())
default:
unhandled = true
}
default:
unhandled = true
}
if unhandled {
panic(fmt.Errorf("unhandled field %s.%s (%v)", name, field.Name(), field.Type()))
}
}
fmt.Fprintln(f, " return h\n}")
fmt.Fprintln(f)
}
}