| // Copyright 2021 The Go Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style | 
 | // license that can be found in the LICENSE file. | 
 |  | 
 | //go:build ignore | 
 | // +build ignore | 
 |  | 
 | // mkconsts generates const definition files for each GOEXPERIMENT. | 
 | package main | 
 |  | 
 | import ( | 
 | 	"bytes" | 
 | 	"fmt" | 
 | 	"internal/goexperiment" | 
 | 	"log" | 
 | 	"os" | 
 | 	"reflect" | 
 | 	"strings" | 
 | ) | 
 |  | 
 | func main() { | 
 | 	// Delete existing experiment constant files. | 
 | 	ents, err := os.ReadDir(".") | 
 | 	if err != nil { | 
 | 		log.Fatal(err) | 
 | 	} | 
 | 	for _, ent := range ents { | 
 | 		name := ent.Name() | 
 | 		if !strings.HasPrefix(name, "exp_") { | 
 | 			continue | 
 | 		} | 
 | 		// Check that this is definitely a generated file. | 
 | 		data, err := os.ReadFile(name) | 
 | 		if err != nil { | 
 | 			log.Fatalf("reading %s: %v", name, err) | 
 | 		} | 
 | 		if !bytes.Contains(data, []byte("Code generated by mkconsts")) { | 
 | 			log.Fatalf("%s: expected generated file", name) | 
 | 		} | 
 | 		if err := os.Remove(name); err != nil { | 
 | 			log.Fatal(err) | 
 | 		} | 
 | 	} | 
 |  | 
 | 	// Generate new experiment constant files. | 
 | 	rt := reflect.TypeOf(&goexperiment.Flags{}).Elem() | 
 | 	for i := 0; i < rt.NumField(); i++ { | 
 | 		f := rt.Field(i).Name | 
 | 		buildTag := "goexperiment." + strings.ToLower(f) | 
 | 		for _, val := range []bool{false, true} { | 
 | 			name := fmt.Sprintf("exp_%s_%s.go", strings.ToLower(f), pick(val, "off", "on")) | 
 | 			data := fmt.Sprintf(`// Code generated by mkconsts.go. DO NOT EDIT. | 
 |  | 
 | //go:build %s%s | 
 | // +build %s%s | 
 |  | 
 | package goexperiment | 
 |  | 
 | const %s = %v | 
 | const %sInt = %s | 
 | `, pick(val, "!", ""), buildTag, pick(val, "!", ""), buildTag, f, val, f, pick(val, "0", "1")) | 
 | 			if err := os.WriteFile(name, []byte(data), 0666); err != nil { | 
 | 				log.Fatalf("writing %s: %v", name, err) | 
 | 			} | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 | func pick(v bool, f, t string) string { | 
 | 	if v { | 
 | 		return t | 
 | 	} | 
 | 	return f | 
 | } |