1// Copyright 2021 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// mkconsts generates const definition files for each GOEXPERIMENT.
8package main
9
10import (
11	"bytes"
12	"fmt"
13	"internal/goexperiment"
14	"log"
15	"os"
16	"reflect"
17	"strings"
18)
19
20func main() {
21	// Delete existing experiment constant files.
22	ents, err := os.ReadDir(".")
23	if err != nil {
24		log.Fatal(err)
25	}
26	for _, ent := range ents {
27		name := ent.Name()
28		if !strings.HasPrefix(name, "exp_") {
29			continue
30		}
31		// Check that this is definitely a generated file.
32		data, err := os.ReadFile(name)
33		if err != nil {
34			log.Fatalf("reading %s: %v", name, err)
35		}
36		if !bytes.Contains(data, []byte("Code generated by mkconsts")) {
37			log.Fatalf("%s: expected generated file", name)
38		}
39		if err := os.Remove(name); err != nil {
40			log.Fatal(err)
41		}
42	}
43
44	// Generate new experiment constant files.
45	rt := reflect.TypeOf(&goexperiment.Flags{}).Elem()
46	for i := 0; i < rt.NumField(); i++ {
47		f := rt.Field(i).Name
48		buildTag := "goexperiment." + strings.ToLower(f)
49		for _, val := range []bool{false, true} {
50			name := fmt.Sprintf("exp_%s_%s.go", strings.ToLower(f), pick(val, "off", "on"))
51			data := fmt.Sprintf(`// Code generated by mkconsts.go. DO NOT EDIT.
52
53//go:build %s%s
54
55package goexperiment
56
57const %s = %v
58const %sInt = %s
59`, pick(val, "!", ""), buildTag, f, val, f, pick(val, "0", "1"))
60			if err := os.WriteFile(name, []byte(data), 0666); err != nil {
61				log.Fatalf("writing %s: %v", name, err)
62			}
63		}
64	}
65}
66
67func pick(v bool, f, t string) string {
68	if v {
69		return t
70	}
71	return f
72}
73