blob: 1a42331c509afcf4a4e775126fb0a7341da5bc20 [file] [log] [blame]
/*
* Copyright 2018 The Bazel Authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:Suppress("UNCHECKED_CAST")
package io.bazel.ruleskotlin.workers
import java.util.*
import java.util.stream.Stream
class Context private constructor(args: List<String>) {
private val args = EnumMap<Flags, String>(Flags::class.java)
private val meta = HashMap<Meta<*>, Any>()
init {
if (args.size % 2 != 0) {
throw RuntimeException("args should be k,v pairs")
}
for (i in 0 until args.size / 2) {
val flag = args[i * 2]
val value = args[i * 2 + 1]
val field = ALL_FIELDS_MAP[flag] ?: throw RuntimeException("unrecognised arg: " + flag)
this.args[field] = value
}
MANDATORY_FIELDS.asSequence()
.filterNot { this.args.containsKey(it) }
.forEach { throw RuntimeException("mandatory arg missing: " + it.globalFlag) }
}
fun of(vararg fields: Flags): EnumMap<Flags, String> {
val result = EnumMap<Flags, String>(Flags::class.java)
for (field in fields) {
val value = args[field]
if (value != null) {
result[field] = value
}
}
return result
}
fun apply(vararg consumers: (Context) -> Unit) {
Stream.of(*consumers).forEach { it(this) }
}
internal operator fun get(field: Flags): String? = args[field]
internal operator fun <T : Any> get(key: Meta<T>): T? = meta[key] as T?
internal fun <T : Any> putIfAbsent(key: Meta<T>, value: T): T? = meta.putIfAbsent(key, value as Any) as T?
companion object {
private val ALL_FIELDS_MAP = Flags.values().map { it.globalFlag to Flags.valueOf(it.name) }.toMap()
private val MANDATORY_FIELDS = Flags.values().filter { x -> x.mandatory }
fun from(args: List<String>): Context {
return Context(args)
}
}
}