As with many other systems that involve a client indirectly manipulating
objects on the other side of a trust boundary, we're going to use opaque
"handles" to represent objects that remain active on the server side
between different RPC API calls.
A handle is just a 64-bit integer corresponding to an entry in a lookup
table maintained by the server, in the "handleTable" type.
In the public API we don't make any promises about uniqueness of handles
between different types of objects, but to minimize the impact of client
bugs we'll internally ensure that we never issue the same handle number
for two objects of different types. This means that a client getting their
handles mixed up will typically cause an explicit error rather than just
doing something weird with an unrelated object that happened to have a
matching handle.
Our internal API for this will use explicit separate methods for each type
of handle and use type parameters so that the Go compiler can call us out
if we're inconsistent in how we're using the handles. From a client
perspective though these all just layer to protobuf int64; clients might
choose to add their own similar abstraction to track handle types, but
that's their own business since we can't represent such things efficiently
within the protocol buffers schema model.
This commit includes initial implementations of
Dependencies.OpenSourceBundle and Dependencies.CloseSourceBundle just as
some initial evidence that this design works. We'll continue implementing
the other real service functions in later commits once the basic
infrastructure (like this) is in place.