-
Notifications
You must be signed in to change notification settings - Fork 712
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
It was removed from the build-tools repository. Add it to extra/ and fix a couple of linter errors.
- Loading branch information
Showing
1 changed file
with
178 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
#!/usr/bin/env bash | ||
# | ||
# Generate concrete implementations of LatestMap. | ||
# | ||
# e.g. | ||
# $ generate_latest_map ./report/out.go string NodeControlData ... | ||
# | ||
# Depends on: | ||
# - gofmt | ||
|
||
function generate_header { | ||
local out_file="${1}" | ||
local cmd="${2}" | ||
|
||
cat << EOF >"${out_file}" | ||
// Generated file, do not edit. | ||
// To regenerate, run ${cmd} | ||
package report | ||
import ( | ||
"time" | ||
"github.com/ugorji/go/codec" | ||
) | ||
EOF | ||
} | ||
|
||
function generate_latest_map { | ||
local out_file="$1" | ||
local data_type="$2" | ||
local uppercase_data_type="${data_type^}" | ||
local lowercase_data_type="${data_type,}" | ||
local wire_entry_type="wire${uppercase_data_type}LatestEntry" | ||
local decoder_type="${lowercase_data_type}LatestEntryDecoder" | ||
local iface_decoder_variable="${uppercase_data_type}LatestEntryDecoder" | ||
local latest_map_type="${uppercase_data_type}LatestMap" | ||
local empty_latest_map_variable="Empty${latest_map_type}" | ||
local make_function="Make${latest_map_type}" | ||
|
||
# shellcheck disable=SC2016 | ||
local json_timestamp='`json:"timestamp"`' | ||
# shellcheck disable=SC2016 | ||
local json_value='`json:"value"`' | ||
|
||
cat << EOF >>"${out_file}" | ||
type ${wire_entry_type} struct { | ||
Timestamp time.Time ${json_timestamp} | ||
Value ${data_type} ${json_value} | ||
} | ||
type ${decoder_type} struct {} | ||
func (d *${decoder_type}) Decode(decoder *codec.Decoder, entry *LatestEntry) { | ||
wire := ${wire_entry_type}{} | ||
decoder.Decode(&wire) | ||
entry.Timestamp = wire.Timestamp | ||
entry.Value = wire.Value | ||
} | ||
// ${iface_decoder_variable} is an implementation of LatestEntryDecoder | ||
// that decodes the LatestEntry instances having a ${data_type} value. | ||
var ${iface_decoder_variable} LatestEntryDecoder = &${decoder_type}{} | ||
// ${latest_map_type} holds latest ${data_type} instances. | ||
type ${latest_map_type} LatestMap | ||
// ${empty_latest_map_variable} is an empty ${latest_map_type}. Start with this. | ||
var ${empty_latest_map_variable} = (${latest_map_type})(MakeLatestMapWithDecoder(${iface_decoder_variable})) | ||
// ${make_function} makes an empty ${latest_map_type}. | ||
func ${make_function}() ${latest_map_type} { | ||
return ${empty_latest_map_variable} | ||
} | ||
// Copy is a noop, as ${latest_map_type}s are immutable. | ||
func (m ${latest_map_type}) Copy() ${latest_map_type} { | ||
return (${latest_map_type})((LatestMap)(m).Copy()) | ||
} | ||
// Size returns the number of elements. | ||
func (m ${latest_map_type}) Size() int { | ||
return (LatestMap)(m).Size() | ||
} | ||
// Merge produces a fresh ${latest_map_type} containing the keys from both inputs. | ||
// When both inputs contain the same key, the newer value is used. | ||
func (m ${latest_map_type}) Merge(other ${latest_map_type}) ${latest_map_type} { | ||
return (${latest_map_type})((LatestMap)(m).Merge((LatestMap)(other))) | ||
} | ||
// Lookup the value for the given key. | ||
func (m ${latest_map_type}) Lookup(key string) (${data_type}, bool) { | ||
v, ok := (LatestMap)(m).Lookup(key) | ||
if !ok { | ||
var zero ${data_type} | ||
return zero, false | ||
} | ||
return v.(${data_type}), true | ||
} | ||
// LookupEntry returns the raw entry for the given key. | ||
func (m ${latest_map_type}) LookupEntry(key string) (${data_type}, time.Time, bool) { | ||
v, timestamp, ok := (LatestMap)(m).LookupEntry(key) | ||
if !ok { | ||
var zero ${data_type} | ||
return zero, timestamp, false | ||
} | ||
return v.(${data_type}), timestamp, true | ||
} | ||
// Set the value for the given key. | ||
func (m ${latest_map_type}) Set(key string, timestamp time.Time, value ${data_type}) ${latest_map_type} { | ||
return (${latest_map_type})((LatestMap)(m).Set(key, timestamp, value)) | ||
} | ||
// Delete the value for the given key. | ||
func (m ${latest_map_type}) Delete(key string) ${latest_map_type} { | ||
return (${latest_map_type})((LatestMap)(m).Delete(key)) | ||
} | ||
// ForEach executes fn on each key value pair in the map. | ||
func (m ${latest_map_type}) ForEach(fn func(k string, timestamp time.Time, v ${data_type})) { | ||
(LatestMap)(m).ForEach(func(key string, ts time.Time, value interface{}) { | ||
fn(key, ts, value.(${data_type})) | ||
}) | ||
} | ||
// String returns the ${latest_map_type}'s string representation. | ||
func (m ${latest_map_type}) String() string { | ||
return (LatestMap)(m).String() | ||
} | ||
// DeepEqual tests equality with other ${latest_map_type}. | ||
func (m ${latest_map_type}) DeepEqual(n ${latest_map_type}) bool { | ||
return (LatestMap)(m).DeepEqual((LatestMap)(n)) | ||
} | ||
// CodecEncodeSelf implements codec.Selfer. | ||
func (m *${latest_map_type}) CodecEncodeSelf(encoder *codec.Encoder) { | ||
(*LatestMap)(m).CodecEncodeSelf(encoder) | ||
} | ||
// CodecDecodeSelf implements codec.Selfer. | ||
func (m *${latest_map_type}) CodecDecodeSelf(decoder *codec.Decoder) { | ||
bm := (*LatestMap)(m) | ||
bm.decoder = ${iface_decoder_variable} | ||
bm.CodecDecodeSelf(decoder) | ||
} | ||
// MarshalJSON shouldn't be used, use CodecEncodeSelf instead. | ||
func (${latest_map_type}) MarshalJSON() ([]byte, error) { | ||
panic("MarshalJSON shouldn't be used, use CodecEncodeSelf instead") | ||
} | ||
// UnmarshalJSON shouldn't be used, use CodecDecodeSelf instead. | ||
func (*${latest_map_type}) UnmarshalJSON(b []byte) error { | ||
panic("UnmarshalJSON shouldn't be used, use CodecDecodeSelf instead") | ||
} | ||
EOF | ||
} | ||
|
||
if [ -z "${1}" ]; then | ||
echo "No output file given" | ||
exit 1 | ||
fi | ||
|
||
out="${1}" | ||
outtmp="${out}.tmp" | ||
|
||
generate_header "${outtmp}" "${0} ${*}" | ||
shift | ||
for t in "${@}"; do | ||
generate_latest_map "${outtmp}" "${t}" | ||
done | ||
|
||
gofmt -s -w "${outtmp}" | ||
mv "${outtmp}" "${out}" |