- Plumb a `context.Context` parameter to pass to the decrypter
- Rephrase conversion over `config.Plaintext` values in order to
decouple decryption and conversion
These changes replace the idiosyncratic implementation of some of the
config Map and Value APIs with (hopefully) more straightforward code.
The fundamental representation of a config.Value remains a (value,
secure, object) tuple, where value is either a plain, possible-encrypted
string value or the JSON encoding of an object value. All operations on
values that need to observe the object value itself still decode the
JSON representation into a richer representation. This richer
representation, however, is no longer composed of `any` values: instead,
it is composed of `object` values. These values contain a restricted set
of types and directly track whether or not their contents are a secure
string value. The object-based representation allows for much clearer
implementations of the marshaling and traversal code without breaking
compatibility.
In addition to the new implementation for config.Value, these changes
add a config.Plaintext type that represents a plaintext config value. A
Plaintext value can be created manually or by decrypting a Value, and
can be encrypted and converted to a Value. This allows for more natural
creation and manipulation of config values.