Fixes https://github.com/pulumi/pulumi/issues/12738https://github.com/pulumi/pulumi/pull/11834 turned on the prealloc
linter and changed a load of slice uses from just `var x T[]` to `x :=
make([]T, 0, preallocSize)`. This was good for performance but it turns
out there are a number of places in the codebase that treat a `nil`
slice as semnatically different to an empty slice.
Trying to test that, or even reason that through for every callsite is
untractable, so this PR replaces all expressions of the form `make([]T,
0, size)` with a call to `slice.Prealloc[T](size)`. When size is 0 that
returns a nil array, rather than an empty array.
Migrates all remaining usages of
`contract.Assert*` and `contract.Require*` to the f variants,
which require adding meaningful error messages.
There were a couple cases where a `testing.T` or `testing.B`
was already available.
For those, this uses t.FailNow or require.NoError.
Refs #12132
This change is composed of two pieces: one to guard access to the binding
operations and their results using a mutex, and one to make the result of
PartialPackage.Snapshot safe to use concurrently.
The former set of changes is pretty straighforward, and just involves
adding a mutex and appropriate locking/unlocking around binding operations
and reads/writes from/to PartialPackage.def.
The latter change is a bit riskier. The result of PartialPackage.Snapshot
is a *Package. Prior to these changes, multiple calls to Snapshot would
return a pointer to the same Package value after updating its fields.
Becuase the *Package API is field-based instead of method-based, there is
no way to make the update itself concurrency-safe, as there's nowhere to
add locking, and it is not possible to atomically update some of the
fields that are being updated (e.g. slice-typed fields). After these
changes, each call to Snapshot will return a new copy of the package.
By far the riskiest part of this change is that pointer equality can no
longer be used with the result of Snapshot to determine whether or not
two *Package values are the same. To facilitate proper equality
comparison, these changes add Equals() and Identity() methods to the
*Package API. The former compares two *Packages; the latter returns a
stringified version of the *Package's name and version that can be used
as a map key.
Fixes#9667.
These changes extend the public API of `pkg/codegen/schema` to support
on-demand binding of package members. On-demand binding is appropriate for
scenarios that do not require the entire package, especially those such as
program code generation or the YAML LSP server that require only specific
types/functions/etc.
The extensions to the public API consist of two new types and several new
methods. The most notable of these are `PackageReference` and
`Loader.LoadPackageReference`. The former provides the on-demand binding
interface, while the latter creates instances of the former (n.b. it was
my intent to make a breaking change to the signature of `Loader.LoadPackage`
s.t. it returns a `PackageReference`, but the circular dependency between
this Go module and those for YAML and Java prevented that change).
These changes _dramatically_ reduce the memory required to interace with
Pulumi Packages, and only require memory proportional to the number of
accessed package members. We may be able to improve on this in the future
by removing type/resource/function interning, which would allow those
values to be garbage collected at a granaular level rather than at a
package level. That is a more radical change, though, as it requires new
equality semantics for each of the affected types (some of which are
currently used as map keys).