From eb8ae5c1cdde627cdc30c1109379a7341c5271b6 Mon Sep 17 00:00:00 2001 From: Pramod Bindal Date: Wed, 7 Jan 2026 17:00:23 +0530 Subject: [PATCH 01/13] Add MultiCluster Scheduler config Signed-off-by: Pramod Bindal --- pkg/apis/operator/v1alpha1/register.go | 3 + .../v1alpha1/tektonconfig_defaults.go | 1 + .../operator/v1alpha1/tektonconfig_types.go | 5 +- .../v1alpha1/tektonscheduler_defaults.go | 41 ++ .../v1alpha1/tektonscheduler_lifecycle.go | 148 ++++++ .../tektonscheduler_lifecycle_test.go | 90 ++++ .../v1alpha1/tektonscheduler_types.go | 103 +++++ .../v1alpha1/zz_generated.deepcopy.go | 136 ++++++ .../v1alpha1/fake/fake_operator_client.go | 4 + .../v1alpha1/fake/fake_tektonscheduler.go | 52 +++ .../operator/v1alpha1/generated_expansion.go | 2 + .../operator/v1alpha1/operator_client.go | 5 + .../operator/v1alpha1/tektonscheduler.go | 70 +++ .../informers/externalversions/generic.go | 2 + .../operator/v1alpha1/interface.go | 7 + .../operator/v1alpha1/tektonscheduler.go | 89 ++++ .../v1alpha1/tektonscheduler/fake/fake.go | 40 ++ .../tektonscheduler/filtered/fake/fake.go | 52 +++ .../filtered/tektonscheduler.go | 65 +++ .../tektonscheduler/tektonscheduler.go | 52 +++ .../v1alpha1/tektonscheduler/controller.go | 170 +++++++ .../v1alpha1/tektonscheduler/reconciler.go | 432 ++++++++++++++++++ .../v1alpha1/tektonscheduler/state.go | 97 ++++ .../operator/v1alpha1/expansion_generated.go | 4 + .../operator/v1alpha1/tektonscheduler.go | 48 ++ 25 files changed, 1717 insertions(+), 1 deletion(-) create mode 100644 pkg/apis/operator/v1alpha1/tektonscheduler_defaults.go create mode 100644 pkg/apis/operator/v1alpha1/tektonscheduler_lifecycle.go create mode 100644 pkg/apis/operator/v1alpha1/tektonscheduler_lifecycle_test.go create mode 100644 pkg/apis/operator/v1alpha1/tektonscheduler_types.go create mode 100644 pkg/client/clientset/versioned/typed/operator/v1alpha1/fake/fake_tektonscheduler.go create mode 100644 pkg/client/clientset/versioned/typed/operator/v1alpha1/tektonscheduler.go create mode 100644 pkg/client/informers/externalversions/operator/v1alpha1/tektonscheduler.go create mode 100644 pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/fake/fake.go create mode 100644 pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/filtered/fake/fake.go create mode 100644 pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/filtered/tektonscheduler.go create mode 100644 pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/tektonscheduler.go create mode 100644 pkg/client/injection/reconciler/operator/v1alpha1/tektonscheduler/controller.go create mode 100644 pkg/client/injection/reconciler/operator/v1alpha1/tektonscheduler/reconciler.go create mode 100644 pkg/client/injection/reconciler/operator/v1alpha1/tektonscheduler/state.go create mode 100644 pkg/client/listers/operator/v1alpha1/tektonscheduler.go diff --git a/pkg/apis/operator/v1alpha1/register.go b/pkg/apis/operator/v1alpha1/register.go index c16c122d9b..bc73095406 100644 --- a/pkg/apis/operator/v1alpha1/register.go +++ b/pkg/apis/operator/v1alpha1/register.go @@ -64,6 +64,9 @@ const ( // KindTektonPruner is the Kind of TektonPruner in a GVK context. KindTektonPruner = "TektonPruner" + + // KindTektonScheduler is the Kind of TektonScheduler in a GVK context. + KindTektonScheduler = "TektonScheduler" ) // Resource takes an unqualified resource and returns a Group qualified GroupResource diff --git a/pkg/apis/operator/v1alpha1/tektonconfig_defaults.go b/pkg/apis/operator/v1alpha1/tektonconfig_defaults.go index 39aaa7e004..93e4cd7945 100644 --- a/pkg/apis/operator/v1alpha1/tektonconfig_defaults.go +++ b/pkg/apis/operator/v1alpha1/tektonconfig_defaults.go @@ -33,6 +33,7 @@ func (tc *TektonConfig) SetDefaults(ctx context.Context) { tc.Spec.Chain.setDefaults() tc.Spec.Result.setDefaults() tc.Spec.TektonPruner.SetDefaults() + tc.Spec.Scheduler.SetDefaults() if IsOpenShiftPlatform() { if tc.Spec.Platforms.OpenShift.PipelinesAsCode == nil { diff --git a/pkg/apis/operator/v1alpha1/tektonconfig_types.go b/pkg/apis/operator/v1alpha1/tektonconfig_types.go index 8e4f5eb227..63b32b29ab 100644 --- a/pkg/apis/operator/v1alpha1/tektonconfig_types.go +++ b/pkg/apis/operator/v1alpha1/tektonconfig_types.go @@ -91,7 +91,10 @@ type TektonConfigSpec struct { Pruner Prune `json:"pruner,omitempty"` // New EventBasedPruner which provides more granular control over TaskRun and PipelineRuns TektonPruner Pruner `json:"tektonpruner,omitempty"` - CommonSpec `json:",inline"` + // To enable Pipeline Scheduling on Single Cluster or Multiple Clusters + // +optional + Scheduler Scheduler `json:"scheduler,omitempty"` + CommonSpec `json:",inline"` // Addon holds the addons config // +optional Addon Addon `json:"addon,omitempty"` diff --git a/pkg/apis/operator/v1alpha1/tektonscheduler_defaults.go b/pkg/apis/operator/v1alpha1/tektonscheduler_defaults.go new file mode 100644 index 0000000000..8c3d022612 --- /dev/null +++ b/pkg/apis/operator/v1alpha1/tektonscheduler_defaults.go @@ -0,0 +1,41 @@ +/* +Copyright 2026 The Tekton Authors + +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. +*/ + +package v1alpha1 + +import ( + "context" + + "k8s.io/utils/ptr" +) + +const ( + DefaultMultiClusterDisabled = true + DefaultSchedulerDisabled = true + MultiClusterRoleSpoke MultiClusterRole = "Spoke" + MultiClusterRoleHub MultiClusterRole = "Hub" +) + +func (tp *TektonScheduler) SetDefaults(_ context.Context) { + tp.Spec.Scheduler.SetDefaults() +} + +func (s *Scheduler) SetDefaults() { + if s.Disabled == nil { + s.Disabled = ptr.To(DefaultSchedulerDisabled) + s.MultiClusterDisabled = DefaultMultiClusterDisabled + } +} diff --git a/pkg/apis/operator/v1alpha1/tektonscheduler_lifecycle.go b/pkg/apis/operator/v1alpha1/tektonscheduler_lifecycle.go new file mode 100644 index 0000000000..d9f0043ad5 --- /dev/null +++ b/pkg/apis/operator/v1alpha1/tektonscheduler_lifecycle.go @@ -0,0 +1,148 @@ +/* +Copyright 2026 The Tekton Authors + +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. +*/ + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "knative.dev/pkg/apis" +) + +var ( + _ TektonComponentStatus = (*TektonSchedulerStatus)(nil) +) + +// GroupVersionKind returns SchemeGroupVersion of a TektonScheduler +func (Scheduler *TektonScheduler) GroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind(KindTektonScheduler) +} + +func (Scheduler *TektonScheduler) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind(KindTektonScheduler) +} + +// GetCondition returns the current condition of a given condition type +func (Scheduler *TektonSchedulerStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return condSet.Manage(Scheduler).GetCondition(t) +} + +// InitializeConditions initializes conditions of an TektonSchedulerStatus +func (Scheduler *TektonSchedulerStatus) InitializeConditions() { + condSet.Manage(Scheduler).InitializeConditions() +} + +// IsReady looks at the conditions returns true if they are all true. +func (Scheduler *TektonSchedulerStatus) IsReady() bool { + return condSet.Manage(Scheduler).IsHappy() +} + +func (Scheduler *TektonSchedulerStatus) MarkPreReconcilerComplete() { + condSet.Manage(Scheduler).MarkTrue(PreReconciler) +} + +func (Scheduler *TektonSchedulerStatus) MarkInstallerSetAvailable() { + condSet.Manage(Scheduler).MarkTrue(InstallerSetAvailable) +} + +func (Scheduler *TektonSchedulerStatus) MarkInstallerSetReady() { + condSet.Manage(Scheduler).MarkTrue(InstallerSetReady) +} + +func (Scheduler *TektonSchedulerStatus) MarkPostReconcilerComplete() { + condSet.Manage(Scheduler).MarkTrue(PostReconciler) +} + +// MarkDependenciesInstalled marks the DependenciesInstalled status as true. +func (Scheduler *TektonSchedulerStatus) MarkDependenciesInstalled() { + condSet.Manage(Scheduler).MarkTrue(DependenciesInstalled) +} + +func (Scheduler *TektonSchedulerStatus) MarkNotReady(msg string) { + condSet.Manage(Scheduler).MarkFalse( + apis.ConditionReady, + "Error", + "Ready: %s", msg) +} + +func (Scheduler *TektonSchedulerStatus) MarkPreReconcilerFailed(msg string) { + Scheduler.MarkNotReady("PreReconciliation failed") + condSet.Manage(Scheduler).MarkFalse( + PreReconciler, + "Error", + "PreReconciliation failed with message: %s", msg) +} + +func (Scheduler *TektonSchedulerStatus) MarkInstallerSetNotAvailable(msg string) { + Scheduler.MarkNotReady("TektonScheduler not ready") + condSet.Manage(Scheduler).MarkFalse( + InstallerSetAvailable, + "Error", + "Installer set not ready: %s", msg) +} + +func (Scheduler *TektonSchedulerStatus) MarkInstallerSetNotReady(msg string) { + Scheduler.MarkNotReady("TektonScheduler not ready") + condSet.Manage(Scheduler).MarkFalse( + InstallerSetReady, + "Error", + "Installer set not ready: %s", msg) +} + +func (Scheduler *TektonSchedulerStatus) MarkPostReconcilerFailed(msg string) { + Scheduler.MarkNotReady("PostReconciliation failed") + condSet.Manage(Scheduler).MarkFalse( + PostReconciler, + "Error", + "PostReconciliation failed with message: %s", msg) +} + +// MarkDependencyInstalling marks the DependenciesInstalled status as false with the +// given message. +func (Scheduler *TektonSchedulerStatus) MarkDependencyInstalling(msg string) { + Scheduler.MarkNotReady("Dependencies installing") + condSet.Manage(Scheduler).MarkFalse( + DependenciesInstalled, + "Error", + "Dependency installing: %s", msg) +} + +// MarkDependencyMissing marks the DependenciesInstalled status as false with the +// given message. +func (Scheduler *TektonSchedulerStatus) MarkDependencyMissing(msg string) { + Scheduler.MarkNotReady("Missing Dependencies for TektonScheduler") + condSet.Manage(Scheduler).MarkFalse( + DependenciesInstalled, + "Error", + "Dependency missing: %s", msg) +} + +func (Scheduler *TektonSchedulerStatus) GetTektonScheduler() string { + return Scheduler.TektonScheduler +} + +func (Scheduler *TektonSchedulerStatus) SetTektonScheduler(installerSet string) { + Scheduler.TektonScheduler = installerSet +} + +// GetVersion gets the currently installed version of the component. +func (Scheduler *TektonSchedulerStatus) GetVersion() string { + return Scheduler.Version +} + +// SetVersion sets the currently installed version of the component. +func (Scheduler *TektonSchedulerStatus) SetVersion(version string) { + Scheduler.Version = version +} diff --git a/pkg/apis/operator/v1alpha1/tektonscheduler_lifecycle_test.go b/pkg/apis/operator/v1alpha1/tektonscheduler_lifecycle_test.go new file mode 100644 index 0000000000..c2e8db92cd --- /dev/null +++ b/pkg/apis/operator/v1alpha1/tektonscheduler_lifecycle_test.go @@ -0,0 +1,90 @@ +/* +Copyright 2026 The Tekton Authors + +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. +*/ + +package v1alpha1 + +import ( + "testing" + + "knative.dev/pkg/apis" + apistest "knative.dev/pkg/apis/testing" +) + +func TestTektonSchedulerStatus_SuccessConditions(t *testing.T) { + tt := &TektonSchedulerStatus{} + tt.InitializeConditions() + + apistest.CheckConditionOngoing(tt, DependenciesInstalled, t) + apistest.CheckConditionOngoing(tt, PreReconciler, t) + apistest.CheckConditionOngoing(tt, InstallerSetAvailable, t) + apistest.CheckConditionOngoing(tt, InstallerSetReady, t) + apistest.CheckConditionOngoing(tt, PostReconciler, t) + + // Dependencies installed + tt.MarkDependenciesInstalled() + apistest.CheckConditionSucceeded(tt, DependenciesInstalled, t) + + // Pre reconciler completes execution + tt.MarkPreReconcilerComplete() + apistest.CheckConditionSucceeded(tt, PreReconciler, t) + + // Installer set created + tt.MarkInstallerSetAvailable() + apistest.CheckConditionSucceeded(tt, InstallerSetAvailable, t) + + // InstallerSet and then PostReconciler become ready and we're good. + tt.MarkInstallerSetReady() + apistest.CheckConditionSucceeded(tt, InstallerSetReady, t) + + tt.MarkPostReconcilerComplete() + apistest.CheckConditionSucceeded(tt, PostReconciler, t) + + if ready := tt.IsReady(); !ready { + t.Errorf("tt.IsReady() = %v, want true", ready) + } +} + +func TestTektonSchedulerStatus_ErrorConditions(t *testing.T) { + // Given + tps := &TektonSchedulerStatus{} + + tps.MarkPreReconcilerFailed("Reconciliation Failed for Scheduler") + apistest.CheckConditionFailed(tps, PreReconciler, t) + + // Not Ready Condition + tps.MarkNotReady("Scheduler Not Ready") + apistest.CheckConditionFailed(tps, apis.ConditionReady, t) + + // PostReconciler Failed Condition + tps.MarkPostReconcilerFailed("Scheduler PostReconciler Failed") + apistest.CheckConditionFailed(tps, PostReconciler, t) + + // InstallerSetNotAvailable Condition + tps.MarkInstallerSetNotAvailable("Scheduler InstallerSetNotAvailable ") + apistest.CheckConditionFailed(tps, InstallerSetAvailable, t) + + // InstallerSetNotAvailable Condition + tps.MarkInstallerSetNotReady("Scheduler InstallerSetNotReady ") + apistest.CheckConditionFailed(tps, InstallerSetReady, t) + + // DependencyInstalling Condition + tps.MarkDependencyInstalling("Scheduler Dependencies are installing ") + apistest.CheckConditionFailed(tps, DependenciesInstalled, t) + + // DependencyMissing Condition + tps.MarkDependencyMissing("Scheduler Dependencies are Missing ") + apistest.CheckConditionFailed(tps, DependenciesInstalled, t) +} diff --git a/pkg/apis/operator/v1alpha1/tektonscheduler_types.go b/pkg/apis/operator/v1alpha1/tektonscheduler_types.go new file mode 100644 index 0000000000..8c0af223c0 --- /dev/null +++ b/pkg/apis/operator/v1alpha1/tektonscheduler_types.go @@ -0,0 +1,103 @@ +/* +Copyright 2026 The Tekton Authors + +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. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + duckv1 "knative.dev/pkg/apis/duck/v1" +) + +var ( + _ TektonComponent = (*TektonScheduler)(nil) + _ TektonComponentSpec = (*TektonSchedulerSpec)(nil) +) + +// TektonScheduler is the Schema for the TektonScheduler API +// +genclient +// +genreconciler:krshapedlogic=false +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +genclient:nonNamespaced +// +kubebuilder:resource:scope=Cluster + +type TektonScheduler struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec TektonSchedulerSpec `json:"spec,omitempty"` + Status TektonSchedulerStatus `json:"status,omitempty"` +} + +// Scheduler Configuration to manage Scheduler Configuration. +type Scheduler struct { + // enable or disable TektonScheduler Component + Disabled *bool `json:"disabled"` + MultiClusterConfig `json:",inline"` + // options holds additions fields and these fields will be updated on the manifests + Options AdditionalOptions `json:"options"` +} + +// MultiClusterConfig Configuration to enable/disable MultiCluster Configuration +type MultiClusterConfig struct { + MultiClusterDisabled bool `json:"multi-cluster-disabled"` + MultiClusterRole MultiClusterRole `json:"multi-cluster-role"` +} + +// MultiClusterRole Define the role of current cluster in multi-cluster environment. The MultiClusterRole can be one of Hub or Spoke +type MultiClusterRole string + +// TektonSchedulerList contains a list of TektonScheduler +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type TektonSchedulerList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []TektonScheduler `json:"items"` +} + +type TektonSchedulerSpec struct { + CommonSpec `json:",inline"` + Scheduler `json:",inline"` +} + +// TektonSchedulerStatus defines the observed state of TektonScheduler +type TektonSchedulerStatus struct { + duckv1.Status `json:",inline"` + + // The version of the installed release + // +optional + Version string `json:"version,omitempty"` + + // The current installer set name for TektonScheduler + // +optional + TektonScheduler string `json:"tekton-scheduler,omitempty"` +} + +// GetSpec implements TektonComponent +func (tp *TektonScheduler) GetSpec() TektonComponentSpec { + return &tp.Spec +} + +func (tp *TektonScheduler) GetStatus() TektonComponentStatus { + return &tp.Status +} + +// IsDisabled returns true if the TektonScheduler is disabled +func (p *Scheduler) IsDisabled() bool { + if p == nil || p.Disabled == nil { + // When the Scheduler is nil or Disabled is nil, we assume it is the default state. + return DefaultSchedulerDisabled + } + return *p.Disabled +} diff --git a/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go index 677b5ed37b..b2c3ae6ed9 100644 --- a/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/operator/v1alpha1/zz_generated.deepcopy.go @@ -570,6 +570,22 @@ func (in *ManualApprovalGateStatus) DeepCopy() *ManualApprovalGateStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MultiClusterConfig) DeepCopyInto(out *MultiClusterConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultiClusterConfig. +func (in *MultiClusterConfig) DeepCopy() *MultiClusterConfig { + if in == nil { + return nil + } + out := new(MultiClusterConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NamespaceMetadata) DeepCopyInto(out *NamespaceMetadata) { *out = *in @@ -1330,6 +1346,29 @@ func (in *SCC) DeepCopy() *SCC { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Scheduler) DeepCopyInto(out *Scheduler) { + *out = *in + if in.Disabled != nil { + in, out := &in.Disabled, &out.Disabled + *out = new(bool) + **out = **in + } + out.MultiClusterConfig = in.MultiClusterConfig + in.Options.DeepCopyInto(&out.Options) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Scheduler. +func (in *Scheduler) DeepCopy() *Scheduler { + if in == nil { + return nil + } + out := new(Scheduler) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Scope) DeepCopyInto(out *Scope) { *out = *in @@ -1619,6 +1658,7 @@ func (in *TektonConfigSpec) DeepCopyInto(out *TektonConfigSpec) { in.Config.DeepCopyInto(&out.Config) in.Pruner.DeepCopyInto(&out.Pruner) in.TektonPruner.DeepCopyInto(&out.TektonPruner) + in.Scheduler.DeepCopyInto(&out.Scheduler) out.CommonSpec = in.CommonSpec in.Addon.DeepCopyInto(&out.Addon) in.Hub.DeepCopyInto(&out.Hub) @@ -2310,6 +2350,102 @@ func (in *TektonResultStatus) DeepCopy() *TektonResultStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TektonScheduler) DeepCopyInto(out *TektonScheduler) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TektonScheduler. +func (in *TektonScheduler) DeepCopy() *TektonScheduler { + if in == nil { + return nil + } + out := new(TektonScheduler) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TektonScheduler) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TektonSchedulerList) DeepCopyInto(out *TektonSchedulerList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]TektonScheduler, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TektonSchedulerList. +func (in *TektonSchedulerList) DeepCopy() *TektonSchedulerList { + if in == nil { + return nil + } + out := new(TektonSchedulerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *TektonSchedulerList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TektonSchedulerSpec) DeepCopyInto(out *TektonSchedulerSpec) { + *out = *in + out.CommonSpec = in.CommonSpec + in.Scheduler.DeepCopyInto(&out.Scheduler) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TektonSchedulerSpec. +func (in *TektonSchedulerSpec) DeepCopy() *TektonSchedulerSpec { + if in == nil { + return nil + } + out := new(TektonSchedulerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TektonSchedulerStatus) DeepCopyInto(out *TektonSchedulerStatus) { + *out = *in + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TektonSchedulerStatus. +func (in *TektonSchedulerStatus) DeepCopy() *TektonSchedulerStatus { + if in == nil { + return nil + } + out := new(TektonSchedulerStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TektonTrigger) DeepCopyInto(out *TektonTrigger) { *out = *in diff --git a/pkg/client/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go b/pkg/client/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go index 49bb5e6bf6..f1d55c3caa 100644 --- a/pkg/client/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go +++ b/pkg/client/clientset/versioned/typed/operator/v1alpha1/fake/fake_operator_client.go @@ -72,6 +72,10 @@ func (c *FakeOperatorV1alpha1) TektonResults() v1alpha1.TektonResultInterface { return newFakeTektonResults(c) } +func (c *FakeOperatorV1alpha1) TektonSchedulers() v1alpha1.TektonSchedulerInterface { + return newFakeTektonSchedulers(c) +} + func (c *FakeOperatorV1alpha1) TektonTriggers() v1alpha1.TektonTriggerInterface { return newFakeTektonTriggers(c) } diff --git a/pkg/client/clientset/versioned/typed/operator/v1alpha1/fake/fake_tektonscheduler.go b/pkg/client/clientset/versioned/typed/operator/v1alpha1/fake/fake_tektonscheduler.go new file mode 100644 index 0000000000..f8402a59ce --- /dev/null +++ b/pkg/client/clientset/versioned/typed/operator/v1alpha1/fake/fake_tektonscheduler.go @@ -0,0 +1,52 @@ +/* +Copyright 2020 The Tekton Authors + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" + operatorv1alpha1 "github.com/tektoncd/operator/pkg/client/clientset/versioned/typed/operator/v1alpha1" + gentype "k8s.io/client-go/gentype" +) + +// fakeTektonSchedulers implements TektonSchedulerInterface +type fakeTektonSchedulers struct { + *gentype.FakeClientWithList[*v1alpha1.TektonScheduler, *v1alpha1.TektonSchedulerList] + Fake *FakeOperatorV1alpha1 +} + +func newFakeTektonSchedulers(fake *FakeOperatorV1alpha1) operatorv1alpha1.TektonSchedulerInterface { + return &fakeTektonSchedulers{ + gentype.NewFakeClientWithList[*v1alpha1.TektonScheduler, *v1alpha1.TektonSchedulerList]( + fake.Fake, + "", + v1alpha1.SchemeGroupVersion.WithResource("tektonschedulers"), + v1alpha1.SchemeGroupVersion.WithKind("TektonScheduler"), + func() *v1alpha1.TektonScheduler { return &v1alpha1.TektonScheduler{} }, + func() *v1alpha1.TektonSchedulerList { return &v1alpha1.TektonSchedulerList{} }, + func(dst, src *v1alpha1.TektonSchedulerList) { dst.ListMeta = src.ListMeta }, + func(list *v1alpha1.TektonSchedulerList) []*v1alpha1.TektonScheduler { + return gentype.ToPointerSlice(list.Items) + }, + func(list *v1alpha1.TektonSchedulerList, items []*v1alpha1.TektonScheduler) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/pkg/client/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go index eefbedb4f6..7c8fd8671f 100644 --- a/pkg/client/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/operator/v1alpha1/generated_expansion.go @@ -40,4 +40,6 @@ type TektonPrunerExpansion interface{} type TektonResultExpansion interface{} +type TektonSchedulerExpansion interface{} + type TektonTriggerExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/operator/v1alpha1/operator_client.go b/pkg/client/clientset/versioned/typed/operator/v1alpha1/operator_client.go index 58a6078733..4343469e4a 100644 --- a/pkg/client/clientset/versioned/typed/operator/v1alpha1/operator_client.go +++ b/pkg/client/clientset/versioned/typed/operator/v1alpha1/operator_client.go @@ -39,6 +39,7 @@ type OperatorV1alpha1Interface interface { TektonPipelinesGetter TektonPrunersGetter TektonResultsGetter + TektonSchedulersGetter TektonTriggersGetter } @@ -91,6 +92,10 @@ func (c *OperatorV1alpha1Client) TektonResults() TektonResultInterface { return newTektonResults(c) } +func (c *OperatorV1alpha1Client) TektonSchedulers() TektonSchedulerInterface { + return newTektonSchedulers(c) +} + func (c *OperatorV1alpha1Client) TektonTriggers() TektonTriggerInterface { return newTektonTriggers(c) } diff --git a/pkg/client/clientset/versioned/typed/operator/v1alpha1/tektonscheduler.go b/pkg/client/clientset/versioned/typed/operator/v1alpha1/tektonscheduler.go new file mode 100644 index 0000000000..8684253837 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/operator/v1alpha1/tektonscheduler.go @@ -0,0 +1,70 @@ +/* +Copyright 2020 The Tekton Authors + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + context "context" + + operatorv1alpha1 "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" + scheme "github.com/tektoncd/operator/pkg/client/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + gentype "k8s.io/client-go/gentype" +) + +// TektonSchedulersGetter has a method to return a TektonSchedulerInterface. +// A group's client should implement this interface. +type TektonSchedulersGetter interface { + TektonSchedulers() TektonSchedulerInterface +} + +// TektonSchedulerInterface has methods to work with TektonScheduler resources. +type TektonSchedulerInterface interface { + Create(ctx context.Context, tektonScheduler *operatorv1alpha1.TektonScheduler, opts v1.CreateOptions) (*operatorv1alpha1.TektonScheduler, error) + Update(ctx context.Context, tektonScheduler *operatorv1alpha1.TektonScheduler, opts v1.UpdateOptions) (*operatorv1alpha1.TektonScheduler, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, tektonScheduler *operatorv1alpha1.TektonScheduler, opts v1.UpdateOptions) (*operatorv1alpha1.TektonScheduler, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*operatorv1alpha1.TektonScheduler, error) + List(ctx context.Context, opts v1.ListOptions) (*operatorv1alpha1.TektonSchedulerList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *operatorv1alpha1.TektonScheduler, err error) + TektonSchedulerExpansion +} + +// tektonSchedulers implements TektonSchedulerInterface +type tektonSchedulers struct { + *gentype.ClientWithList[*operatorv1alpha1.TektonScheduler, *operatorv1alpha1.TektonSchedulerList] +} + +// newTektonSchedulers returns a TektonSchedulers +func newTektonSchedulers(c *OperatorV1alpha1Client) *tektonSchedulers { + return &tektonSchedulers{ + gentype.NewClientWithList[*operatorv1alpha1.TektonScheduler, *operatorv1alpha1.TektonSchedulerList]( + "tektonschedulers", + c.RESTClient(), + scheme.ParameterCodec, + "", + func() *operatorv1alpha1.TektonScheduler { return &operatorv1alpha1.TektonScheduler{} }, + func() *operatorv1alpha1.TektonSchedulerList { return &operatorv1alpha1.TektonSchedulerList{} }, + ), + } +} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index 77dbe58508..4625bc1c32 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -75,6 +75,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Operator().V1alpha1().TektonPruners().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("tektonresults"): return &genericInformer{resource: resource.GroupResource(), informer: f.Operator().V1alpha1().TektonResults().Informer()}, nil + case v1alpha1.SchemeGroupVersion.WithResource("tektonschedulers"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Operator().V1alpha1().TektonSchedulers().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("tektontriggers"): return &genericInformer{resource: resource.GroupResource(), informer: f.Operator().V1alpha1().TektonTriggers().Informer()}, nil diff --git a/pkg/client/informers/externalversions/operator/v1alpha1/interface.go b/pkg/client/informers/externalversions/operator/v1alpha1/interface.go index 9079fde7eb..5adfb37797 100644 --- a/pkg/client/informers/externalversions/operator/v1alpha1/interface.go +++ b/pkg/client/informers/externalversions/operator/v1alpha1/interface.go @@ -46,6 +46,8 @@ type Interface interface { TektonPruners() TektonPrunerInformer // TektonResults returns a TektonResultInformer. TektonResults() TektonResultInformer + // TektonSchedulers returns a TektonSchedulerInformer. + TektonSchedulers() TektonSchedulerInformer // TektonTriggers returns a TektonTriggerInformer. TektonTriggers() TektonTriggerInformer } @@ -116,6 +118,11 @@ func (v *version) TektonResults() TektonResultInformer { return &tektonResultInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } +// TektonSchedulers returns a TektonSchedulerInformer. +func (v *version) TektonSchedulers() TektonSchedulerInformer { + return &tektonSchedulerInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + // TektonTriggers returns a TektonTriggerInformer. func (v *version) TektonTriggers() TektonTriggerInformer { return &tektonTriggerInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} diff --git a/pkg/client/informers/externalversions/operator/v1alpha1/tektonscheduler.go b/pkg/client/informers/externalversions/operator/v1alpha1/tektonscheduler.go new file mode 100644 index 0000000000..4a0d9ff4b0 --- /dev/null +++ b/pkg/client/informers/externalversions/operator/v1alpha1/tektonscheduler.go @@ -0,0 +1,89 @@ +/* +Copyright 2020 The Tekton Authors + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + context "context" + time "time" + + apisoperatorv1alpha1 "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" + versioned "github.com/tektoncd/operator/pkg/client/clientset/versioned" + internalinterfaces "github.com/tektoncd/operator/pkg/client/informers/externalversions/internalinterfaces" + operatorv1alpha1 "github.com/tektoncd/operator/pkg/client/listers/operator/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// TektonSchedulerInformer provides access to a shared informer and lister for +// TektonSchedulers. +type TektonSchedulerInformer interface { + Informer() cache.SharedIndexInformer + Lister() operatorv1alpha1.TektonSchedulerLister +} + +type tektonSchedulerInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewTektonSchedulerInformer constructs a new informer for TektonScheduler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewTektonSchedulerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredTektonSchedulerInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredTektonSchedulerInformer constructs a new informer for TektonScheduler type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredTektonSchedulerInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.OperatorV1alpha1().TektonSchedulers().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.OperatorV1alpha1().TektonSchedulers().Watch(context.TODO(), options) + }, + }, + &apisoperatorv1alpha1.TektonScheduler{}, + resyncPeriod, + indexers, + ) +} + +func (f *tektonSchedulerInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredTektonSchedulerInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *tektonSchedulerInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apisoperatorv1alpha1.TektonScheduler{}, f.defaultInformer) +} + +func (f *tektonSchedulerInformer) Lister() operatorv1alpha1.TektonSchedulerLister { + return operatorv1alpha1.NewTektonSchedulerLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/fake/fake.go b/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/fake/fake.go new file mode 100644 index 0000000000..5c422362cc --- /dev/null +++ b/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/fake/fake.go @@ -0,0 +1,40 @@ +/* +Copyright 2020 The Tekton Authors + +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. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + context "context" + + fake "github.com/tektoncd/operator/pkg/client/injection/informers/factory/fake" + tektonscheduler "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" +) + +var Get = tektonscheduler.Get + +func init() { + injection.Fake.RegisterInformer(withInformer) +} + +func withInformer(ctx context.Context) (context.Context, controller.Informer) { + f := fake.Get(ctx) + inf := f.Operator().V1alpha1().TektonSchedulers() + return context.WithValue(ctx, tektonscheduler.Key{}, inf), inf.Informer() +} diff --git a/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/filtered/fake/fake.go b/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/filtered/fake/fake.go new file mode 100644 index 0000000000..9a29765062 --- /dev/null +++ b/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/filtered/fake/fake.go @@ -0,0 +1,52 @@ +/* +Copyright 2020 The Tekton Authors + +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. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + context "context" + + factoryfiltered "github.com/tektoncd/operator/pkg/client/injection/informers/factory/filtered" + filtered "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/filtered" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + logging "knative.dev/pkg/logging" +) + +var Get = filtered.Get + +func init() { + injection.Fake.RegisterFilteredInformers(withInformer) +} + +func withInformer(ctx context.Context) (context.Context, []controller.Informer) { + untyped := ctx.Value(factoryfiltered.LabelKey{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch labelkey from context.") + } + labelSelectors := untyped.([]string) + infs := []controller.Informer{} + for _, selector := range labelSelectors { + f := factoryfiltered.Get(ctx, selector) + inf := f.Operator().V1alpha1().TektonSchedulers() + ctx = context.WithValue(ctx, filtered.Key{Selector: selector}, inf) + infs = append(infs, inf.Informer()) + } + return ctx, infs +} diff --git a/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/filtered/tektonscheduler.go b/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/filtered/tektonscheduler.go new file mode 100644 index 0000000000..3ceb15bdf3 --- /dev/null +++ b/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/filtered/tektonscheduler.go @@ -0,0 +1,65 @@ +/* +Copyright 2020 The Tekton Authors + +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. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package filtered + +import ( + context "context" + + v1alpha1 "github.com/tektoncd/operator/pkg/client/informers/externalversions/operator/v1alpha1" + filtered "github.com/tektoncd/operator/pkg/client/injection/informers/factory/filtered" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterFilteredInformers(withInformer) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct { + Selector string +} + +func withInformer(ctx context.Context) (context.Context, []controller.Informer) { + untyped := ctx.Value(filtered.LabelKey{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch labelkey from context.") + } + labelSelectors := untyped.([]string) + infs := []controller.Informer{} + for _, selector := range labelSelectors { + f := filtered.Get(ctx, selector) + inf := f.Operator().V1alpha1().TektonSchedulers() + ctx = context.WithValue(ctx, Key{Selector: selector}, inf) + infs = append(infs, inf.Informer()) + } + return ctx, infs +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context, selector string) v1alpha1.TektonSchedulerInformer { + untyped := ctx.Value(Key{Selector: selector}) + if untyped == nil { + logging.FromContext(ctx).Panicf( + "Unable to fetch github.com/tektoncd/operator/pkg/client/informers/externalversions/operator/v1alpha1.TektonSchedulerInformer with selector %s from context.", selector) + } + return untyped.(v1alpha1.TektonSchedulerInformer) +} diff --git a/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/tektonscheduler.go b/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/tektonscheduler.go new file mode 100644 index 0000000000..df7a1dcc0d --- /dev/null +++ b/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler/tektonscheduler.go @@ -0,0 +1,52 @@ +/* +Copyright 2020 The Tekton Authors + +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. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package tektonscheduler + +import ( + context "context" + + v1alpha1 "github.com/tektoncd/operator/pkg/client/informers/externalversions/operator/v1alpha1" + factory "github.com/tektoncd/operator/pkg/client/injection/informers/factory" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterInformer(withInformer) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func withInformer(ctx context.Context) (context.Context, controller.Informer) { + f := factory.Get(ctx) + inf := f.Operator().V1alpha1().TektonSchedulers() + return context.WithValue(ctx, Key{}, inf), inf.Informer() +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) v1alpha1.TektonSchedulerInformer { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch github.com/tektoncd/operator/pkg/client/informers/externalversions/operator/v1alpha1.TektonSchedulerInformer from context.") + } + return untyped.(v1alpha1.TektonSchedulerInformer) +} diff --git a/pkg/client/injection/reconciler/operator/v1alpha1/tektonscheduler/controller.go b/pkg/client/injection/reconciler/operator/v1alpha1/tektonscheduler/controller.go new file mode 100644 index 0000000000..036a2fcd1b --- /dev/null +++ b/pkg/client/injection/reconciler/operator/v1alpha1/tektonscheduler/controller.go @@ -0,0 +1,170 @@ +/* +Copyright 2020 The Tekton Authors + +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. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package tektonscheduler + +import ( + context "context" + fmt "fmt" + reflect "reflect" + strings "strings" + + versionedscheme "github.com/tektoncd/operator/pkg/client/clientset/versioned/scheme" + client "github.com/tektoncd/operator/pkg/client/injection/client" + tektonscheduler "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonscheduler" + zap "go.uber.org/zap" + corev1 "k8s.io/api/core/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + scheme "k8s.io/client-go/kubernetes/scheme" + v1 "k8s.io/client-go/kubernetes/typed/core/v1" + record "k8s.io/client-go/tools/record" + kubeclient "knative.dev/pkg/client/injection/kube/client" + controller "knative.dev/pkg/controller" + logging "knative.dev/pkg/logging" + logkey "knative.dev/pkg/logging/logkey" + reconciler "knative.dev/pkg/reconciler" +) + +const ( + defaultControllerAgentName = "tektonscheduler-controller" + defaultFinalizerName = "tektonschedulers.operator.tekton.dev" +) + +// NewImpl returns a controller.Impl that handles queuing and feeding work from +// the queue through an implementation of controller.Reconciler, delegating to +// the provided Interface and optional Finalizer methods. OptionsFn is used to return +// controller.ControllerOptions to be used by the internal reconciler. +func NewImpl(ctx context.Context, r Interface, optionsFns ...controller.OptionsFn) *controller.Impl { + logger := logging.FromContext(ctx) + + // Check the options function input. It should be 0 or 1. + if len(optionsFns) > 1 { + logger.Fatal("Up to one options function is supported, found: ", len(optionsFns)) + } + + tektonschedulerInformer := tektonscheduler.Get(ctx) + + lister := tektonschedulerInformer.Lister() + + var promoteFilterFunc func(obj interface{}) bool + var promoteFunc = func(bkt reconciler.Bucket) {} + + rec := &reconcilerImpl{ + LeaderAwareFuncs: reconciler.LeaderAwareFuncs{ + PromoteFunc: func(bkt reconciler.Bucket, enq func(reconciler.Bucket, types.NamespacedName)) error { + + // Signal promotion event + promoteFunc(bkt) + + all, err := lister.List(labels.Everything()) + if err != nil { + return err + } + for _, elt := range all { + if promoteFilterFunc != nil { + if ok := promoteFilterFunc(elt); !ok { + continue + } + } + enq(bkt, types.NamespacedName{ + Namespace: elt.GetNamespace(), + Name: elt.GetName(), + }) + } + return nil + }, + }, + Client: client.Get(ctx), + Lister: lister, + reconciler: r, + finalizerName: defaultFinalizerName, + } + + ctrType := reflect.TypeOf(r).Elem() + ctrTypeName := fmt.Sprintf("%s.%s", ctrType.PkgPath(), ctrType.Name()) + ctrTypeName = strings.ReplaceAll(ctrTypeName, "/", ".") + + logger = logger.With( + zap.String(logkey.ControllerType, ctrTypeName), + zap.String(logkey.Kind, "operator.tekton.dev.TektonScheduler"), + ) + + impl := controller.NewContext(ctx, rec, controller.ControllerOptions{WorkQueueName: ctrTypeName, Logger: logger}) + agentName := defaultControllerAgentName + + // Pass impl to the options. Save any optional results. + for _, fn := range optionsFns { + opts := fn(impl) + if opts.ConfigStore != nil { + rec.configStore = opts.ConfigStore + } + if opts.FinalizerName != "" { + rec.finalizerName = opts.FinalizerName + } + if opts.AgentName != "" { + agentName = opts.AgentName + } + if opts.SkipStatusUpdates { + rec.skipStatusUpdates = true + } + if opts.DemoteFunc != nil { + rec.DemoteFunc = opts.DemoteFunc + } + if opts.PromoteFilterFunc != nil { + promoteFilterFunc = opts.PromoteFilterFunc + } + if opts.PromoteFunc != nil { + promoteFunc = opts.PromoteFunc + } + } + + rec.Recorder = createRecorder(ctx, agentName) + + return impl +} + +func createRecorder(ctx context.Context, agentName string) record.EventRecorder { + logger := logging.FromContext(ctx) + + recorder := controller.GetEventRecorder(ctx) + if recorder == nil { + // Create event broadcaster + logger.Debug("Creating event broadcaster") + eventBroadcaster := record.NewBroadcaster() + watches := []watch.Interface{ + eventBroadcaster.StartLogging(logger.Named("event-broadcaster").Infof), + eventBroadcaster.StartRecordingToSink( + &v1.EventSinkImpl{Interface: kubeclient.Get(ctx).CoreV1().Events("")}), + } + recorder = eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: agentName}) + go func() { + <-ctx.Done() + for _, w := range watches { + w.Stop() + } + }() + } + + return recorder +} + +func init() { + versionedscheme.AddToScheme(scheme.Scheme) +} diff --git a/pkg/client/injection/reconciler/operator/v1alpha1/tektonscheduler/reconciler.go b/pkg/client/injection/reconciler/operator/v1alpha1/tektonscheduler/reconciler.go new file mode 100644 index 0000000000..3c27ae8f71 --- /dev/null +++ b/pkg/client/injection/reconciler/operator/v1alpha1/tektonscheduler/reconciler.go @@ -0,0 +1,432 @@ +/* +Copyright 2020 The Tekton Authors + +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. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package tektonscheduler + +import ( + context "context" + json "encoding/json" + fmt "fmt" + + v1alpha1 "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" + versioned "github.com/tektoncd/operator/pkg/client/clientset/versioned" + operatorv1alpha1 "github.com/tektoncd/operator/pkg/client/listers/operator/v1alpha1" + zap "go.uber.org/zap" + zapcore "go.uber.org/zap/zapcore" + v1 "k8s.io/api/core/v1" + equality "k8s.io/apimachinery/pkg/api/equality" + errors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + sets "k8s.io/apimachinery/pkg/util/sets" + record "k8s.io/client-go/tools/record" + controller "knative.dev/pkg/controller" + kmp "knative.dev/pkg/kmp" + logging "knative.dev/pkg/logging" + reconciler "knative.dev/pkg/reconciler" +) + +// Interface defines the strongly typed interfaces to be implemented by a +// controller reconciling v1alpha1.TektonScheduler. +type Interface interface { + // ReconcileKind implements custom logic to reconcile v1alpha1.TektonScheduler. Any changes + // to the objects .Status or .Finalizers will be propagated to the stored + // object. It is recommended that implementors do not call any update calls + // for the Kind inside of ReconcileKind, it is the responsibility of the calling + // controller to propagate those properties. The resource passed to ReconcileKind + // will always have an empty deletion timestamp. + ReconcileKind(ctx context.Context, o *v1alpha1.TektonScheduler) reconciler.Event +} + +// Finalizer defines the strongly typed interfaces to be implemented by a +// controller finalizing v1alpha1.TektonScheduler. +type Finalizer interface { + // FinalizeKind implements custom logic to finalize v1alpha1.TektonScheduler. Any changes + // to the objects .Status or .Finalizers will be ignored. Returning a nil or + // Normal type reconciler.Event will allow the finalizer to be deleted on + // the resource. The resource passed to FinalizeKind will always have a set + // deletion timestamp. + FinalizeKind(ctx context.Context, o *v1alpha1.TektonScheduler) reconciler.Event +} + +// ReadOnlyInterface defines the strongly typed interfaces to be implemented by a +// controller reconciling v1alpha1.TektonScheduler if they want to process resources for which +// they are not the leader. +type ReadOnlyInterface interface { + // ObserveKind implements logic to observe v1alpha1.TektonScheduler. + // This method should not write to the API. + ObserveKind(ctx context.Context, o *v1alpha1.TektonScheduler) reconciler.Event +} + +type doReconcile func(ctx context.Context, o *v1alpha1.TektonScheduler) reconciler.Event + +// reconcilerImpl implements controller.Reconciler for v1alpha1.TektonScheduler resources. +type reconcilerImpl struct { + // LeaderAwareFuncs is inlined to help us implement reconciler.LeaderAware. + reconciler.LeaderAwareFuncs + + // Client is used to write back status updates. + Client versioned.Interface + + // Listers index properties about resources. + Lister operatorv1alpha1.TektonSchedulerLister + + // Recorder is an event recorder for recording Event resources to the + // Kubernetes API. + Recorder record.EventRecorder + + // configStore allows for decorating a context with config maps. + // +optional + configStore reconciler.ConfigStore + + // reconciler is the implementation of the business logic of the resource. + reconciler Interface + + // finalizerName is the name of the finalizer to reconcile. + finalizerName string + + // skipStatusUpdates configures whether or not this reconciler automatically updates + // the status of the reconciled resource. + skipStatusUpdates bool +} + +// Check that our Reconciler implements controller.Reconciler. +var _ controller.Reconciler = (*reconcilerImpl)(nil) + +// Check that our generated Reconciler is always LeaderAware. +var _ reconciler.LeaderAware = (*reconcilerImpl)(nil) + +func NewReconciler(ctx context.Context, logger *zap.SugaredLogger, client versioned.Interface, lister operatorv1alpha1.TektonSchedulerLister, recorder record.EventRecorder, r Interface, options ...controller.Options) controller.Reconciler { + // Check the options function input. It should be 0 or 1. + if len(options) > 1 { + logger.Fatal("Up to one options struct is supported, found: ", len(options)) + } + + // Fail fast when users inadvertently implement the other LeaderAware interface. + // For the typed reconcilers, Promote shouldn't take any arguments. + if _, ok := r.(reconciler.LeaderAware); ok { + logger.Fatalf("%T implements the incorrect LeaderAware interface. Promote() should not take an argument as genreconciler handles the enqueuing automatically.", r) + } + + rec := &reconcilerImpl{ + LeaderAwareFuncs: reconciler.LeaderAwareFuncs{ + PromoteFunc: func(bkt reconciler.Bucket, enq func(reconciler.Bucket, types.NamespacedName)) error { + all, err := lister.List(labels.Everything()) + if err != nil { + return err + } + for _, elt := range all { + // TODO: Consider letting users specify a filter in options. + enq(bkt, types.NamespacedName{ + Namespace: elt.GetNamespace(), + Name: elt.GetName(), + }) + } + return nil + }, + }, + Client: client, + Lister: lister, + Recorder: recorder, + reconciler: r, + finalizerName: defaultFinalizerName, + } + + for _, opts := range options { + if opts.ConfigStore != nil { + rec.configStore = opts.ConfigStore + } + if opts.FinalizerName != "" { + rec.finalizerName = opts.FinalizerName + } + if opts.SkipStatusUpdates { + rec.skipStatusUpdates = true + } + if opts.DemoteFunc != nil { + rec.DemoteFunc = opts.DemoteFunc + } + } + + return rec +} + +// Reconcile implements controller.Reconciler +func (r *reconcilerImpl) Reconcile(ctx context.Context, key string) error { + logger := logging.FromContext(ctx) + + // Initialize the reconciler state. This will convert the namespace/name + // string into a distinct namespace and name, determine if this instance of + // the reconciler is the leader, and any additional interfaces implemented + // by the reconciler. Returns an error is the resource key is invalid. + s, err := newState(key, r) + if err != nil { + logger.Error("Invalid resource key: ", key) + return nil + } + + // If we are not the leader, and we don't implement either ReadOnly + // observer interfaces, then take a fast-path out. + if s.isNotLeaderNorObserver() { + return controller.NewSkipKey(key) + } + + // If configStore is set, attach the frozen configuration to the context. + if r.configStore != nil { + ctx = r.configStore.ToContext(ctx) + } + + // Add the recorder to context. + ctx = controller.WithEventRecorder(ctx, r.Recorder) + + // Get the resource with this namespace/name. + + getter := r.Lister + + original, err := getter.Get(s.name) + + if errors.IsNotFound(err) { + // The resource may no longer exist, in which case we stop processing and call + // the ObserveDeletion handler if appropriate. + logger.Debugf("Resource %q no longer exists", key) + if del, ok := r.reconciler.(reconciler.OnDeletionInterface); ok { + return del.ObserveDeletion(ctx, types.NamespacedName{ + Namespace: s.namespace, + Name: s.name, + }) + } + return nil + } else if err != nil { + return err + } + + // Don't modify the informers copy. + resource := original.DeepCopy() + + var reconcileEvent reconciler.Event + + name, do := s.reconcileMethodFor(resource) + // Append the target method to the logger. + logger = logger.With(zap.String("targetMethod", name)) + switch name { + case reconciler.DoReconcileKind: + // Set and update the finalizer on resource if r.reconciler + // implements Finalizer. + if resource, err = r.setFinalizerIfFinalizer(ctx, resource); err != nil { + return fmt.Errorf("failed to set finalizers: %w", err) + } + + // Reconcile this copy of the resource and then write back any status + // updates regardless of whether the reconciliation errored out. + reconcileEvent = do(ctx, resource) + + case reconciler.DoFinalizeKind: + // For finalizing reconcilers, if this resource being marked for deletion + // and reconciled cleanly (nil or normal event), remove the finalizer. + reconcileEvent = do(ctx, resource) + + if resource, err = r.clearFinalizer(ctx, resource, reconcileEvent); err != nil { + return fmt.Errorf("failed to clear finalizers: %w", err) + } + + case reconciler.DoObserveKind: + // Observe any changes to this resource, since we are not the leader. + reconcileEvent = do(ctx, resource) + + } + + // Synchronize the status. + switch { + case r.skipStatusUpdates: + // This reconciler implementation is configured to skip resource updates. + // This may mean this reconciler does not observe spec, but reconciles external changes. + case equality.Semantic.DeepEqual(original.Status, resource.Status): + // If we didn't change anything then don't call updateStatus. + // This is important because the copy we loaded from the injectionInformer's + // cache may be stale and we don't want to overwrite a prior update + // to status with this stale state. + case !s.isLeader: + // High-availability reconcilers may have many replicas watching the resource, but only + // the elected leader is expected to write modifications. + logger.Warn("Saw status changes when we aren't the leader!") + default: + if err = r.updateStatus(ctx, logger, original, resource); err != nil { + logger.Warnw("Failed to update resource status", zap.Error(err)) + r.Recorder.Eventf(resource, v1.EventTypeWarning, "UpdateFailed", + "Failed to update status for %q: %v", resource.Name, err) + return err + } + } + + // Report the reconciler event, if any. + if reconcileEvent != nil { + var event *reconciler.ReconcilerEvent + if reconciler.EventAs(reconcileEvent, &event) { + logger.Infow("Returned an event", zap.Any("event", reconcileEvent)) + r.Recorder.Event(resource, event.EventType, event.Reason, event.Error()) + + // the event was wrapped inside an error, consider the reconciliation as failed + if _, isEvent := reconcileEvent.(*reconciler.ReconcilerEvent); !isEvent { + return reconcileEvent + } + return nil + } + + if controller.IsSkipKey(reconcileEvent) { + // This is a wrapped error, don't emit an event. + } else if ok, _ := controller.IsRequeueKey(reconcileEvent); ok { + // This is a wrapped error, don't emit an event. + } else { + logger.Errorw("Returned an error", zap.Error(reconcileEvent)) + r.Recorder.Event(resource, v1.EventTypeWarning, "InternalError", reconcileEvent.Error()) + } + return reconcileEvent + } + + return nil +} + +func (r *reconcilerImpl) updateStatus(ctx context.Context, logger *zap.SugaredLogger, existing *v1alpha1.TektonScheduler, desired *v1alpha1.TektonScheduler) error { + existing = existing.DeepCopy() + return reconciler.RetryUpdateConflicts(func(attempts int) (err error) { + // The first iteration tries to use the injectionInformer's state, subsequent attempts fetch the latest state via API. + if attempts > 0 { + + getter := r.Client.OperatorV1alpha1().TektonSchedulers() + + existing, err = getter.Get(ctx, desired.Name, metav1.GetOptions{}) + if err != nil { + return err + } + } + + // If there's nothing to update, just return. + if equality.Semantic.DeepEqual(existing.Status, desired.Status) { + return nil + } + + if logger.Desugar().Core().Enabled(zapcore.DebugLevel) { + if diff, err := kmp.SafeDiff(existing.Status, desired.Status); err == nil && diff != "" { + logger.Debug("Updating status with: ", diff) + } + } + + existing.Status = desired.Status + + updater := r.Client.OperatorV1alpha1().TektonSchedulers() + + _, err = updater.UpdateStatus(ctx, existing, metav1.UpdateOptions{}) + return err + }) +} + +// updateFinalizersFiltered will update the Finalizers of the resource. +// TODO: this method could be generic and sync all finalizers. For now it only +// updates defaultFinalizerName or its override. +func (r *reconcilerImpl) updateFinalizersFiltered(ctx context.Context, resource *v1alpha1.TektonScheduler, desiredFinalizers sets.Set[string]) (*v1alpha1.TektonScheduler, error) { + // Don't modify the informers copy. + existing := resource.DeepCopy() + + var finalizers []string + + // If there's nothing to update, just return. + existingFinalizers := sets.New[string](existing.Finalizers...) + + if desiredFinalizers.Has(r.finalizerName) { + if existingFinalizers.Has(r.finalizerName) { + // Nothing to do. + return resource, nil + } + // Add the finalizer. + finalizers = append(existing.Finalizers, r.finalizerName) + } else { + if !existingFinalizers.Has(r.finalizerName) { + // Nothing to do. + return resource, nil + } + // Remove the finalizer. + existingFinalizers.Delete(r.finalizerName) + finalizers = sets.List(existingFinalizers) + } + + mergePatch := map[string]interface{}{ + "metadata": map[string]interface{}{ + "finalizers": finalizers, + "resourceVersion": existing.ResourceVersion, + }, + } + + patch, err := json.Marshal(mergePatch) + if err != nil { + return resource, err + } + + patcher := r.Client.OperatorV1alpha1().TektonSchedulers() + + resourceName := resource.Name + updated, err := patcher.Patch(ctx, resourceName, types.MergePatchType, patch, metav1.PatchOptions{}) + if err != nil { + r.Recorder.Eventf(existing, v1.EventTypeWarning, "FinalizerUpdateFailed", + "Failed to update finalizers for %q: %v", resourceName, err) + } else { + r.Recorder.Eventf(updated, v1.EventTypeNormal, "FinalizerUpdate", + "Updated %q finalizers", resource.GetName()) + } + return updated, err +} + +func (r *reconcilerImpl) setFinalizerIfFinalizer(ctx context.Context, resource *v1alpha1.TektonScheduler) (*v1alpha1.TektonScheduler, error) { + if _, ok := r.reconciler.(Finalizer); !ok { + return resource, nil + } + + finalizers := sets.New[string](resource.Finalizers...) + + // If this resource is not being deleted, mark the finalizer. + if resource.GetDeletionTimestamp().IsZero() { + finalizers.Insert(r.finalizerName) + } + + // Synchronize the finalizers filtered by r.finalizerName. + return r.updateFinalizersFiltered(ctx, resource, finalizers) +} + +func (r *reconcilerImpl) clearFinalizer(ctx context.Context, resource *v1alpha1.TektonScheduler, reconcileEvent reconciler.Event) (*v1alpha1.TektonScheduler, error) { + if _, ok := r.reconciler.(Finalizer); !ok { + return resource, nil + } + if resource.GetDeletionTimestamp().IsZero() { + return resource, nil + } + + finalizers := sets.New[string](resource.Finalizers...) + + if reconcileEvent != nil { + var event *reconciler.ReconcilerEvent + if reconciler.EventAs(reconcileEvent, &event) { + if event.EventType == v1.EventTypeNormal { + finalizers.Delete(r.finalizerName) + } + } + } else { + finalizers.Delete(r.finalizerName) + } + + // Synchronize the finalizers filtered by r.finalizerName. + return r.updateFinalizersFiltered(ctx, resource, finalizers) +} diff --git a/pkg/client/injection/reconciler/operator/v1alpha1/tektonscheduler/state.go b/pkg/client/injection/reconciler/operator/v1alpha1/tektonscheduler/state.go new file mode 100644 index 0000000000..e46cd70005 --- /dev/null +++ b/pkg/client/injection/reconciler/operator/v1alpha1/tektonscheduler/state.go @@ -0,0 +1,97 @@ +/* +Copyright 2020 The Tekton Authors + +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. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package tektonscheduler + +import ( + fmt "fmt" + + v1alpha1 "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" + types "k8s.io/apimachinery/pkg/types" + cache "k8s.io/client-go/tools/cache" + reconciler "knative.dev/pkg/reconciler" +) + +// state is used to track the state of a reconciler in a single run. +type state struct { + // key is the original reconciliation key from the queue. + key string + // namespace is the namespace split from the reconciliation key. + namespace string + // name is the name split from the reconciliation key. + name string + // reconciler is the reconciler. + reconciler Interface + // roi is the read only interface cast of the reconciler. + roi ReadOnlyInterface + // isROI (Read Only Interface) the reconciler only observes reconciliation. + isROI bool + // isLeader the instance of the reconciler is the elected leader. + isLeader bool +} + +func newState(key string, r *reconcilerImpl) (*state, error) { + // Convert the namespace/name string into a distinct namespace and name. + namespace, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + return nil, fmt.Errorf("invalid resource key: %s", key) + } + + roi, isROI := r.reconciler.(ReadOnlyInterface) + + isLeader := r.IsLeaderFor(types.NamespacedName{ + Namespace: namespace, + Name: name, + }) + + return &state{ + key: key, + namespace: namespace, + name: name, + reconciler: r.reconciler, + roi: roi, + isROI: isROI, + isLeader: isLeader, + }, nil +} + +// isNotLeaderNorObserver checks to see if this reconciler with the current +// state is enabled to do any work or not. +// isNotLeaderNorObserver returns true when there is no work possible for the +// reconciler. +func (s *state) isNotLeaderNorObserver() bool { + if !s.isLeader && !s.isROI { + // If we are not the leader, and we don't implement the ReadOnly + // interface, then take a fast-path out. + return true + } + return false +} + +func (s *state) reconcileMethodFor(o *v1alpha1.TektonScheduler) (string, doReconcile) { + if o.GetDeletionTimestamp().IsZero() { + if s.isLeader { + return reconciler.DoReconcileKind, s.reconciler.ReconcileKind + } else if s.isROI { + return reconciler.DoObserveKind, s.roi.ObserveKind + } + } else if fin, ok := s.reconciler.(Finalizer); s.isLeader && ok { + return reconciler.DoFinalizeKind, fin.FinalizeKind + } + return "unknown", nil +} diff --git a/pkg/client/listers/operator/v1alpha1/expansion_generated.go b/pkg/client/listers/operator/v1alpha1/expansion_generated.go index 0b30636585..bfec8dc2bf 100644 --- a/pkg/client/listers/operator/v1alpha1/expansion_generated.go +++ b/pkg/client/listers/operator/v1alpha1/expansion_generated.go @@ -62,6 +62,10 @@ type TektonPrunerListerExpansion interface{} // TektonResultLister. type TektonResultListerExpansion interface{} +// TektonSchedulerListerExpansion allows custom methods to be added to +// TektonSchedulerLister. +type TektonSchedulerListerExpansion interface{} + // TektonTriggerListerExpansion allows custom methods to be added to // TektonTriggerLister. type TektonTriggerListerExpansion interface{} diff --git a/pkg/client/listers/operator/v1alpha1/tektonscheduler.go b/pkg/client/listers/operator/v1alpha1/tektonscheduler.go new file mode 100644 index 0000000000..6f31c3d382 --- /dev/null +++ b/pkg/client/listers/operator/v1alpha1/tektonscheduler.go @@ -0,0 +1,48 @@ +/* +Copyright 2020 The Tekton Authors + +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + operatorv1alpha1 "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" +) + +// TektonSchedulerLister helps list TektonSchedulers. +// All objects returned here must be treated as read-only. +type TektonSchedulerLister interface { + // List lists all TektonSchedulers in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*operatorv1alpha1.TektonScheduler, err error) + // Get retrieves the TektonScheduler from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*operatorv1alpha1.TektonScheduler, error) + TektonSchedulerListerExpansion +} + +// tektonSchedulerLister implements the TektonSchedulerLister interface. +type tektonSchedulerLister struct { + listers.ResourceIndexer[*operatorv1alpha1.TektonScheduler] +} + +// NewTektonSchedulerLister returns a new TektonSchedulerLister. +func NewTektonSchedulerLister(indexer cache.Indexer) TektonSchedulerLister { + return &tektonSchedulerLister{listers.New[*operatorv1alpha1.TektonScheduler](indexer, operatorv1alpha1.Resource("tektonscheduler"))} +} From b77d87e587ca3c20f64b80e6ce050e123d10f955 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:33:58 +0000 Subject: [PATCH 02/13] chore(deps): bump github/codeql-action from 4.31.9 to 4.31.10 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.31.9 to 4.31.10. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/5d4e8d1aca955e8d8589aabd499c5cae939e33c7...cdefb33c0f6224e58673d9004f47f7cb3e328b89) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.31.10 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 0ef879e7f3..3dabd52f9d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -44,7 +44,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 + uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -77,4 +77,4 @@ jobs: make bin/tool - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 + uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10 From f68a9c435bce9c044e82d693ac0d84698c89a9b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:35:11 +0000 Subject: [PATCH 03/13] chore(deps): bump golang.org/x/mod from 0.31.0 to 0.32.0 Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.31.0 to 0.32.0. - [Commits](https://github.com/golang/mod/compare/v0.31.0...v0.32.0) --- updated-dependencies: - dependency-name: golang.org/x/mod dependency-version: 0.32.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 14 +- go.sum | 28 +- vendor/golang.org/x/net/http2/transport.go | 160 ++++- vendor/golang.org/x/net/trace/events.go | 2 +- vendor/golang.org/x/sys/cpu/cpu.go | 3 - vendor/golang.org/x/sys/cpu/cpu_arm64.go | 20 +- vendor/golang.org/x/sys/cpu/cpu_arm64.s | 7 - vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go | 1 - .../golang.org/x/sys/cpu/cpu_gccgo_arm64.go | 1 - .../golang.org/x/sys/cpu/cpu_netbsd_arm64.go | 2 +- .../golang.org/x/sys/cpu/cpu_openbsd_arm64.go | 2 +- vendor/golang.org/x/sys/unix/mkerrors.sh | 3 +- vendor/golang.org/x/sys/unix/zerrors_linux.go | 2 + .../x/sys/unix/zerrors_linux_386.go | 2 + .../x/sys/unix/zerrors_linux_amd64.go | 2 + .../x/sys/unix/zerrors_linux_arm.go | 2 + .../x/sys/unix/zerrors_linux_arm64.go | 2 + .../x/sys/unix/zerrors_linux_loong64.go | 2 + .../x/sys/unix/zerrors_linux_mips.go | 2 + .../x/sys/unix/zerrors_linux_mips64.go | 2 + .../x/sys/unix/zerrors_linux_mips64le.go | 2 + .../x/sys/unix/zerrors_linux_mipsle.go | 2 + .../x/sys/unix/zerrors_linux_ppc.go | 2 + .../x/sys/unix/zerrors_linux_ppc64.go | 2 + .../x/sys/unix/zerrors_linux_ppc64le.go | 2 + .../x/sys/unix/zerrors_linux_riscv64.go | 2 + .../x/sys/unix/zerrors_linux_s390x.go | 2 + .../x/sys/unix/zerrors_linux_sparc64.go | 2 + .../x/sys/unix/ztypes_netbsd_arm.go | 2 +- .../x/text/encoding/unicode/unicode.go | 6 +- .../x/tools/go/ast/astutil/imports.go | 19 +- .../x/tools/go/packages/packages.go | 41 +- .../x/tools/go/types/typeutil/callee.go | 1 + .../x/tools/internal/event/core/export.go | 15 +- .../x/tools/internal/event/label/label.go | 12 +- .../x/tools/internal/imports/sortimports.go | 23 +- .../x/tools/internal/modindex/lookup.go | 8 +- .../x/tools/internal/stdlib/deps.go | 626 +++++++++--------- .../x/tools/internal/stdlib/manifest.go | 549 ++++++++++++++- .../x/tools/internal/stdlib/stdlib.go | 2 +- .../internal/typesinternal/classify_call.go | 2 +- .../x/tools/internal/typesinternal/types.go | 4 +- .../x/tools/internal/versions/features.go | 1 + vendor/modules.txt | 14 +- 44 files changed, 1150 insertions(+), 450 deletions(-) diff --git a/go.mod b/go.mod index 16c7ce2196..a5b3d9b8e2 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( go.opencensus.io v0.24.0 go.uber.org/zap v1.27.1 golang.org/x/exp v0.0.0-20250911091902-df9299821621 - golang.org/x/mod v0.31.0 + golang.org/x/mod v0.32.0 golang.org/x/sync v0.19.0 gomodules.xyz/jsonpatch/v2 v2.5.0 gopkg.in/yaml.v3 v3.0.1 @@ -289,14 +289,14 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/net v0.47.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/net v0.48.0 // indirect golang.org/x/oauth2 v0.32.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.13.0 // indirect - golang.org/x/tools v0.39.0 // indirect + golang.org/x/tools v0.40.0 // indirect google.golang.org/api v0.249.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 // indirect diff --git a/go.sum b/go.sum index 8851e88c31..8a1a90f036 100644 --- a/go.sum +++ b/go.sum @@ -2881,8 +2881,8 @@ golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5D golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -2958,8 +2958,8 @@ golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= -golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= +golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -3053,8 +3053,8 @@ golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -3249,8 +3249,8 @@ golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -3279,8 +3279,8 @@ golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -3306,8 +3306,8 @@ golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -3407,8 +3407,8 @@ golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxb golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM= golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index 1965913e54..ccb87e6da3 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -376,11 +376,24 @@ type ClientConn struct { // completely unresponsive connection. pendingResets int + // readBeforeStreamID is the smallest stream ID that has not been followed by + // a frame read from the peer. We use this to determine when a request may + // have been sent to a completely unresponsive connection: + // If the request ID is less than readBeforeStreamID, then we have had some + // indication of life on the connection since sending the request. + readBeforeStreamID uint32 + // reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests. // Write to reqHeaderMu to lock it, read from it to unlock. // Lock reqmu BEFORE mu or wmu. reqHeaderMu chan struct{} + // internalStateHook reports state changes back to the net/http.ClientConn. + // Note that this is different from the user state hook registered by + // net/http.ClientConn.SetStateHook: The internal hook calls ClientConn, + // which calls the user hook. + internalStateHook func() + // wmu is held while writing. // Acquire BEFORE mu when holding both, to avoid blocking mu on network writes. // Only acquire both at the same time when changing peer settings. @@ -710,7 +723,7 @@ func canRetryError(err error) bool { func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) { if t.transportTestHooks != nil { - return t.newClientConn(nil, singleUse) + return t.newClientConn(nil, singleUse, nil) } host, _, err := net.SplitHostPort(addr) if err != nil { @@ -720,7 +733,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b if err != nil { return nil, err } - return t.newClientConn(tconn, singleUse) + return t.newClientConn(tconn, singleUse, nil) } func (t *Transport) newTLSConfig(host string) *tls.Config { @@ -772,10 +785,10 @@ func (t *Transport) expectContinueTimeout() time.Duration { } func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { - return t.newClientConn(c, t.disableKeepAlives()) + return t.newClientConn(c, t.disableKeepAlives(), nil) } -func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) { +func (t *Transport) newClientConn(c net.Conn, singleUse bool, internalStateHook func()) (*ClientConn, error) { conf := configFromTransport(t) cc := &ClientConn{ t: t, @@ -797,6 +810,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro pings: make(map[[8]byte]chan struct{}), reqHeaderMu: make(chan struct{}, 1), lastActive: time.Now(), + internalStateHook: internalStateHook, } if t.transportTestHooks != nil { t.transportTestHooks.newclientconn(cc) @@ -1037,10 +1051,7 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { maxConcurrentOkay = cc.currentRequestCountLocked() < int(cc.maxConcurrentStreams) } - st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay && - !cc.doNotReuse && - int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 && - !cc.tooIdleLocked() + st.canTakeNewRequest = maxConcurrentOkay && cc.isUsableLocked() // If this connection has never been used for a request and is closed, // then let it take a request (which will fail). @@ -1056,6 +1067,31 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) { return } +func (cc *ClientConn) isUsableLocked() bool { + return cc.goAway == nil && + !cc.closed && + !cc.closing && + !cc.doNotReuse && + int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 && + !cc.tooIdleLocked() +} + +// canReserveLocked reports whether a net/http.ClientConn can reserve a slot on this conn. +// +// This follows slightly different rules than clientConnIdleState.canTakeNewRequest. +// We only permit reservations up to the conn's concurrency limit. +// This differs from ClientConn.ReserveNewRequest, which permits reservations +// past the limit when StrictMaxConcurrentStreams is set. +func (cc *ClientConn) canReserveLocked() bool { + if cc.currentRequestCountLocked() >= int(cc.maxConcurrentStreams) { + return false + } + if !cc.isUsableLocked() { + return false + } + return true +} + // currentRequestCountLocked reports the number of concurrency slots currently in use, // including active streams, reserved slots, and reset streams waiting for acknowledgement. func (cc *ClientConn) currentRequestCountLocked() int { @@ -1067,6 +1103,14 @@ func (cc *ClientConn) canTakeNewRequestLocked() bool { return st.canTakeNewRequest } +// availableLocked reports the number of concurrency slots available. +func (cc *ClientConn) availableLocked() int { + if !cc.canTakeNewRequestLocked() { + return 0 + } + return max(0, int(cc.maxConcurrentStreams)-cc.currentRequestCountLocked()) +} + // tooIdleLocked reports whether this connection has been been sitting idle // for too much wall time. func (cc *ClientConn) tooIdleLocked() bool { @@ -1091,6 +1135,7 @@ func (cc *ClientConn) closeConn() { t := time.AfterFunc(250*time.Millisecond, cc.forceCloseConn) defer t.Stop() cc.tconn.Close() + cc.maybeCallStateHook() } // A tls.Conn.Close can hang for a long time if the peer is unresponsive. @@ -1616,6 +1661,8 @@ func (cs *clientStream) cleanupWriteRequest(err error) { } bodyClosed := cs.reqBodyClosed closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil + // Have we read any frames from the connection since sending this request? + readSinceStream := cc.readBeforeStreamID > cs.ID cc.mu.Unlock() if mustCloseBody { cs.reqBody.Close() @@ -1647,8 +1694,10 @@ func (cs *clientStream) cleanupWriteRequest(err error) { // // This could be due to the server becoming unresponsive. // To avoid sending too many requests on a dead connection, - // we let the request continue to consume a concurrency slot - // until we can confirm the server is still responding. + // if we haven't read any frames from the connection since + // sending this request, we let it continue to consume + // a concurrency slot until we can confirm the server is + // still responding. // We do this by sending a PING frame along with the RST_STREAM // (unless a ping is already in flight). // @@ -1659,7 +1708,7 @@ func (cs *clientStream) cleanupWriteRequest(err error) { // because it's short lived and will probably be closed before // we get the ping response. ping := false - if !closeOnIdle { + if !closeOnIdle && !readSinceStream { cc.mu.Lock() // rstStreamPingsBlocked works around a gRPC behavior: // see comment on the field for details. @@ -1693,6 +1742,7 @@ func (cs *clientStream) cleanupWriteRequest(err error) { } close(cs.donec) + cc.maybeCallStateHook() } // awaitOpenSlotForStreamLocked waits until len(streams) < maxConcurrentStreams. @@ -2745,6 +2795,7 @@ func (rl *clientConnReadLoop) streamByID(id uint32, headerOrData bool) *clientSt // See comment on ClientConn.rstStreamPingsBlocked for details. rl.cc.rstStreamPingsBlocked = false } + rl.cc.readBeforeStreamID = rl.cc.nextStreamID cs := rl.cc.streams[id] if cs != nil && !cs.readAborted { return cs @@ -2795,6 +2846,7 @@ func (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error { func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error { cc := rl.cc + defer cc.maybeCallStateHook() cc.mu.Lock() defer cc.mu.Unlock() @@ -2975,6 +3027,7 @@ func (cc *ClientConn) Ping(ctx context.Context) error { func (rl *clientConnReadLoop) processPing(f *PingFrame) error { if f.IsAck() { cc := rl.cc + defer cc.maybeCallStateHook() cc.mu.Lock() defer cc.mu.Unlock() // If ack, notify listener if any @@ -3198,9 +3251,13 @@ func registerHTTPSProtocol(t *http.Transport, rt noDialH2RoundTripper) (err erro } // noDialH2RoundTripper is a RoundTripper which only tries to complete the request -// if there's already has a cached connection to the host. +// if there's already a cached connection to the host. // (The field is exported so it can be accessed via reflect from net/http; tested // by TestNoDialH2RoundTripperType) +// +// A noDialH2RoundTripper is registered with http1.Transport.RegisterProtocol, +// and the http1.Transport can use type assertions to call non-RoundTrip methods on it. +// This lets us expose, for example, NewClientConn to net/http. type noDialH2RoundTripper struct{ *Transport } func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { @@ -3211,6 +3268,85 @@ func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, err return res, err } +func (rt noDialH2RoundTripper) NewClientConn(conn net.Conn, internalStateHook func()) (http.RoundTripper, error) { + tr := rt.Transport + cc, err := tr.newClientConn(conn, tr.disableKeepAlives(), internalStateHook) + if err != nil { + return nil, err + } + + // RoundTrip should block when the conn is at its concurrency limit, + // not return an error. Setting strictMaxConcurrentStreams enables this. + cc.strictMaxConcurrentStreams = true + + return netHTTPClientConn{cc}, nil +} + +// netHTTPClientConn wraps ClientConn and implements the interface net/http expects from +// the RoundTripper returned by NewClientConn. +type netHTTPClientConn struct { + cc *ClientConn +} + +func (cc netHTTPClientConn) RoundTrip(req *http.Request) (*http.Response, error) { + return cc.cc.RoundTrip(req) +} + +func (cc netHTTPClientConn) Close() error { + return cc.cc.Close() +} + +func (cc netHTTPClientConn) Err() error { + cc.cc.mu.Lock() + defer cc.cc.mu.Unlock() + if cc.cc.closed { + return errors.New("connection closed") + } + return nil +} + +func (cc netHTTPClientConn) Reserve() error { + defer cc.cc.maybeCallStateHook() + cc.cc.mu.Lock() + defer cc.cc.mu.Unlock() + if !cc.cc.canReserveLocked() { + return errors.New("connection is unavailable") + } + cc.cc.streamsReserved++ + return nil +} + +func (cc netHTTPClientConn) Release() { + defer cc.cc.maybeCallStateHook() + cc.cc.mu.Lock() + defer cc.cc.mu.Unlock() + // We don't complain if streamsReserved is 0. + // + // This is consistent with RoundTrip: both Release and RoundTrip will + // consume a reservation iff one exists. + if cc.cc.streamsReserved > 0 { + cc.cc.streamsReserved-- + } +} + +func (cc netHTTPClientConn) Available() int { + cc.cc.mu.Lock() + defer cc.cc.mu.Unlock() + return cc.cc.availableLocked() +} + +func (cc netHTTPClientConn) InFlight() int { + cc.cc.mu.Lock() + defer cc.cc.mu.Unlock() + return cc.cc.currentRequestCountLocked() +} + +func (cc *ClientConn) maybeCallStateHook() { + if cc.internalStateHook != nil { + cc.internalStateHook() + } +} + func (t *Transport) idleConnTimeout() time.Duration { // to keep things backwards compatible, we use non-zero values of // IdleConnTimeout, followed by using the IdleConnTimeout on the underlying diff --git a/vendor/golang.org/x/net/trace/events.go b/vendor/golang.org/x/net/trace/events.go index 3aaffdd1f7..c2b3c00980 100644 --- a/vendor/golang.org/x/net/trace/events.go +++ b/vendor/golang.org/x/net/trace/events.go @@ -58,8 +58,8 @@ func RenderEvents(w http.ResponseWriter, req *http.Request, sensitive bool) { Buckets: buckets, } - data.Families = make([]string, 0, len(families)) famMu.RLock() + data.Families = make([]string, 0, len(families)) for name := range families { data.Families = append(data.Families, name) } diff --git a/vendor/golang.org/x/sys/cpu/cpu.go b/vendor/golang.org/x/sys/cpu/cpu.go index 34c9ae76ef..63541994ef 100644 --- a/vendor/golang.org/x/sys/cpu/cpu.go +++ b/vendor/golang.org/x/sys/cpu/cpu.go @@ -92,9 +92,6 @@ var ARM64 struct { HasSHA2 bool // SHA2 hardware implementation HasCRC32 bool // CRC32 hardware implementation HasATOMICS bool // Atomic memory operation instruction set - HasHPDS bool // Hierarchical permission disables in translations tables - HasLOR bool // Limited ordering regions - HasPAN bool // Privileged access never HasFPHP bool // Half precision floating-point instruction set HasASIMDHP bool // Advanced SIMD half precision instruction set HasCPUID bool // CPUID identification scheme registers diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_arm64.go index f449c679fe..af2aa99f9f 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.go @@ -65,10 +65,10 @@ func setMinimalFeatures() { func readARM64Registers() { Initialized = true - parseARM64SystemRegisters(getisar0(), getisar1(), getmmfr1(), getpfr0()) + parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0()) } -func parseARM64SystemRegisters(isar0, isar1, mmfr1, pfr0 uint64) { +func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) { // ID_AA64ISAR0_EL1 switch extractBits(isar0, 4, 7) { case 1: @@ -152,22 +152,6 @@ func parseARM64SystemRegisters(isar0, isar1, mmfr1, pfr0 uint64) { ARM64.HasI8MM = true } - // ID_AA64MMFR1_EL1 - switch extractBits(mmfr1, 12, 15) { - case 1, 2: - ARM64.HasHPDS = true - } - - switch extractBits(mmfr1, 16, 19) { - case 1: - ARM64.HasLOR = true - } - - switch extractBits(mmfr1, 20, 23) { - case 1, 2, 3: - ARM64.HasPAN = true - } - // ID_AA64PFR0_EL1 switch extractBits(pfr0, 16, 19) { case 0: diff --git a/vendor/golang.org/x/sys/cpu/cpu_arm64.s b/vendor/golang.org/x/sys/cpu/cpu_arm64.s index a4f24b3b0c..3b0450a06a 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_arm64.s +++ b/vendor/golang.org/x/sys/cpu/cpu_arm64.s @@ -20,13 +20,6 @@ TEXT ·getisar1(SB),NOSPLIT,$0-8 MOVD R0, ret+0(FP) RET -// func getmmfr1() uint64 -TEXT ·getmmfr1(SB),NOSPLIT,$0-8 - // get Memory Model Feature Register 1 into x0 - MRS ID_AA64MMFR1_EL1, R0 - MOVD R0, ret+0(FP) - RET - // func getpfr0() uint64 TEXT ·getpfr0(SB),NOSPLIT,$0-8 // get Processor Feature Register 0 into x0 diff --git a/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go index e3fc5a8d31..6ac6e1efb2 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go @@ -8,6 +8,5 @@ package cpu func getisar0() uint64 func getisar1() uint64 -func getmmfr1() uint64 func getpfr0() uint64 func getzfr0() uint64 diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go index 8df2079e15..7f1946780b 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go @@ -8,5 +8,4 @@ package cpu func getisar0() uint64 { return 0 } func getisar1() uint64 { return 0 } -func getmmfr1() uint64 { return 0 } func getpfr0() uint64 { return 0 } diff --git a/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go index 19aea0633e..ebfb3fc8e7 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go @@ -167,7 +167,7 @@ func doinit() { setMinimalFeatures() return } - parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64mmfr1, cpuid.aa64pfr0) + parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64pfr0) Initialized = true } diff --git a/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go index 87fd3a7780..85b64d5ccb 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go @@ -59,7 +59,7 @@ func doinit() { if !ok { return } - parseARM64SystemRegisters(isar0, isar1, 0, 0) + parseARM64SystemRegisters(isar0, isar1, 0) Initialized = true } diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 42517077c4..fd39be4efd 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -256,6 +256,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -613,7 +614,7 @@ ccflags="$@" $2 !~ /IOC_MAGIC/ && $2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ || $2 ~ /^(VM|VMADDR)_/ || - $2 ~ /^IOCTL_VM_SOCKETS_/ || + $2 ~ /^(IOCTL_VM_SOCKETS_|IOCTL_MEI_)/ || $2 ~ /^(TASKSTATS|TS)_/ || $2 ~ /^CGROUPSTATS_/ || $2 ~ /^GENL_/ || diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index d0a75da572..120a7b35d1 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -1615,6 +1615,8 @@ const ( IN_OPEN = 0x20 IN_Q_OVERFLOW = 0x4000 IN_UNMOUNT = 0x2000 + IOCTL_MEI_CONNECT_CLIENT = 0xc0104801 + IOCTL_MEI_CONNECT_CLIENT_VTAG = 0xc0144804 IPPROTO_AH = 0x33 IPPROTO_BEETPH = 0x5e IPPROTO_COMP = 0x6c diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 1c37f9fbc4..97a61fc5b8 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -116,6 +116,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index 6f54d34aef..a0d6d498c4 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -116,6 +116,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index 783ec5c126..dd9c903f9a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -115,6 +115,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index ca83d3ba16..384c61ca3a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -120,6 +120,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 607e611c0c..6384c9831f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -116,6 +116,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index b9cb5bd3c0..553c1c6f15 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -115,6 +115,8 @@ const ( IEXTEN = 0x100 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xfffffff IPV6_FLOWLABEL_MASK = 0xfffff diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 65b078a638..b3339f2099 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -115,6 +115,8 @@ const ( IEXTEN = 0x100 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xfffffff IPV6_FLOWLABEL_MASK = 0xfffff diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 5298a3033d..177091d2bc 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -115,6 +115,8 @@ const ( IEXTEN = 0x100 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 7bc557c876..c5abf156d0 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -115,6 +115,8 @@ const ( IEXTEN = 0x100 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index 152399bb04..f1f3fadf57 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -115,6 +115,8 @@ const ( IEXTEN = 0x400 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xfffffff IPV6_FLOWLABEL_MASK = 0xfffff diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 1a1ce2409c..203ad9c54a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -115,6 +115,8 @@ const ( IEXTEN = 0x400 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xfffffff IPV6_FLOWLABEL_MASK = 0xfffff diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 4231a1fb57..4b9abcb21a 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -115,6 +115,8 @@ const ( IEXTEN = 0x400 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 21c0e95266..f87983037d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -115,6 +115,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index f00d1cd7cf..64347eb354 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -115,6 +115,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 + IOCTL_MEI_NOTIFY_GET = 0x80044803 + IOCTL_MEI_NOTIFY_SET = 0x40044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 IPV6_FLOWINFO_MASK = 0xfffffff IPV6_FLOWLABEL_MASK = 0xfffff diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index bc8d539e6a..7d71911718 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -119,6 +119,8 @@ const ( IEXTEN = 0x8000 IN_CLOEXEC = 0x400000 IN_NONBLOCK = 0x4000 + IOCTL_MEI_NOTIFY_GET = 0x40044803 + IOCTL_MEI_NOTIFY_SET = 0x80044802 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 IPV6_FLOWINFO_MASK = 0xfffffff IPV6_FLOWLABEL_MASK = 0xfffff diff --git a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go index 439548ec9a..50e8e64497 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go @@ -104,7 +104,7 @@ type Statvfs_t struct { Fsid uint32 Namemax uint32 Owner uint32 - Spare [4]uint32 + Spare [4]uint64 Fstypename [32]byte Mntonname [1024]byte Mntfromname [1024]byte diff --git a/vendor/golang.org/x/text/encoding/unicode/unicode.go b/vendor/golang.org/x/text/encoding/unicode/unicode.go index dd99ad14d3..ce28c90628 100644 --- a/vendor/golang.org/x/text/encoding/unicode/unicode.go +++ b/vendor/golang.org/x/text/encoding/unicode/unicode.go @@ -60,9 +60,9 @@ func (utf8bomEncoding) NewDecoder() *encoding.Decoder { } var utf8enc = &internal.Encoding{ - &internal.SimpleEncoding{utf8Decoder{}, runes.ReplaceIllFormed()}, - "UTF-8", - identifier.UTF8, + Encoding: &internal.SimpleEncoding{Decoder: utf8Decoder{}, Encoder: runes.ReplaceIllFormed()}, + Name: "UTF-8", + MIB: identifier.UTF8, } type utf8bomDecoder struct { diff --git a/vendor/golang.org/x/tools/go/ast/astutil/imports.go b/vendor/golang.org/x/tools/go/ast/astutil/imports.go index 5bacc0fa49..adb4711019 100644 --- a/vendor/golang.org/x/tools/go/ast/astutil/imports.go +++ b/vendor/golang.org/x/tools/go/ast/astutil/imports.go @@ -9,6 +9,7 @@ import ( "fmt" "go/ast" "go/token" + "reflect" "slices" "strconv" "strings" @@ -149,7 +150,7 @@ func AddNamedImport(fset *token.FileSet, f *ast.File, name, path string) (added if newImport.Name != nil { newImport.Name.NamePos = pos } - newImport.Path.ValuePos = pos + updateBasicLitPos(newImport.Path, pos) newImport.EndPos = pos // Clean up parens. impDecl contains at least one spec. @@ -184,7 +185,7 @@ func AddNamedImport(fset *token.FileSet, f *ast.File, name, path string) (added first.Lparen = first.Pos() // Move the imports of the other import declaration to the first one. for _, spec := range gen.Specs { - spec.(*ast.ImportSpec).Path.ValuePos = first.Pos() + updateBasicLitPos(spec.(*ast.ImportSpec).Path, first.Pos()) first.Specs = append(first.Specs, spec) } f.Decls = slices.Delete(f.Decls, i, i+1) @@ -470,3 +471,17 @@ func Imports(fset *token.FileSet, f *ast.File) [][]*ast.ImportSpec { return groups } + +// updateBasicLitPos updates lit.Pos, +// ensuring that lit.End (if set) is displaced by the same amount. +// (See https://go.dev/issue/76395.) +func updateBasicLitPos(lit *ast.BasicLit, pos token.Pos) { + len := lit.End() - lit.Pos() + lit.ValuePos = pos + // TODO(adonovan): after go1.26, simplify to: + // lit.ValueEnd = pos + len + v := reflect.ValueOf(lit).Elem().FieldByName("ValueEnd") + if v.IsValid() && v.Int() != 0 { + v.SetInt(int64(pos + len)) + } +} diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go index 060ab08efb..ff607389da 100644 --- a/vendor/golang.org/x/tools/go/packages/packages.go +++ b/vendor/golang.org/x/tools/go/packages/packages.go @@ -1027,11 +1027,15 @@ func (ld *loader) refine(response *DriverResponse) ([]*Package, error) { // Precondition: ld.Mode&(NeedSyntax|NeedTypes|NeedTypesInfo) != 0. func (ld *loader) loadPackage(lpkg *loaderPackage) { if lpkg.PkgPath == "unsafe" { - // Fill in the blanks to avoid surprises. + // To avoid surprises, fill in the blanks consistent + // with other packages. (For example, some analyzers + // assert that each needed types.Info map is non-nil + // even when there is no syntax that would cause them + // to consult the map.) lpkg.Types = types.Unsafe lpkg.Fset = ld.Fset lpkg.Syntax = []*ast.File{} - lpkg.TypesInfo = new(types.Info) + lpkg.TypesInfo = ld.newTypesInfo() lpkg.TypesSizes = ld.sizes return } @@ -1180,20 +1184,7 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) { return } - // Populate TypesInfo only if needed, as it - // causes the type checker to work much harder. - if ld.Config.Mode&NeedTypesInfo != 0 { - lpkg.TypesInfo = &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Instances: make(map[*ast.Ident]types.Instance), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - FileVersions: make(map[*ast.File]string), - } - } + lpkg.TypesInfo = ld.newTypesInfo() lpkg.TypesSizes = ld.sizes importer := importerFunc(func(path string) (*types.Package, error) { @@ -1307,6 +1298,24 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) { lpkg.IllTyped = illTyped } +func (ld *loader) newTypesInfo() *types.Info { + // Populate TypesInfo only if needed, as it + // causes the type checker to work much harder. + if ld.Config.Mode&NeedTypesInfo == 0 { + return nil + } + return &types.Info{ + Types: make(map[ast.Expr]types.TypeAndValue), + Defs: make(map[*ast.Ident]types.Object), + Uses: make(map[*ast.Ident]types.Object), + Implicits: make(map[ast.Node]types.Object), + Instances: make(map[*ast.Ident]types.Instance), + Scopes: make(map[ast.Node]*types.Scope), + Selections: make(map[*ast.SelectorExpr]*types.Selection), + FileVersions: make(map[*ast.File]string), + } +} + // An importFunc is an implementation of the single-method // types.Importer interface based on a function value. type importerFunc func(path string) (*types.Package, error) diff --git a/vendor/golang.org/x/tools/go/types/typeutil/callee.go b/vendor/golang.org/x/tools/go/types/typeutil/callee.go index 5f10f56cba..3d24a8c637 100644 --- a/vendor/golang.org/x/tools/go/types/typeutil/callee.go +++ b/vendor/golang.org/x/tools/go/types/typeutil/callee.go @@ -12,6 +12,7 @@ import ( // Callee returns the named target of a function call, if any: // a function, method, builtin, or variable. +// It returns nil for a T(x) conversion. // // Functions and methods may potentially have type parameters. // diff --git a/vendor/golang.org/x/tools/internal/event/core/export.go b/vendor/golang.org/x/tools/internal/event/core/export.go index 05f3a9a579..16ae6bb021 100644 --- a/vendor/golang.org/x/tools/internal/event/core/export.go +++ b/vendor/golang.org/x/tools/internal/event/core/export.go @@ -8,7 +8,6 @@ import ( "context" "sync/atomic" "time" - "unsafe" "golang.org/x/tools/internal/event/label" ) @@ -17,23 +16,21 @@ import ( // It may return a modified context and event. type Exporter func(context.Context, Event, label.Map) context.Context -var ( - exporter unsafe.Pointer -) +var exporter atomic.Pointer[Exporter] // SetExporter sets the global exporter function that handles all events. // The exporter is called synchronously from the event call site, so it should // return quickly so as not to hold up user code. func SetExporter(e Exporter) { - p := unsafe.Pointer(&e) if e == nil { // &e is always valid, and so p is always valid, but for the early abort // of ProcessEvent to be efficient it needs to make the nil check on the // pointer without having to dereference it, so we make the nil function // also a nil pointer - p = nil + exporter.Store(nil) + } else { + exporter.Store(&e) } - atomic.StorePointer(&exporter, p) } // deliver is called to deliver an event to the supplied exporter. @@ -48,7 +45,7 @@ func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context { // Export is called to deliver an event to the global exporter if set. func Export(ctx context.Context, ev Event) context.Context { // get the global exporter and abort early if there is not one - exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter)) + exporterPtr := exporter.Load() if exporterPtr == nil { return ctx } @@ -61,7 +58,7 @@ func Export(ctx context.Context, ev Event) context.Context { // It will fill in the time. func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) { // get the global exporter and abort early if there is not one - exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter)) + exporterPtr := exporter.Load() if exporterPtr == nil { return ctx, func() {} } diff --git a/vendor/golang.org/x/tools/internal/event/label/label.go b/vendor/golang.org/x/tools/internal/event/label/label.go index 92a3910573..c37584af94 100644 --- a/vendor/golang.org/x/tools/internal/event/label/label.go +++ b/vendor/golang.org/x/tools/internal/event/label/label.go @@ -7,7 +7,6 @@ package label import ( "fmt" "io" - "reflect" "slices" "unsafe" ) @@ -103,11 +102,10 @@ type stringptr unsafe.Pointer // This method is for implementing new key types, label creation should // normally be done with the Of method of the key. func OfString(k Key, v string) Label { - hdr := (*reflect.StringHeader)(unsafe.Pointer(&v)) return Label{ key: k, - packed: uint64(hdr.Len), - untyped: stringptr(hdr.Data), + packed: uint64(len(v)), + untyped: stringptr(unsafe.StringData(v)), } } @@ -116,11 +114,7 @@ func OfString(k Key, v string) Label { // This method is for implementing new key types, for type safety normal // access should be done with the From method of the key. func (t Label) UnpackString() string { - var v string - hdr := (*reflect.StringHeader)(unsafe.Pointer(&v)) - hdr.Data = uintptr(t.untyped.(stringptr)) - hdr.Len = int(t.packed) - return v + return unsafe.String((*byte)(t.untyped.(stringptr)), int(t.packed)) } // Valid returns true if the Label is a valid one (it has a key). diff --git a/vendor/golang.org/x/tools/internal/imports/sortimports.go b/vendor/golang.org/x/tools/internal/imports/sortimports.go index 67c17bc431..f390be90f1 100644 --- a/vendor/golang.org/x/tools/internal/imports/sortimports.go +++ b/vendor/golang.org/x/tools/internal/imports/sortimports.go @@ -11,6 +11,7 @@ import ( "go/ast" "go/token" "log" + "reflect" "slices" "sort" "strconv" @@ -65,7 +66,7 @@ func sortImports(localPrefix string, tokFile *token.File, f *ast.File) { } // mergeImports merges all the import declarations into the first one. -// Taken from golang.org/x/tools/ast/astutil. +// Taken from golang.org/x/tools/go/ast/astutil. // This does not adjust line numbers properly func mergeImports(f *ast.File) { if len(f.Decls) <= 1 { @@ -89,7 +90,7 @@ func mergeImports(f *ast.File) { first.Lparen = first.Pos() // Move the imports of the other import declaration to the first one. for _, spec := range gen.Specs { - spec.(*ast.ImportSpec).Path.ValuePos = first.Pos() + updateBasicLitPos(spec.(*ast.ImportSpec).Path, first.Pos()) first.Specs = append(first.Specs, spec) } f.Decls = slices.Delete(f.Decls, i, i+1) @@ -98,7 +99,7 @@ func mergeImports(f *ast.File) { } // declImports reports whether gen contains an import of path. -// Taken from golang.org/x/tools/ast/astutil. +// Taken from golang.org/x/tools/go/ast/astutil. func declImports(gen *ast.GenDecl, path string) bool { if gen.Tok != token.IMPORT { return false @@ -221,7 +222,7 @@ func sortSpecs(localPrefix string, tokFile *token.File, f *ast.File, specs []ast if s.Name != nil { s.Name.NamePos = pos[i].Start } - s.Path.ValuePos = pos[i].Start + updateBasicLitPos(s.Path, pos[i].Start) s.EndPos = pos[i].End nextSpecPos := pos[i].End @@ -296,3 +297,17 @@ type byCommentPos []*ast.CommentGroup func (x byCommentPos) Len() int { return len(x) } func (x byCommentPos) Swap(i, j int) { x[i], x[j] = x[j], x[i] } func (x byCommentPos) Less(i, j int) bool { return x[i].Pos() < x[j].Pos() } + +// updateBasicLitPos updates lit.Pos, +// ensuring that lit.End (if set) is displaced by the same amount. +// (See https://go.dev/issue/76395.) +func updateBasicLitPos(lit *ast.BasicLit, pos token.Pos) { + len := lit.End() - lit.Pos() + lit.ValuePos = pos + // TODO(adonovan): after go1.26, simplify to: + // lit.ValueEnd = pos + len + v := reflect.ValueOf(lit).Elem().FieldByName("ValueEnd") + if v.IsValid() && v.Int() != 0 { + v.SetInt(int64(pos + len)) + } +} diff --git a/vendor/golang.org/x/tools/internal/modindex/lookup.go b/vendor/golang.org/x/tools/internal/modindex/lookup.go index 0c011a99b3..83bd49cd4b 100644 --- a/vendor/golang.org/x/tools/internal/modindex/lookup.go +++ b/vendor/golang.org/x/tools/internal/modindex/lookup.go @@ -8,6 +8,8 @@ import ( "slices" "strconv" "strings" + + "golang.org/x/mod/module" ) type Candidate struct { @@ -104,11 +106,15 @@ func (ix *Index) Lookup(pkgName, name string, prefix bool) []Candidate { if len(flds) < 2 { continue // should never happen } + impPath, err := module.UnescapePath(e.ImportPath) + if err != nil { + continue + } px := Candidate{ PkgName: pkgName, Name: flds[0], Dir: string(e.Dir), - ImportPath: e.ImportPath, + ImportPath: impPath, Type: asLexType(flds[1][0]), Deprecated: len(flds[1]) > 1 && flds[1][1] == 'D', } diff --git a/vendor/golang.org/x/tools/internal/stdlib/deps.go b/vendor/golang.org/x/tools/internal/stdlib/deps.go index 581784da43..f7b9c12865 100644 --- a/vendor/golang.org/x/tools/internal/stdlib/deps.go +++ b/vendor/golang.org/x/tools/internal/stdlib/deps.go @@ -12,360 +12,364 @@ type pkginfo struct { } var deps = [...]pkginfo{ - {"archive/tar", "\x03n\x03E<\x01\n\x01$\x01\x01\x02\x05\b\x02\x01\x02\x02\f"}, - {"archive/zip", "\x02\x04d\a\x03\x12\x021<\x01+\x05\x01\x0f\x03\x02\x0e\x04"}, - {"bufio", "\x03n\x84\x01D\x14"}, - {"bytes", "q*Z\x03\fG\x02\x02"}, + {"archive/tar", "\x03p\x03F=\x01\n\x01$\x01\x01\x02\x05\b\x02\x01\x02\x02\f"}, + {"archive/zip", "\x02\x04f\a\x03\x13\x021=\x01+\x05\x01\x0f\x03\x02\x0e\x04"}, + {"bufio", "\x03p\x86\x01D\x14"}, + {"bytes", "s+[\x03\fG\x02\x02"}, {"cmp", ""}, - {"compress/bzip2", "\x02\x02\xf1\x01A"}, - {"compress/flate", "\x02o\x03\x81\x01\f\x033\x01\x03"}, - {"compress/gzip", "\x02\x04d\a\x03\x14mT"}, - {"compress/lzw", "\x02o\x03\x81\x01"}, - {"compress/zlib", "\x02\x04d\a\x03\x12\x01n"}, - {"container/heap", "\xb7\x02"}, + {"compress/bzip2", "\x02\x02\xf5\x01A"}, + {"compress/flate", "\x02q\x03\x83\x01\f\x033\x01\x03"}, + {"compress/gzip", "\x02\x04f\a\x03\x15nT"}, + {"compress/lzw", "\x02q\x03\x83\x01"}, + {"compress/zlib", "\x02\x04f\a\x03\x13\x01o"}, + {"container/heap", "\xbb\x02"}, {"container/list", ""}, {"container/ring", ""}, - {"context", "q[o\x01\r"}, - {"crypto", "\x86\x01oC"}, - {"crypto/aes", "\x10\n\t\x95\x02"}, - {"crypto/cipher", "\x03 \x01\x01\x1f\x11\x1c+Y"}, - {"crypto/des", "\x10\x15\x1f-+\x9c\x01\x03"}, - {"crypto/dsa", "D\x04)\x84\x01\r"}, - {"crypto/ecdh", "\x03\v\f\x10\x04\x16\x04\r\x1c\x84\x01"}, - {"crypto/ecdsa", "\x0e\x05\x03\x04\x01\x10\a\v\x06\x01\x04\f\x01\x1c\x84\x01\r\x05K\x01"}, - {"crypto/ed25519", "\x0e\x1e\x11\a\n\a\x1c\x84\x01C"}, - {"crypto/elliptic", "2?\x84\x01\r9"}, + {"context", "s\\p\x01\r"}, + {"crypto", "\x89\x01pC"}, + {"crypto/aes", "\x10\n\t\x99\x02"}, + {"crypto/cipher", "\x03 \x01\x01 \x12\x1c,Z"}, + {"crypto/des", "\x10\x15 .,\x9d\x01\x03"}, + {"crypto/dsa", "E\x04*\x86\x01\r"}, + {"crypto/ecdh", "\x03\v\f\x10\x04\x17\x04\x0e\x1c\x86\x01"}, + {"crypto/ecdsa", "\x0e\x05\x03\x04\x01\x10\b\v\x06\x01\x04\r\x01\x1c\x86\x01\r\x05K\x01"}, + {"crypto/ed25519", "\x0e\x1e\x12\a\v\a\x1c\x86\x01C"}, + {"crypto/elliptic", "3@\x86\x01\r9"}, {"crypto/fips140", "\"\x05"}, - {"crypto/hkdf", "/\x14\x01-\x15"}, - {"crypto/hmac", "\x1a\x16\x13\x01\x111"}, - {"crypto/internal/boring", "\x0e\x02\ri"}, - {"crypto/internal/boring/bbig", "\x1a\xe8\x01M"}, - {"crypto/internal/boring/bcache", "\xbc\x02\x13"}, + {"crypto/hkdf", "/\x15\x01.\x16"}, + {"crypto/hmac", "\x1a\x16\x14\x01\x122"}, + {"crypto/internal/boring", "\x0e\x02\rl"}, + {"crypto/internal/boring/bbig", "\x1a\xec\x01M"}, + {"crypto/internal/boring/bcache", "\xc0\x02\x13"}, {"crypto/internal/boring/sig", ""}, {"crypto/internal/constanttime", ""}, - {"crypto/internal/cryptotest", "\x03\r\n\b%\x0e\x19\x06\x12\x12 \x04\x06\t\x18\x01\x11\x11\x1b\x01\a\x05\b\x03\x05\v"}, - {"crypto/internal/entropy", "I"}, - {"crypto/internal/entropy/v1.0.0", "B/\x93\x018\x13"}, - {"crypto/internal/fips140", "A0\xbd\x01\v\x16"}, - {"crypto/internal/fips140/aes", "\x03\x1f\x03\x02\x13\x05\x01\x01\x06*\x93\x014"}, - {"crypto/internal/fips140/aes/gcm", "\"\x01\x02\x02\x02\x11\x05\x01\a*\x90\x01"}, - {"crypto/internal/fips140/alias", "\xcf\x02"}, - {"crypto/internal/fips140/bigmod", "'\x18\x01\a*\x93\x01"}, - {"crypto/internal/fips140/check", "\"\x0e\x06\t\x02\xb4\x01Z"}, - {"crypto/internal/fips140/check/checktest", "'\x87\x02!"}, - {"crypto/internal/fips140/drbg", "\x03\x1e\x01\x01\x04\x13\x05\t\x01(\x84\x01\x0f7\x01"}, - {"crypto/internal/fips140/ecdh", "\x03\x1f\x05\x02\t\r2\x84\x01\x0f7"}, - {"crypto/internal/fips140/ecdsa", "\x03\x1f\x04\x01\x02\a\x02\x069\x15oF"}, - {"crypto/internal/fips140/ed25519", "\x03\x1f\x05\x02\x04\v9\xc7\x01\x03"}, - {"crypto/internal/fips140/edwards25519", "\x1e\t\a\x112\x93\x017"}, - {"crypto/internal/fips140/edwards25519/field", "'\x13\x052\x93\x01"}, - {"crypto/internal/fips140/hkdf", "\x03\x1f\x05\t\x06;\x15"}, - {"crypto/internal/fips140/hmac", "\x03\x1f\x14\x01\x019\x15"}, - {"crypto/internal/fips140/mlkem", "\x03\x1f\x05\x02\x0e\x03\x052\xca\x01"}, - {"crypto/internal/fips140/nistec", "\x1e\t\f\f2\x93\x01*\r\x14"}, - {"crypto/internal/fips140/nistec/fiat", "'\x137\x93\x01"}, - {"crypto/internal/fips140/pbkdf2", "\x03\x1f\x05\t\x06;\x15"}, - {"crypto/internal/fips140/rsa", "\x03\x1b\x04\x04\x01\x02\r\x01\x01\x027\x15oF"}, - {"crypto/internal/fips140/sha256", "\x03\x1f\x1d\x01\a*\x15~"}, - {"crypto/internal/fips140/sha3", "\x03\x1f\x18\x05\x011\x93\x01K"}, - {"crypto/internal/fips140/sha512", "\x03\x1f\x1d\x01\a*\x15~"}, - {"crypto/internal/fips140/ssh", "'_"}, - {"crypto/internal/fips140/subtle", "\x1e\a\x1a\xc5\x01"}, - {"crypto/internal/fips140/tls12", "\x03\x1f\x05\t\x06\x029\x15"}, - {"crypto/internal/fips140/tls13", "\x03\x1f\x05\b\a\t2\x15"}, - {"crypto/internal/fips140cache", "\xae\x02\r&"}, + {"crypto/internal/cryptotest", "\x03\r\n\b&\x0f\x19\x06\x13\x12 \x04\x06\t\x19\x01\x11\x11\x1b\x01\a\x05\b\x03\x05\v"}, + {"crypto/internal/entropy", "J"}, + {"crypto/internal/entropy/v1.0.0", "C0\x95\x018\x13"}, + {"crypto/internal/fips140", "B1\xbf\x01\v\x16"}, + {"crypto/internal/fips140/aes", "\x03\x1f\x03\x02\x14\x05\x01\x01\x06+\x95\x014"}, + {"crypto/internal/fips140/aes/gcm", "\"\x01\x02\x02\x02\x12\x05\x01\a+\x92\x01"}, + {"crypto/internal/fips140/alias", "\xd3\x02"}, + {"crypto/internal/fips140/bigmod", "'\x19\x01\a+\x95\x01"}, + {"crypto/internal/fips140/check", "\"\x0e\a\t\x02\xb7\x01Z"}, + {"crypto/internal/fips140/check/checktest", "'\x8b\x02!"}, + {"crypto/internal/fips140/drbg", "\x03\x1e\x01\x01\x04\x14\x05\t\x01)\x86\x01\x0f7\x01"}, + {"crypto/internal/fips140/ecdh", "\x03\x1f\x05\x02\n\r3\x86\x01\x0f7"}, + {"crypto/internal/fips140/ecdsa", "\x03\x1f\x04\x01\x02\a\x03\x06:\x16pF"}, + {"crypto/internal/fips140/ed25519", "\x03\x1f\x05\x02\x04\f:\xc9\x01\x03"}, + {"crypto/internal/fips140/edwards25519", "\x1e\t\a\x123\x95\x017"}, + {"crypto/internal/fips140/edwards25519/field", "'\x14\x053\x95\x01"}, + {"crypto/internal/fips140/hkdf", "\x03\x1f\x05\t\a<\x16"}, + {"crypto/internal/fips140/hmac", "\x03\x1f\x15\x01\x01:\x16"}, + {"crypto/internal/fips140/mldsa", "\x03\x1b\x04\x05\x02\x0e\x01\x03\x053\x95\x017"}, + {"crypto/internal/fips140/mlkem", "\x03\x1f\x05\x02\x0f\x03\x053\xcc\x01"}, + {"crypto/internal/fips140/nistec", "\x1e\t\r\f3\x95\x01*\r\x14"}, + {"crypto/internal/fips140/nistec/fiat", "'\x148\x95\x01"}, + {"crypto/internal/fips140/pbkdf2", "\x03\x1f\x05\t\a<\x16"}, + {"crypto/internal/fips140/rsa", "\x03\x1b\x04\x04\x01\x02\x0e\x01\x01\x028\x16pF"}, + {"crypto/internal/fips140/sha256", "\x03\x1f\x1e\x01\a+\x16\x7f"}, + {"crypto/internal/fips140/sha3", "\x03\x1f\x19\x05\x012\x95\x01K"}, + {"crypto/internal/fips140/sha512", "\x03\x1f\x1e\x01\a+\x16\x7f"}, + {"crypto/internal/fips140/ssh", "'b"}, + {"crypto/internal/fips140/subtle", "\x1e\a\x1b\xc8\x01"}, + {"crypto/internal/fips140/tls12", "\x03\x1f\x05\t\a\x02:\x16"}, + {"crypto/internal/fips140/tls13", "\x03\x1f\x05\b\b\t3\x16"}, + {"crypto/internal/fips140cache", "\xb2\x02\r&"}, {"crypto/internal/fips140deps", ""}, - {"crypto/internal/fips140deps/byteorder", "\x9c\x01"}, - {"crypto/internal/fips140deps/cpu", "\xb1\x01\a"}, - {"crypto/internal/fips140deps/godebug", "\xb9\x01"}, - {"crypto/internal/fips140deps/time", "\xc9\x02"}, - {"crypto/internal/fips140hash", "7\x1c3\xc9\x01"}, - {"crypto/internal/fips140only", ")\r\x01\x01N3<"}, + {"crypto/internal/fips140deps/byteorder", "\x9f\x01"}, + {"crypto/internal/fips140deps/cpu", "\xb4\x01\a"}, + {"crypto/internal/fips140deps/godebug", "\xbc\x01"}, + {"crypto/internal/fips140deps/time", "\xcd\x02"}, + {"crypto/internal/fips140hash", "8\x1d4\xca\x01"}, + {"crypto/internal/fips140only", ")\x0e\x01\x01P3="}, {"crypto/internal/fips140test", ""}, - {"crypto/internal/hpke", "\x0e\x01\x01\x03\x056#+hM"}, - {"crypto/internal/impl", "\xb9\x02"}, - {"crypto/internal/randutil", "\xf5\x01\x12"}, - {"crypto/internal/sysrand", "qo! \r\r\x01\x01\f\x06"}, - {"crypto/internal/sysrand/internal/seccomp", "q"}, - {"crypto/md5", "\x0e6-\x15\x16h"}, - {"crypto/mlkem", "1"}, - {"crypto/pbkdf2", "4\x0f\x01-\x15"}, - {"crypto/rand", "\x1a\b\a\x1b\x04\x01(\x84\x01\rM"}, - {"crypto/rc4", "%\x1f-\xc7\x01"}, - {"crypto/rsa", "\x0e\f\x01\v\x0f\x0e\x01\x04\x06\a\x1c\x03\x123<\f\x01"}, - {"crypto/sha1", "\x0e\f*\x03*\x15\x16\x15S"}, - {"crypto/sha256", "\x0e\f\x1cP"}, - {"crypto/sha3", "\x0e)O\xc9\x01"}, - {"crypto/sha512", "\x0e\f\x1eN"}, - {"crypto/subtle", "\x1e\x1c\x9c\x01X"}, - {"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x02\x01\x01\t\x01\r\n\x01\n\x05\x03\x01\x01\x01\x01\x02\x01\x02\x01\x17\x02\x03\x12\x16\x15\b<\x16\x16\r\b\x01\x01\x01\x02\x01\r\x06\x02\x01\x0f"}, - {"crypto/tls/internal/fips140tls", "\x17\xa5\x02"}, - {"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x015\x05\x01\x01\x02\x05\x0e\x06\x02\x02\x03E\x039\x01\x02\b\x01\x01\x02\a\x10\x05\x01\x06\x02\x05\b\x02\x01\x02\x0e\x02\x01\x01\x02\x03\x01"}, - {"crypto/x509/pkix", "g\x06\a\x8e\x01G"}, - {"database/sql", "\x03\nN\x16\x03\x81\x01\v\a\"\x05\b\x02\x03\x01\r\x02\x02\x02"}, - {"database/sql/driver", "\rd\x03\xb5\x01\x0f\x11"}, - {"debug/buildinfo", "\x03[\x02\x01\x01\b\a\x03e\x1a\x02\x01+\x0f\x1f"}, - {"debug/dwarf", "\x03g\a\x03\x81\x011\x11\x01\x01"}, - {"debug/elf", "\x03\x06T\r\a\x03e\x1b\x01\f \x17\x01\x16"}, - {"debug/gosym", "\x03g\n\xc3\x01\x01\x01\x02"}, - {"debug/macho", "\x03\x06T\r\ne\x1c,\x17\x01"}, - {"debug/pe", "\x03\x06T\r\a\x03e\x1c,\x17\x01\x16"}, - {"debug/plan9obj", "j\a\x03e\x1c,"}, - {"embed", "q*A\x19\x01S"}, + {"crypto/internal/hpke", "\x03\v\x01\x01\x03\x055\x03\x04\x01\x01\x16\a\x03\x13\xcc\x01"}, + {"crypto/internal/impl", "\xbd\x02"}, + {"crypto/internal/randutil", "\xf9\x01\x12"}, + {"crypto/internal/sysrand", "sq! \r\r\x01\x01\f\x06"}, + {"crypto/internal/sysrand/internal/seccomp", "s"}, + {"crypto/md5", "\x0e7.\x16\x16i"}, + {"crypto/mlkem", "\x0e$"}, + {"crypto/mlkem/mlkemtest", "2\x1b&"}, + {"crypto/pbkdf2", "5\x0f\x01.\x16"}, + {"crypto/rand", "\x1a\b\a\x1c\x04\x01)\x86\x01\rM"}, + {"crypto/rc4", "% .\xc9\x01"}, + {"crypto/rsa", "\x0e\f\x01\v\x10\x0e\x01\x04\a\a\x1c\x03\x133=\f\x01"}, + {"crypto/sha1", "\x0e\f+\x03+\x16\x16\x15T"}, + {"crypto/sha256", "\x0e\f\x1dR"}, + {"crypto/sha3", "\x0e*Q\xca\x01"}, + {"crypto/sha512", "\x0e\f\x1fP"}, + {"crypto/subtle", "\x1e\x1d\x9f\x01X"}, + {"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x02\x01\x01\t\x01\x0e\n\x01\n\x05\x04\x01\x01\x01\x01\x02\x01\x02\x01\x17\x02\x03\x13\x16\x15\b=\x16\x16\r\b\x01\x01\x01\x02\x01\r\x06\x02\x01\x0f"}, + {"crypto/tls/internal/fips140tls", "\x17\xa9\x02"}, + {"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x016\x06\x01\x01\x02\x05\x0e\x06\x02\x02\x03F\x03:\x01\x02\b\x01\x01\x02\a\x10\x05\x01\x06\a\b\x02\x01\x02\x0e\x02\x01\x01\x02\x03\x01"}, + {"crypto/x509/pkix", "i\x06\a\x90\x01G"}, + {"database/sql", "\x03\nP\x16\x03\x83\x01\v\a\"\x05\b\x02\x03\x01\r\x02\x02\x02"}, + {"database/sql/driver", "\rf\x03\xb7\x01\x0f\x11"}, + {"debug/buildinfo", "\x03]\x02\x01\x01\b\a\x03g\x1a\x02\x01+\x0f\x1f"}, + {"debug/dwarf", "\x03i\a\x03\x83\x011\x11\x01\x01"}, + {"debug/elf", "\x03\x06V\r\a\x03g\x1b\x01\f \x17\x01\x16"}, + {"debug/gosym", "\x03i\n\xc5\x01\x01\x01\x02"}, + {"debug/macho", "\x03\x06V\r\ng\x1c,\x17\x01"}, + {"debug/pe", "\x03\x06V\r\a\x03g\x1c,\x17\x01\x16"}, + {"debug/plan9obj", "l\a\x03g\x1c,"}, + {"embed", "s+B\x19\x01S"}, {"embed/internal/embedtest", ""}, {"encoding", ""}, - {"encoding/ascii85", "\xf5\x01C"}, - {"encoding/asn1", "\x03n\x03e(\x01'\r\x02\x01\x10\x03\x01"}, - {"encoding/base32", "\xf5\x01A\x02"}, - {"encoding/base64", "\x9c\x01YA\x02"}, - {"encoding/binary", "q\x84\x01\f(\r\x05"}, - {"encoding/csv", "\x02\x01n\x03\x81\x01D\x12\x02"}, - {"encoding/gob", "\x02c\x05\a\x03e\x1c\v\x01\x03\x1d\b\x12\x01\x0f\x02"}, - {"encoding/hex", "q\x03\x81\x01A\x03"}, - {"encoding/json", "\x03\x01a\x04\b\x03\x81\x01\f(\r\x02\x01\x02\x10\x01\x01\x02"}, - {"encoding/pem", "\x03f\b\x84\x01A\x03"}, - {"encoding/xml", "\x02\x01b\f\x03\x81\x014\x05\n\x01\x02\x10\x02"}, - {"errors", "\xcc\x01\x83\x01"}, - {"expvar", "nK@\b\v\x15\r\b\x02\x03\x01\x11"}, - {"flag", "e\f\x03\x81\x01,\b\x05\b\x02\x01\x10"}, - {"fmt", "qE&\x19\f \b\r\x02\x03\x12"}, - {"go/ast", "\x03\x01p\x0e\x01r\x03)\b\r\x02\x01\x12\x02"}, - {"go/build", "\x02\x01n\x03\x01\x02\x02\a\x02\x01\x17\x1f\x04\x02\b\x1b\x13\x01+\x01\x04\x01\a\b\x02\x01\x12\x02\x02"}, - {"go/build/constraint", "q\xc7\x01\x01\x12\x02"}, - {"go/constant", "t\x0f~\x01\x024\x01\x02\x12"}, - {"go/doc", "\x04p\x01\x05\t=51\x10\x02\x01\x12\x02"}, - {"go/doc/comment", "\x03q\xc2\x01\x01\x01\x01\x12\x02"}, - {"go/format", "\x03q\x01\v\x01\x02rD"}, - {"go/importer", "v\a\x01\x01\x04\x01q9"}, - {"go/internal/gccgoimporter", "\x02\x01[\x13\x03\x04\v\x01o\x02,\x01\x05\x11\x01\f\b"}, - {"go/internal/gcimporter", "\x02r\x0f\x010\x05\r/,\x15\x03\x02"}, - {"go/internal/srcimporter", "t\x01\x01\n\x03\x01q,\x01\x05\x12\x02\x14"}, - {"go/parser", "\x03n\x03\x01\x02\v\x01r\x01+\x06\x12"}, - {"go/printer", "t\x01\x02\x03\tr\f \x15\x02\x01\x02\v\x05\x02"}, - {"go/scanner", "\x03q\x0fr2\x10\x01\x13\x02"}, - {"go/token", "\x04p\x84\x01>\x02\x03\x01\x0f\x02"}, - {"go/types", "\x03\x01\x06g\x03\x01\x03\b\x03\x024\x062\x04\x03\t \x06\a\b\x01\x01\x01\x02\x01\x0f\x02\x02"}, - {"go/version", "\xbe\x01{"}, - {"hash", "\xf5\x01"}, - {"hash/adler32", "q\x15\x16"}, - {"hash/crc32", "q\x15\x16\x15\x8a\x01\x01\x13"}, - {"hash/crc64", "q\x15\x16\x9f\x01"}, - {"hash/fnv", "q\x15\x16h"}, - {"hash/maphash", "\x86\x01\x11<|"}, - {"html", "\xb9\x02\x02\x12"}, - {"html/template", "\x03k\x06\x18-<\x01\n!\x05\x01\x02\x03\f\x01\x02\f\x01\x03\x02"}, - {"image", "\x02o\x1ef\x0f4\x03\x01"}, + {"encoding/ascii85", "\xf9\x01C"}, + {"encoding/asn1", "\x03p\x03g(\x01'\r\x02\x01\x10\x03\x01"}, + {"encoding/base32", "\xf9\x01A\x02"}, + {"encoding/base64", "\x9f\x01ZA\x02"}, + {"encoding/binary", "s\x86\x01\f(\r\x05"}, + {"encoding/csv", "\x02\x01p\x03\x83\x01D\x12\x02"}, + {"encoding/gob", "\x02e\x05\a\x03g\x1c\v\x01\x03\x1d\b\x12\x01\x0f\x02"}, + {"encoding/hex", "s\x03\x83\x01A\x03"}, + {"encoding/json", "\x03\x01c\x04\b\x03\x83\x01\f(\r\x02\x01\x02\x10\x01\x01\x02"}, + {"encoding/pem", "\x03h\b\x86\x01A\x03"}, + {"encoding/xml", "\x02\x01d\f\x03\x83\x014\x05\n\x01\x02\x10\x02"}, + {"errors", "\xcf\x01\x84\x01"}, + {"expvar", "pLA\b\v\x15\r\b\x02\x03\x01\x11"}, + {"flag", "g\f\x03\x83\x01,\b\x05\b\x02\x01\x10"}, + {"fmt", "sF'\x19\f \b\r\x02\x03\x12"}, + {"go/ast", "\x03\x01r\x0f\x01s\x03)\b\r\x02\x01\x12\x02"}, + {"go/build", "\x02\x01p\x03\x01\x02\x02\b\x02\x01\x17\x1f\x04\x02\b\x1c\x13\x01+\x01\x04\x01\a\b\x02\x01\x12\x02\x02"}, + {"go/build/constraint", "s\xc9\x01\x01\x12\x02"}, + {"go/constant", "v\x10\x7f\x01\x024\x01\x02\x12"}, + {"go/doc", "\x04r\x01\x05\n=61\x10\x02\x01\x12\x02"}, + {"go/doc/comment", "\x03s\xc4\x01\x01\x01\x01\x12\x02"}, + {"go/format", "\x03s\x01\f\x01\x02sD"}, + {"go/importer", "x\a\x01\x02\x04\x01r9"}, + {"go/internal/gccgoimporter", "\x02\x01]\x13\x03\x04\f\x01p\x02,\x01\x05\x11\x01\f\b"}, + {"go/internal/gcimporter", "\x02t\x10\x010\x05\r0,\x15\x03\x02"}, + {"go/internal/scannerhooks", "\x86\x01"}, + {"go/internal/srcimporter", "v\x01\x01\v\x03\x01r,\x01\x05\x12\x02\x14"}, + {"go/parser", "\x03p\x03\x01\x02\b\x04\x01s\x01+\x06\x12"}, + {"go/printer", "v\x01\x02\x03\ns\f \x15\x02\x01\x02\v\x05\x02"}, + {"go/scanner", "\x03s\v\x05s2\x10\x01\x13\x02"}, + {"go/token", "\x04r\x86\x01>\x02\x03\x01\x0f\x02"}, + {"go/types", "\x03\x01\x06i\x03\x01\x03\t\x03\x024\x063\x04\x03\t \x06\a\b\x01\x01\x01\x02\x01\x0f\x02\x02"}, + {"go/version", "\xc1\x01|"}, + {"hash", "\xf9\x01"}, + {"hash/adler32", "s\x16\x16"}, + {"hash/crc32", "s\x16\x16\x15\x8b\x01\x01\x13"}, + {"hash/crc64", "s\x16\x16\xa0\x01"}, + {"hash/fnv", "s\x16\x16i"}, + {"hash/maphash", "\x89\x01\x11<}"}, + {"html", "\xbd\x02\x02\x12"}, + {"html/template", "\x03m\x06\x19-=\x01\n!\x05\x01\x02\x03\f\x01\x02\f\x01\x03\x02"}, + {"image", "\x02q\x1fg\x0f4\x03\x01"}, {"image/color", ""}, - {"image/color/palette", "\x8f\x01"}, - {"image/draw", "\x8e\x01\x01\x04"}, - {"image/gif", "\x02\x01\x05i\x03\x1a\x01\x01\x01\vY"}, - {"image/internal/imageutil", "\x8e\x01"}, - {"image/jpeg", "\x02o\x1d\x01\x04b"}, - {"image/png", "\x02\aa\n\x12\x02\x06\x01fC"}, - {"index/suffixarray", "\x03g\a\x84\x01\f+\n\x01"}, - {"internal/abi", "\xb8\x01\x97\x01"}, - {"internal/asan", "\xcf\x02"}, - {"internal/bisect", "\xae\x02\r\x01"}, - {"internal/buildcfg", "tGf\x06\x02\x05\n\x01"}, - {"internal/bytealg", "\xb1\x01\x9e\x01"}, + {"image/color/palette", "\x92\x01"}, + {"image/draw", "\x91\x01\x01\x04"}, + {"image/gif", "\x02\x01\x05k\x03\x1b\x01\x01\x01\vZ\x0f"}, + {"image/internal/imageutil", "\x91\x01"}, + {"image/jpeg", "\x02q\x1e\x01\x04c"}, + {"image/png", "\x02\ac\n\x13\x02\x06\x01gC"}, + {"index/suffixarray", "\x03i\a\x86\x01\f+\n\x01"}, + {"internal/abi", "\xbb\x01\x98\x01"}, + {"internal/asan", "\xd3\x02"}, + {"internal/bisect", "\xb2\x02\r\x01"}, + {"internal/buildcfg", "vHg\x06\x02\x05\n\x01"}, + {"internal/bytealg", "\xb4\x01\x9f\x01"}, {"internal/byteorder", ""}, {"internal/cfg", ""}, - {"internal/cgrouptest", "tZS\x06\x0f\x02\x01\x04\x01"}, - {"internal/chacha8rand", "\x9c\x01\x15\a\x97\x01"}, + {"internal/cgrouptest", "v[T\x06\x0f\x02\x01\x04\x01"}, + {"internal/chacha8rand", "\x9f\x01\x15\a\x98\x01"}, {"internal/copyright", ""}, {"internal/coverage", ""}, {"internal/coverage/calloc", ""}, - {"internal/coverage/cfile", "n\x06\x16\x17\x01\x02\x01\x01\x01\x01\x01\x01\x01\"\x02&,\x06\a\n\x01\x03\r\x06"}, - {"internal/coverage/cformat", "\x04p-\x04P\v6\x01\x02\r"}, - {"internal/coverage/cmerge", "t-`"}, - {"internal/coverage/decodecounter", "j\n-\v\x02G,\x17\x17"}, - {"internal/coverage/decodemeta", "\x02h\n\x16\x17\v\x02G,"}, - {"internal/coverage/encodecounter", "\x02h\n-\f\x01\x02E\v!\x15"}, - {"internal/coverage/encodemeta", "\x02\x01g\n\x12\x04\x17\r\x02E,."}, - {"internal/coverage/pods", "\x04p-\x80\x01\x06\x05\n\x02\x01"}, - {"internal/coverage/rtcov", "\xcf\x02"}, - {"internal/coverage/slicereader", "j\n\x81\x01Z"}, - {"internal/coverage/slicewriter", "t\x81\x01"}, - {"internal/coverage/stringtab", "t8\x04E"}, + {"internal/coverage/cfile", "p\x06\x17\x17\x01\x02\x01\x01\x01\x01\x01\x01\x01\"\x02',\x06\a\n\x01\x03\r\x06"}, + {"internal/coverage/cformat", "\x04r.\x04Q\v6\x01\x02\r"}, + {"internal/coverage/cmerge", "v.a"}, + {"internal/coverage/decodecounter", "l\n.\v\x02H,\x17\x17"}, + {"internal/coverage/decodemeta", "\x02j\n\x17\x17\v\x02H,"}, + {"internal/coverage/encodecounter", "\x02j\n.\f\x01\x02F\v!\x15"}, + {"internal/coverage/encodemeta", "\x02\x01i\n\x13\x04\x17\r\x02F,."}, + {"internal/coverage/pods", "\x04r.\x81\x01\x06\x05\n\x02\x01"}, + {"internal/coverage/rtcov", "\xd3\x02"}, + {"internal/coverage/slicereader", "l\n\x83\x01Z"}, + {"internal/coverage/slicewriter", "v\x83\x01"}, + {"internal/coverage/stringtab", "v9\x04F"}, {"internal/coverage/test", ""}, {"internal/coverage/uleb128", ""}, - {"internal/cpu", "\xcf\x02"}, - {"internal/dag", "\x04p\xc2\x01\x03"}, - {"internal/diff", "\x03q\xc3\x01\x02"}, - {"internal/exportdata", "\x02\x01n\x03\x02c\x1c,\x01\x05\x11\x01\x02"}, - {"internal/filepathlite", "q*A\x1a@"}, - {"internal/fmtsort", "\x04\xa5\x02\r"}, - {"internal/fuzz", "\x03\nE\x18\x04\x03\x03\x01\v\x036<\f\x03\x1d\x01\x05\x02\x05\n\x01\x02\x01\x01\f\x04\x02"}, + {"internal/cpu", "\xd3\x02"}, + {"internal/dag", "\x04r\xc4\x01\x03"}, + {"internal/diff", "\x03s\xc5\x01\x02"}, + {"internal/exportdata", "\x02\x01p\x03\x02e\x1c,\x01\x05\x11\x01\x02"}, + {"internal/filepathlite", "s+B\x1a@"}, + {"internal/fmtsort", "\x04\xa9\x02\r"}, + {"internal/fuzz", "\x03\nG\x18\x04\x03\x03\x01\f\x036=\f\x03\x1d\x01\x05\x02\x05\n\x01\x02\x01\x01\f\x04\x02"}, {"internal/goarch", ""}, - {"internal/godebug", "\x99\x01!\x81\x01\x01\x13"}, + {"internal/godebug", "\x9c\x01!\x82\x01\x01\x13"}, {"internal/godebugs", ""}, {"internal/goexperiment", ""}, {"internal/goos", ""}, - {"internal/goroot", "\xa1\x02\x01\x05\x12\x02"}, + {"internal/goroot", "\xa5\x02\x01\x05\x12\x02"}, {"internal/gover", "\x04"}, {"internal/goversion", ""}, - {"internal/lazyregexp", "\xa1\x02\v\r\x02"}, - {"internal/lazytemplate", "\xf5\x01,\x18\x02\f"}, - {"internal/msan", "\xcf\x02"}, + {"internal/lazyregexp", "\xa5\x02\v\r\x02"}, + {"internal/lazytemplate", "\xf9\x01,\x18\x02\f"}, + {"internal/msan", "\xd3\x02"}, {"internal/nettrace", ""}, - {"internal/obscuretestdata", "i\x8c\x01,"}, - {"internal/oserror", "q"}, - {"internal/pkgbits", "\x03O\x18\a\x03\x04\vr\r\x1f\r\n\x01"}, + {"internal/obscuretestdata", "k\x8e\x01,"}, + {"internal/oserror", "s"}, + {"internal/pkgbits", "\x03Q\x18\a\x03\x04\fs\r\x1f\r\n\x01"}, {"internal/platform", ""}, - {"internal/poll", "qj\x05\x159\r\x01\x01\f\x06"}, - {"internal/profile", "\x03\x04j\x03\x81\x017\n\x01\x01\x01\x10"}, + {"internal/poll", "sl\x05\x159\r\x01\x01\f\x06"}, + {"internal/profile", "\x03\x04l\x03\x83\x017\n\x01\x01\x01\x10"}, {"internal/profilerecord", ""}, - {"internal/race", "\x97\x01\xb8\x01"}, - {"internal/reflectlite", "\x97\x01!:\x16"}, - {"vendor/golang.org/x/text/unicode/norm", "j\n\x81\x01F\x12\x11"}, - {"weak", "\x97\x01\x97\x01!"}, + {"vendor/golang.org/x/crypto/internal/alias", "\xd3\x02"}, + {"vendor/golang.org/x/crypto/internal/poly1305", "W\x15\x9c\x01"}, + {"vendor/golang.org/x/net/dns/dnsmessage", "s\xc7\x01"}, + {"vendor/golang.org/x/net/http/httpguts", "\x8f\x02\x14\x1a\x14\r"}, + {"vendor/golang.org/x/net/http/httpproxy", "s\x03\x99\x01\x10\x05\x01\x18\x14\r"}, + {"vendor/golang.org/x/net/http2/hpack", "\x03p\x03\x83\x01F"}, + {"vendor/golang.org/x/net/idna", "v\x8f\x018\x14\x10\x02\x01"}, + {"vendor/golang.org/x/net/nettest", "\x03i\a\x03\x83\x01\x11\x05\x16\x01\f\n\x01\x02\x02\x01\v"}, + {"vendor/golang.org/x/sys/cpu", "\xa5\x02\r\n\x01\x16"}, + {"vendor/golang.org/x/text/secure/bidirule", "s\xde\x01\x11\x01"}, + {"vendor/golang.org/x/text/transform", "\x03p\x86\x01X"}, + {"vendor/golang.org/x/text/unicode/bidi", "\x03\bk\x87\x01>\x16"}, + {"vendor/golang.org/x/text/unicode/norm", "l\n\x83\x01F\x12\x11"}, + {"weak", "\x9a\x01\x98\x01!"}, } // bootstrap is the list of bootstrap packages extracted from cmd/dist. @@ -385,6 +389,7 @@ var bootstrap = map[string]bool{ "cmd/compile/internal/arm64": true, "cmd/compile/internal/base": true, "cmd/compile/internal/bitvec": true, + "cmd/compile/internal/bloop": true, "cmd/compile/internal/compare": true, "cmd/compile/internal/coverage": true, "cmd/compile/internal/deadlocals": true, @@ -413,6 +418,7 @@ var bootstrap = map[string]bool{ "cmd/compile/internal/riscv64": true, "cmd/compile/internal/rttype": true, "cmd/compile/internal/s390x": true, + "cmd/compile/internal/slice": true, "cmd/compile/internal/ssa": true, "cmd/compile/internal/ssagen": true, "cmd/compile/internal/staticdata": true, diff --git a/vendor/golang.org/x/tools/internal/stdlib/manifest.go b/vendor/golang.org/x/tools/internal/stdlib/manifest.go index 362f23c436..f1e24625a7 100644 --- a/vendor/golang.org/x/tools/internal/stdlib/manifest.go +++ b/vendor/golang.org/x/tools/internal/stdlib/manifest.go @@ -16,6 +16,14 @@ var PackageSymbols = map[string][]Symbol{ {"(*Writer).Flush", Method, 0, ""}, {"(*Writer).Write", Method, 0, ""}, {"(*Writer).WriteHeader", Method, 0, ""}, + {"(FileInfoNames).Gname", Method, 23, ""}, + {"(FileInfoNames).IsDir", Method, 23, ""}, + {"(FileInfoNames).ModTime", Method, 23, ""}, + {"(FileInfoNames).Mode", Method, 23, ""}, + {"(FileInfoNames).Name", Method, 23, ""}, + {"(FileInfoNames).Size", Method, 23, ""}, + {"(FileInfoNames).Sys", Method, 23, ""}, + {"(FileInfoNames).Uname", Method, 23, ""}, {"(Format).String", Method, 10, ""}, {"ErrFieldTooLong", Var, 0, ""}, {"ErrHeader", Var, 0, ""}, @@ -338,6 +346,9 @@ var PackageSymbols = map[string][]Symbol{ {"(*Writer).Write", Method, 0, ""}, {"(CorruptInputError).Error", Method, 0, ""}, {"(InternalError).Error", Method, 0, ""}, + {"(Reader).Read", Method, 0, ""}, + {"(Reader).ReadByte", Method, 0, ""}, + {"(Resetter).Reset", Method, 4, ""}, {"BestCompression", Const, 0, ""}, {"BestSpeed", Const, 0, ""}, {"CorruptInputError", Type, 0, ""}, @@ -409,6 +420,7 @@ var PackageSymbols = map[string][]Symbol{ {"(*Writer).Flush", Method, 0, ""}, {"(*Writer).Reset", Method, 2, ""}, {"(*Writer).Write", Method, 0, ""}, + {"(Resetter).Reset", Method, 4, ""}, {"BestCompression", Const, 0, ""}, {"BestSpeed", Const, 0, ""}, {"DefaultCompression", Const, 0, ""}, @@ -426,6 +438,11 @@ var PackageSymbols = map[string][]Symbol{ {"Writer", Type, 0, ""}, }, "container/heap": { + {"(Interface).Len", Method, 0, ""}, + {"(Interface).Less", Method, 0, ""}, + {"(Interface).Pop", Method, 0, ""}, + {"(Interface).Push", Method, 0, ""}, + {"(Interface).Swap", Method, 0, ""}, {"Fix", Func, 2, "func(h Interface, i int)"}, {"Init", Func, 0, "func(h Interface)"}, {"Interface", Type, 0, ""}, @@ -469,6 +486,10 @@ var PackageSymbols = map[string][]Symbol{ {"Ring.Value", Field, 0, ""}, }, "context": { + {"(Context).Deadline", Method, 7, ""}, + {"(Context).Done", Method, 7, ""}, + {"(Context).Err", Method, 7, ""}, + {"(Context).Value", Method, 7, ""}, {"AfterFunc", Func, 21, "func(ctx Context, f func()) (stop func() bool)"}, {"Background", Func, 7, "func() Context"}, {"CancelCauseFunc", Type, 20, ""}, @@ -488,17 +509,31 @@ var PackageSymbols = map[string][]Symbol{ {"WithoutCancel", Func, 21, "func(parent Context) Context"}, }, "crypto": { + {"(Decapsulator).Decapsulate", Method, 26, ""}, + {"(Decapsulator).Encapsulator", Method, 26, ""}, + {"(Decrypter).Decrypt", Method, 5, ""}, + {"(Decrypter).Public", Method, 5, ""}, + {"(Encapsulator).Bytes", Method, 26, ""}, + {"(Encapsulator).Encapsulate", Method, 26, ""}, {"(Hash).Available", Method, 0, ""}, {"(Hash).HashFunc", Method, 4, ""}, {"(Hash).New", Method, 0, ""}, {"(Hash).Size", Method, 0, ""}, {"(Hash).String", Method, 15, ""}, + {"(MessageSigner).Public", Method, 25, ""}, + {"(MessageSigner).Sign", Method, 25, ""}, + {"(MessageSigner).SignMessage", Method, 25, ""}, + {"(Signer).Public", Method, 4, ""}, + {"(Signer).Sign", Method, 4, ""}, + {"(SignerOpts).HashFunc", Method, 4, ""}, {"BLAKE2b_256", Const, 9, ""}, {"BLAKE2b_384", Const, 9, ""}, {"BLAKE2b_512", Const, 9, ""}, {"BLAKE2s_256", Const, 9, ""}, + {"Decapsulator", Type, 26, ""}, {"Decrypter", Type, 5, ""}, {"DecrypterOpts", Type, 5, ""}, + {"Encapsulator", Type, 26, ""}, {"Hash", Type, 0, ""}, {"MD4", Const, 0, ""}, {"MD5", Const, 0, ""}, @@ -530,6 +565,16 @@ var PackageSymbols = map[string][]Symbol{ {"NewCipher", Func, 0, "func(key []byte) (cipher.Block, error)"}, }, "crypto/cipher": { + {"(AEAD).NonceSize", Method, 2, ""}, + {"(AEAD).Open", Method, 2, ""}, + {"(AEAD).Overhead", Method, 2, ""}, + {"(AEAD).Seal", Method, 2, ""}, + {"(Block).BlockSize", Method, 0, ""}, + {"(Block).Decrypt", Method, 0, ""}, + {"(Block).Encrypt", Method, 0, ""}, + {"(BlockMode).BlockSize", Method, 0, ""}, + {"(BlockMode).CryptBlocks", Method, 0, ""}, + {"(Stream).XORKeyStream", Method, 0, ""}, {"(StreamReader).Read", Method, 0, ""}, {"(StreamWriter).Close", Method, 0, ""}, {"(StreamWriter).Write", Method, 0, ""}, @@ -594,7 +639,13 @@ var PackageSymbols = map[string][]Symbol{ {"(*PublicKey).Bytes", Method, 20, ""}, {"(*PublicKey).Curve", Method, 20, ""}, {"(*PublicKey).Equal", Method, 20, ""}, - {"Curve", Type, 20, ""}, + {"(Curve).GenerateKey", Method, 20, ""}, + {"(Curve).NewPrivateKey", Method, 20, ""}, + {"(Curve).NewPublicKey", Method, 20, ""}, + {"(KeyExchanger).Curve", Method, 26, ""}, + {"(KeyExchanger).ECDH", Method, 26, ""}, + {"(KeyExchanger).PublicKey", Method, 26, ""}, + {"KeyExchanger", Type, 26, ""}, {"P256", Func, 20, "func() Curve"}, {"P384", Func, 20, "func() Curve"}, {"P521", Func, 20, "func() Curve"}, @@ -667,6 +718,12 @@ var PackageSymbols = map[string][]Symbol{ {"(*CurveParams).Params", Method, 0, ""}, {"(*CurveParams).ScalarBaseMult", Method, 0, ""}, {"(*CurveParams).ScalarMult", Method, 0, ""}, + {"(Curve).Add", Method, 0, ""}, + {"(Curve).Double", Method, 0, ""}, + {"(Curve).IsOnCurve", Method, 0, ""}, + {"(Curve).Params", Method, 0, ""}, + {"(Curve).ScalarBaseMult", Method, 0, ""}, + {"(Curve).ScalarMult", Method, 0, ""}, {"Curve", Type, 0, ""}, {"CurveParams", Type, 0, ""}, {"CurveParams.B", Field, 0, ""}, @@ -688,6 +745,7 @@ var PackageSymbols = map[string][]Symbol{ }, "crypto/fips140": { {"Enabled", Func, 24, "func() bool"}, + {"Version", Func, 26, "func() string"}, }, "crypto/hkdf": { {"Expand", Func, 24, "func[H hash.Hash](h func() H, pseudorandomKey []byte, info string, keyLength int) ([]byte, error)"}, @@ -708,9 +766,11 @@ var PackageSymbols = map[string][]Symbol{ {"(*DecapsulationKey1024).Bytes", Method, 24, ""}, {"(*DecapsulationKey1024).Decapsulate", Method, 24, ""}, {"(*DecapsulationKey1024).EncapsulationKey", Method, 24, ""}, + {"(*DecapsulationKey1024).Encapsulator", Method, 26, ""}, {"(*DecapsulationKey768).Bytes", Method, 24, ""}, {"(*DecapsulationKey768).Decapsulate", Method, 24, ""}, {"(*DecapsulationKey768).EncapsulationKey", Method, 24, ""}, + {"(*DecapsulationKey768).Encapsulator", Method, 26, ""}, {"(*EncapsulationKey1024).Bytes", Method, 24, ""}, {"(*EncapsulationKey1024).Encapsulate", Method, 24, ""}, {"(*EncapsulationKey768).Bytes", Method, 24, ""}, @@ -732,6 +792,10 @@ var PackageSymbols = map[string][]Symbol{ {"SeedSize", Const, 24, ""}, {"SharedKeySize", Const, 24, ""}, }, + "crypto/mlkem/mlkemtest": { + {"Encapsulate1024", Func, 26, "func(ek *mlkem.EncapsulationKey1024, random []byte) (sharedKey []byte, ciphertext []byte, err error)"}, + {"Encapsulate768", Func, 26, "func(ek *mlkem.EncapsulationKey768, random []byte) (sharedKey []byte, ciphertext []byte, err error)"}, + }, "crypto/pbkdf2": { {"Key", Func, 24, "func[Hash hash.Hash](h func() Hash, password string, salt []byte, iter int, keyLength int) ([]byte, error)"}, }, @@ -769,6 +833,7 @@ var PackageSymbols = map[string][]Symbol{ {"DecryptPKCS1v15", Func, 0, "func(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error)"}, {"DecryptPKCS1v15SessionKey", Func, 0, "func(random io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) error"}, {"EncryptOAEP", Func, 0, "func(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error)"}, + {"EncryptOAEPWithOptions", Func, 26, "func(random io.Reader, pub *PublicKey, msg []byte, opts *OAEPOptions) ([]byte, error)"}, {"EncryptPKCS1v15", Func, 0, "func(random io.Reader, pub *PublicKey, msg []byte) ([]byte, error)"}, {"ErrDecryption", Var, 0, ""}, {"ErrMessageTooLong", Var, 0, ""}, @@ -921,6 +986,8 @@ var PackageSymbols = map[string][]Symbol{ {"(*SessionState).Bytes", Method, 21, ""}, {"(AlertError).Error", Method, 21, ""}, {"(ClientAuthType).String", Method, 15, ""}, + {"(ClientSessionCache).Get", Method, 3, ""}, + {"(ClientSessionCache).Put", Method, 3, ""}, {"(CurveID).String", Method, 15, ""}, {"(QUICEncryptionLevel).String", Method, 21, ""}, {"(RecordHeaderError).Error", Method, 6, ""}, @@ -953,6 +1020,7 @@ var PackageSymbols = map[string][]Symbol{ {"ClientHelloInfo.CipherSuites", Field, 4, ""}, {"ClientHelloInfo.Conn", Field, 8, ""}, {"ClientHelloInfo.Extensions", Field, 24, ""}, + {"ClientHelloInfo.HelloRetryRequest", Field, 26, ""}, {"ClientHelloInfo.ServerName", Field, 4, ""}, {"ClientHelloInfo.SignatureSchemes", Field, 8, ""}, {"ClientHelloInfo.SupportedCurves", Field, 4, ""}, @@ -1001,6 +1069,7 @@ var PackageSymbols = map[string][]Symbol{ {"ConnectionState.DidResume", Field, 1, ""}, {"ConnectionState.ECHAccepted", Field, 23, ""}, {"ConnectionState.HandshakeComplete", Field, 0, ""}, + {"ConnectionState.HelloRetryRequest", Field, 26, ""}, {"ConnectionState.NegotiatedProtocol", Field, 0, ""}, {"ConnectionState.NegotiatedProtocolIsMutual", Field, 0, ""}, {"ConnectionState.OCSPResponse", Field, 5, ""}, @@ -1055,8 +1124,10 @@ var PackageSymbols = map[string][]Symbol{ {"QUICEncryptionLevelEarly", Const, 21, ""}, {"QUICEncryptionLevelHandshake", Const, 21, ""}, {"QUICEncryptionLevelInitial", Const, 21, ""}, + {"QUICErrorEvent", Const, 26, ""}, {"QUICEvent", Type, 21, ""}, {"QUICEvent.Data", Field, 21, ""}, + {"QUICEvent.Err", Field, 26, ""}, {"QUICEvent.Kind", Field, 21, ""}, {"QUICEvent.Level", Field, 21, ""}, {"QUICEvent.SessionState", Field, 23, ""}, @@ -1151,8 +1222,10 @@ var PackageSymbols = map[string][]Symbol{ {"(*RevocationList).CheckSignatureFrom", Method, 19, ""}, {"(CertificateInvalidError).Error", Method, 0, ""}, {"(ConstraintViolationError).Error", Method, 0, ""}, + {"(ExtKeyUsage).String", Method, 26, ""}, {"(HostnameError).Error", Method, 0, ""}, {"(InsecureAlgorithmError).Error", Method, 6, ""}, + {"(KeyUsage).String", Method, 26, ""}, {"(OID).AppendBinary", Method, 24, ""}, {"(OID).AppendText", Method, 24, ""}, {"(OID).Equal", Method, 22, ""}, @@ -1516,6 +1589,9 @@ var PackageSymbols = map[string][]Symbol{ {"(NullInt64).Value", Method, 0, ""}, {"(NullString).Value", Method, 0, ""}, {"(NullTime).Value", Method, 13, ""}, + {"(Result).LastInsertId", Method, 0, ""}, + {"(Result).RowsAffected", Method, 0, ""}, + {"(Scanner).Scan", Method, 0, ""}, {"ColumnType", Type, 8, ""}, {"Conn", Type, 9, ""}, {"DB", Type, 0, ""}, @@ -1547,8 +1623,6 @@ var PackageSymbols = map[string][]Symbol{ {"NamedArg.Name", Field, 8, ""}, {"NamedArg.Value", Field, 8, ""}, {"Null", Type, 22, ""}, - {"Null.V", Field, 22, ""}, - {"Null.Valid", Field, 22, ""}, {"NullBool", Type, 0, ""}, {"NullBool.Bool", Field, 0, ""}, {"NullBool.Valid", Field, 0, ""}, @@ -1591,10 +1665,72 @@ var PackageSymbols = map[string][]Symbol{ {"TxOptions.ReadOnly", Field, 8, ""}, }, "database/sql/driver": { + {"(ColumnConverter).ColumnConverter", Method, 0, ""}, + {"(Conn).Begin", Method, 0, ""}, + {"(Conn).Close", Method, 0, ""}, + {"(Conn).Prepare", Method, 0, ""}, + {"(ConnBeginTx).BeginTx", Method, 8, ""}, + {"(ConnPrepareContext).PrepareContext", Method, 8, ""}, + {"(Connector).Connect", Method, 10, ""}, + {"(Connector).Driver", Method, 10, ""}, + {"(Driver).Open", Method, 0, ""}, + {"(DriverContext).OpenConnector", Method, 10, ""}, + {"(Execer).Exec", Method, 0, ""}, + {"(ExecerContext).ExecContext", Method, 8, ""}, + {"(NamedValueChecker).CheckNamedValue", Method, 9, ""}, {"(NotNull).ConvertValue", Method, 0, ""}, {"(Null).ConvertValue", Method, 0, ""}, + {"(Pinger).Ping", Method, 8, ""}, + {"(Queryer).Query", Method, 1, ""}, + {"(QueryerContext).QueryContext", Method, 8, ""}, + {"(Result).LastInsertId", Method, 0, ""}, + {"(Result).RowsAffected", Method, 0, ""}, + {"(Rows).Close", Method, 0, ""}, + {"(Rows).Columns", Method, 0, ""}, + {"(Rows).Next", Method, 0, ""}, {"(RowsAffected).LastInsertId", Method, 0, ""}, {"(RowsAffected).RowsAffected", Method, 0, ""}, + {"(RowsColumnScanner).Close", Method, 26, ""}, + {"(RowsColumnScanner).Columns", Method, 26, ""}, + {"(RowsColumnScanner).Next", Method, 26, ""}, + {"(RowsColumnScanner).ScanColumn", Method, 26, ""}, + {"(RowsColumnTypeDatabaseTypeName).Close", Method, 8, ""}, + {"(RowsColumnTypeDatabaseTypeName).ColumnTypeDatabaseTypeName", Method, 8, ""}, + {"(RowsColumnTypeDatabaseTypeName).Columns", Method, 8, ""}, + {"(RowsColumnTypeDatabaseTypeName).Next", Method, 8, ""}, + {"(RowsColumnTypeLength).Close", Method, 8, ""}, + {"(RowsColumnTypeLength).ColumnTypeLength", Method, 8, ""}, + {"(RowsColumnTypeLength).Columns", Method, 8, ""}, + {"(RowsColumnTypeLength).Next", Method, 8, ""}, + {"(RowsColumnTypeNullable).Close", Method, 8, ""}, + {"(RowsColumnTypeNullable).ColumnTypeNullable", Method, 8, ""}, + {"(RowsColumnTypeNullable).Columns", Method, 8, ""}, + {"(RowsColumnTypeNullable).Next", Method, 8, ""}, + {"(RowsColumnTypePrecisionScale).Close", Method, 8, ""}, + {"(RowsColumnTypePrecisionScale).ColumnTypePrecisionScale", Method, 8, ""}, + {"(RowsColumnTypePrecisionScale).Columns", Method, 8, ""}, + {"(RowsColumnTypePrecisionScale).Next", Method, 8, ""}, + {"(RowsColumnTypeScanType).Close", Method, 8, ""}, + {"(RowsColumnTypeScanType).ColumnTypeScanType", Method, 8, ""}, + {"(RowsColumnTypeScanType).Columns", Method, 8, ""}, + {"(RowsColumnTypeScanType).Next", Method, 8, ""}, + {"(RowsNextResultSet).Close", Method, 8, ""}, + {"(RowsNextResultSet).Columns", Method, 8, ""}, + {"(RowsNextResultSet).HasNextResultSet", Method, 8, ""}, + {"(RowsNextResultSet).Next", Method, 8, ""}, + {"(RowsNextResultSet).NextResultSet", Method, 8, ""}, + {"(SessionResetter).ResetSession", Method, 10, ""}, + {"(Stmt).Close", Method, 0, ""}, + {"(Stmt).Exec", Method, 0, ""}, + {"(Stmt).NumInput", Method, 0, ""}, + {"(Stmt).Query", Method, 0, ""}, + {"(StmtExecContext).ExecContext", Method, 8, ""}, + {"(StmtQueryContext).QueryContext", Method, 8, ""}, + {"(Tx).Commit", Method, 0, ""}, + {"(Tx).Rollback", Method, 0, ""}, + {"(Validator).IsValid", Method, 15, ""}, + {"(ValueConverter).ConvertValue", Method, 0, ""}, + {"(Valuer).Value", Method, 0, ""}, {"Bool", Var, 0, ""}, {"ColumnConverter", Type, 0, ""}, {"Conn", Type, 0, ""}, @@ -1756,6 +1892,9 @@ var PackageSymbols = map[string][]Symbol{ {"(DecodeError).Error", Method, 0, ""}, {"(Tag).GoString", Method, 0, ""}, {"(Tag).String", Method, 0, ""}, + {"(Type).Common", Method, 0, ""}, + {"(Type).Size", Method, 0, ""}, + {"(Type).String", Method, 0, ""}, {"AddrType", Type, 0, ""}, {"AddrType.BasicType", Field, 0, ""}, {"ArrayType", Type, 0, ""}, @@ -3163,6 +3302,7 @@ var PackageSymbols = map[string][]Symbol{ {"R_LARCH_B16", Const, 20, ""}, {"R_LARCH_B21", Const, 20, ""}, {"R_LARCH_B26", Const, 20, ""}, + {"R_LARCH_CALL36", Const, 26, ""}, {"R_LARCH_CFA", Const, 22, ""}, {"R_LARCH_COPY", Const, 19, ""}, {"R_LARCH_DELETE", Const, 22, ""}, @@ -3220,11 +3360,25 @@ var PackageSymbols = map[string][]Symbol{ {"R_LARCH_SUB64", Const, 19, ""}, {"R_LARCH_SUB8", Const, 19, ""}, {"R_LARCH_SUB_ULEB128", Const, 22, ""}, + {"R_LARCH_TLS_DESC32", Const, 26, ""}, + {"R_LARCH_TLS_DESC64", Const, 26, ""}, + {"R_LARCH_TLS_DESC64_HI12", Const, 26, ""}, + {"R_LARCH_TLS_DESC64_LO20", Const, 26, ""}, + {"R_LARCH_TLS_DESC64_PC_HI12", Const, 26, ""}, + {"R_LARCH_TLS_DESC64_PC_LO20", Const, 26, ""}, + {"R_LARCH_TLS_DESC_CALL", Const, 26, ""}, + {"R_LARCH_TLS_DESC_HI20", Const, 26, ""}, + {"R_LARCH_TLS_DESC_LD", Const, 26, ""}, + {"R_LARCH_TLS_DESC_LO12", Const, 26, ""}, + {"R_LARCH_TLS_DESC_PCREL20_S2", Const, 26, ""}, + {"R_LARCH_TLS_DESC_PC_HI20", Const, 26, ""}, + {"R_LARCH_TLS_DESC_PC_LO12", Const, 26, ""}, {"R_LARCH_TLS_DTPMOD32", Const, 19, ""}, {"R_LARCH_TLS_DTPMOD64", Const, 19, ""}, {"R_LARCH_TLS_DTPREL32", Const, 19, ""}, {"R_LARCH_TLS_DTPREL64", Const, 19, ""}, {"R_LARCH_TLS_GD_HI20", Const, 20, ""}, + {"R_LARCH_TLS_GD_PCREL20_S2", Const, 26, ""}, {"R_LARCH_TLS_GD_PC_HI20", Const, 20, ""}, {"R_LARCH_TLS_IE64_HI12", Const, 20, ""}, {"R_LARCH_TLS_IE64_LO20", Const, 20, ""}, @@ -3235,11 +3389,15 @@ var PackageSymbols = map[string][]Symbol{ {"R_LARCH_TLS_IE_PC_HI20", Const, 20, ""}, {"R_LARCH_TLS_IE_PC_LO12", Const, 20, ""}, {"R_LARCH_TLS_LD_HI20", Const, 20, ""}, + {"R_LARCH_TLS_LD_PCREL20_S2", Const, 26, ""}, {"R_LARCH_TLS_LD_PC_HI20", Const, 20, ""}, {"R_LARCH_TLS_LE64_HI12", Const, 20, ""}, {"R_LARCH_TLS_LE64_LO20", Const, 20, ""}, + {"R_LARCH_TLS_LE_ADD_R", Const, 26, ""}, {"R_LARCH_TLS_LE_HI20", Const, 20, ""}, + {"R_LARCH_TLS_LE_HI20_R", Const, 26, ""}, {"R_LARCH_TLS_LE_LO12", Const, 20, ""}, + {"R_LARCH_TLS_LE_LO12_R", Const, 26, ""}, {"R_LARCH_TLS_TPREL32", Const, 19, ""}, {"R_LARCH_TLS_TPREL64", Const, 19, ""}, {"R_MIPS", Type, 6, ""}, @@ -3944,6 +4102,7 @@ var PackageSymbols = map[string][]Symbol{ {"(FatArch).ImportedSymbols", Method, 3, ""}, {"(FatArch).Section", Method, 3, ""}, {"(FatArch).Segment", Method, 3, ""}, + {"(Load).Raw", Method, 0, ""}, {"(LoadBytes).Raw", Method, 0, ""}, {"(LoadCmd).GoString", Method, 0, ""}, {"(LoadCmd).String", Method, 0, ""}, @@ -4590,6 +4749,12 @@ var PackageSymbols = map[string][]Symbol{ {"FS", Type, 16, ""}, }, "encoding": { + {"(BinaryAppender).AppendBinary", Method, 24, ""}, + {"(BinaryMarshaler).MarshalBinary", Method, 2, ""}, + {"(BinaryUnmarshaler).UnmarshalBinary", Method, 2, ""}, + {"(TextAppender).AppendText", Method, 24, ""}, + {"(TextMarshaler).MarshalText", Method, 2, ""}, + {"(TextUnmarshaler).UnmarshalText", Method, 2, ""}, {"BinaryAppender", Type, 24, ""}, {"BinaryMarshaler", Type, 2, ""}, {"BinaryUnmarshaler", Type, 2, ""}, @@ -4705,6 +4870,17 @@ var PackageSymbols = map[string][]Symbol{ {"URLEncoding", Var, 0, ""}, }, "encoding/binary": { + {"(AppendByteOrder).AppendUint16", Method, 19, ""}, + {"(AppendByteOrder).AppendUint32", Method, 19, ""}, + {"(AppendByteOrder).AppendUint64", Method, 19, ""}, + {"(AppendByteOrder).String", Method, 19, ""}, + {"(ByteOrder).PutUint16", Method, 0, ""}, + {"(ByteOrder).PutUint32", Method, 0, ""}, + {"(ByteOrder).PutUint64", Method, 0, ""}, + {"(ByteOrder).String", Method, 0, ""}, + {"(ByteOrder).Uint16", Method, 0, ""}, + {"(ByteOrder).Uint32", Method, 0, ""}, + {"(ByteOrder).Uint64", Method, 0, ""}, {"Append", Func, 23, "func(buf []byte, order ByteOrder, data any) ([]byte, error)"}, {"AppendByteOrder", Type, 19, ""}, {"AppendUvarint", Func, 19, "func(buf []byte, x uint64) []byte"}, @@ -4767,6 +4943,8 @@ var PackageSymbols = map[string][]Symbol{ {"(*Decoder).DecodeValue", Method, 0, ""}, {"(*Encoder).Encode", Method, 0, ""}, {"(*Encoder).EncodeValue", Method, 0, ""}, + {"(GobDecoder).GobDecode", Method, 0, ""}, + {"(GobEncoder).GobEncode", Method, 0, ""}, {"CommonType", Type, 0, ""}, {"CommonType.Id", Field, 0, ""}, {"CommonType.Name", Field, 0, ""}, @@ -4819,10 +4997,12 @@ var PackageSymbols = map[string][]Symbol{ {"(*UnsupportedTypeError).Error", Method, 0, ""}, {"(*UnsupportedValueError).Error", Method, 0, ""}, {"(Delim).String", Method, 5, ""}, + {"(Marshaler).MarshalJSON", Method, 0, ""}, {"(Number).Float64", Method, 1, ""}, {"(Number).Int64", Method, 1, ""}, {"(Number).String", Method, 1, ""}, {"(RawMessage).MarshalJSON", Method, 8, ""}, + {"(Unmarshaler).UnmarshalJSON", Method, 0, ""}, {"Compact", Func, 0, "func(dst *bytes.Buffer, src []byte) error"}, {"Decoder", Type, 0, ""}, {"Delim", Type, 5, ""}, @@ -4894,10 +5074,15 @@ var PackageSymbols = map[string][]Symbol{ {"(CharData).Copy", Method, 0, ""}, {"(Comment).Copy", Method, 0, ""}, {"(Directive).Copy", Method, 0, ""}, + {"(Marshaler).MarshalXML", Method, 2, ""}, + {"(MarshalerAttr).MarshalXMLAttr", Method, 2, ""}, {"(ProcInst).Copy", Method, 0, ""}, {"(StartElement).Copy", Method, 0, ""}, {"(StartElement).End", Method, 2, ""}, + {"(TokenReader).Token", Method, 10, ""}, {"(UnmarshalError).Error", Method, 0, ""}, + {"(Unmarshaler).UnmarshalXML", Method, 2, ""}, + {"(UnmarshalerAttr).UnmarshalXMLAttr", Method, 2, ""}, {"Attr", Type, 0, ""}, {"Attr.Name", Field, 0, ""}, {"Attr.Value", Field, 0, ""}, @@ -4984,6 +5169,7 @@ var PackageSymbols = map[string][]Symbol{ {"(*String).Value", Method, 8, ""}, {"(Func).String", Method, 0, ""}, {"(Func).Value", Method, 8, ""}, + {"(Var).String", Method, 0, ""}, {"Do", Func, 0, "func(f func(KeyValue))"}, {"Float", Type, 0, ""}, {"Func", Type, 0, ""}, @@ -5039,6 +5225,11 @@ var PackageSymbols = map[string][]Symbol{ {"(*FlagSet).Var", Method, 0, ""}, {"(*FlagSet).Visit", Method, 0, ""}, {"(*FlagSet).VisitAll", Method, 0, ""}, + {"(Getter).Get", Method, 2, ""}, + {"(Getter).Set", Method, 2, ""}, + {"(Getter).String", Method, 2, ""}, + {"(Value).Set", Method, 0, ""}, + {"(Value).String", Method, 0, ""}, {"Arg", Func, 0, "func(i int) string"}, {"Args", Func, 0, "func() []string"}, {"Bool", Func, 0, "func(name string, value bool, usage string) *bool"}, @@ -5090,6 +5281,20 @@ var PackageSymbols = map[string][]Symbol{ {"VisitAll", Func, 0, "func(fn func(*Flag))"}, }, "fmt": { + {"(Formatter).Format", Method, 0, ""}, + {"(GoStringer).GoString", Method, 0, ""}, + {"(ScanState).Read", Method, 0, ""}, + {"(ScanState).ReadRune", Method, 0, ""}, + {"(ScanState).SkipSpace", Method, 0, ""}, + {"(ScanState).Token", Method, 0, ""}, + {"(ScanState).UnreadRune", Method, 0, ""}, + {"(ScanState).Width", Method, 0, ""}, + {"(Scanner).Scan", Method, 0, ""}, + {"(State).Flag", Method, 0, ""}, + {"(State).Precision", Method, 0, ""}, + {"(State).Width", Method, 0, ""}, + {"(State).Write", Method, 0, ""}, + {"(Stringer).String", Method, 0, ""}, {"Append", Func, 19, "func(b []byte, a ...any) []byte"}, {"Appendf", Func, 19, "func(b []byte, format string, a ...any) []byte"}, {"Appendln", Func, 19, "func(b []byte, a ...any) []byte"}, @@ -5248,7 +5453,18 @@ var PackageSymbols = map[string][]Symbol{ {"(CommentMap).Filter", Method, 1, ""}, {"(CommentMap).String", Method, 1, ""}, {"(CommentMap).Update", Method, 1, ""}, + {"(Decl).End", Method, 0, ""}, + {"(Decl).Pos", Method, 0, ""}, + {"(Expr).End", Method, 0, ""}, + {"(Expr).Pos", Method, 0, ""}, + {"(Node).End", Method, 0, ""}, + {"(Node).Pos", Method, 0, ""}, {"(ObjKind).String", Method, 0, ""}, + {"(Spec).End", Method, 0, ""}, + {"(Spec).Pos", Method, 0, ""}, + {"(Stmt).End", Method, 0, ""}, + {"(Stmt).Pos", Method, 0, ""}, + {"(Visitor).Visit", Method, 0, ""}, {"ArrayType", Type, 0, ""}, {"ArrayType.Elt", Field, 0, ""}, {"ArrayType.Lbrack", Field, 0, ""}, @@ -5271,6 +5487,7 @@ var PackageSymbols = map[string][]Symbol{ {"BasicLit", Type, 0, ""}, {"BasicLit.Kind", Field, 0, ""}, {"BasicLit.Value", Field, 0, ""}, + {"BasicLit.ValueEnd", Field, 26, ""}, {"BasicLit.ValuePos", Field, 0, ""}, {"BinaryExpr", Type, 0, ""}, {"BinaryExpr.Op", Field, 0, ""}, @@ -5320,7 +5537,6 @@ var PackageSymbols = map[string][]Symbol{ {"CompositeLit.Rbrace", Field, 0, ""}, {"CompositeLit.Type", Field, 0, ""}, {"Con", Const, 0, ""}, - {"Decl", Type, 0, ""}, {"DeclStmt", Type, 0, ""}, {"DeclStmt.Decl", Field, 0, ""}, {"DeferStmt", Type, 0, ""}, @@ -5341,7 +5557,6 @@ var PackageSymbols = map[string][]Symbol{ {"EmptyStmt", Type, 0, ""}, {"EmptyStmt.Implicit", Field, 5, ""}, {"EmptyStmt.Semicolon", Field, 0, ""}, - {"Expr", Type, 0, ""}, {"ExprStmt", Type, 0, ""}, {"ExprStmt.X", Field, 0, ""}, {"Field", Type, 0, ""}, @@ -5525,11 +5740,9 @@ var PackageSymbols = map[string][]Symbol{ {"SliceExpr.Slice3", Field, 2, ""}, {"SliceExpr.X", Field, 0, ""}, {"SortImports", Func, 0, "func(fset *token.FileSet, f *File)"}, - {"Spec", Type, 0, ""}, {"StarExpr", Type, 0, ""}, {"StarExpr.Star", Field, 0, ""}, {"StarExpr.X", Field, 0, ""}, - {"Stmt", Type, 0, ""}, {"StructType", Type, 0, ""}, {"StructType.Fields", Field, 0, ""}, {"StructType.Incomplete", Field, 0, ""}, @@ -5684,10 +5897,11 @@ var PackageSymbols = map[string][]Symbol{ {"(*SyntaxError).Error", Method, 16, ""}, {"(*TagExpr).Eval", Method, 16, ""}, {"(*TagExpr).String", Method, 16, ""}, + {"(Expr).Eval", Method, 16, ""}, + {"(Expr).String", Method, 16, ""}, {"AndExpr", Type, 16, ""}, {"AndExpr.X", Field, 16, ""}, {"AndExpr.Y", Field, 16, ""}, - {"Expr", Type, 16, ""}, {"GoVersion", Func, 21, "func(x Expr) string"}, {"IsGoBuild", Func, 16, "func(line string) bool"}, {"IsPlusBuild", Func, 16, "func(line string) bool"}, @@ -5706,6 +5920,9 @@ var PackageSymbols = map[string][]Symbol{ }, "go/constant": { {"(Kind).String", Method, 18, ""}, + {"(Value).ExactString", Method, 6, ""}, + {"(Value).Kind", Method, 5, ""}, + {"(Value).String", Method, 5, ""}, {"BinaryOp", Func, 5, "func(x_ Value, op token.Token, y_ Value) Value"}, {"BitLen", Func, 5, "func(x Value) int"}, {"Bool", Const, 5, ""}, @@ -5744,7 +5961,6 @@ var PackageSymbols = map[string][]Symbol{ {"UnaryOp", Func, 5, "func(op token.Token, y Value, prec uint) Value"}, {"Unknown", Const, 5, ""}, {"Val", Func, 13, "func(x Value) any"}, - {"Value", Type, 5, ""}, }, "go/doc": { {"(*Package).Filter", Method, 0, ""}, @@ -5828,7 +6044,6 @@ var PackageSymbols = map[string][]Symbol{ {"(*Printer).HTML", Method, 19, ""}, {"(*Printer).Markdown", Method, 19, ""}, {"(*Printer).Text", Method, 19, ""}, - {"Block", Type, 19, ""}, {"Code", Type, 19, ""}, {"Code.Text", Field, 19, ""}, {"DefaultLookupPackage", Func, 19, "func(name string) (importPath string, ok bool)"}, @@ -5873,7 +6088,6 @@ var PackageSymbols = map[string][]Symbol{ {"Printer.TextCodePrefix", Field, 19, ""}, {"Printer.TextPrefix", Field, 19, ""}, {"Printer.TextWidth", Field, 19, ""}, - {"Text", Type, 19, ""}, }, "go/format": { {"Node", Func, 1, "func(dst io.Writer, fset *token.FileSet, node any) error"}, @@ -5945,6 +6159,7 @@ var PackageSymbols = map[string][]Symbol{ {"(*File).AddLineColumnInfo", Method, 11, ""}, {"(*File).AddLineInfo", Method, 0, ""}, {"(*File).Base", Method, 0, ""}, + {"(*File).End", Method, 26, ""}, {"(*File).Line", Method, 0, ""}, {"(*File).LineCount", Method, 0, ""}, {"(*File).LineStart", Method, 12, ""}, @@ -6307,6 +6522,22 @@ var PackageSymbols = map[string][]Symbol{ {"(Checker).PkgNameOf", Method, 22, ""}, {"(Checker).TypeOf", Method, 5, ""}, {"(Error).Error", Method, 5, ""}, + {"(Importer).Import", Method, 5, ""}, + {"(ImporterFrom).Import", Method, 6, ""}, + {"(ImporterFrom).ImportFrom", Method, 6, ""}, + {"(Object).Exported", Method, 5, ""}, + {"(Object).Id", Method, 5, ""}, + {"(Object).Name", Method, 5, ""}, + {"(Object).Parent", Method, 5, ""}, + {"(Object).Pkg", Method, 5, ""}, + {"(Object).Pos", Method, 5, ""}, + {"(Object).String", Method, 5, ""}, + {"(Object).Type", Method, 5, ""}, + {"(Sizes).Alignof", Method, 5, ""}, + {"(Sizes).Offsetsof", Method, 5, ""}, + {"(Sizes).Sizeof", Method, 5, ""}, + {"(Type).String", Method, 5, ""}, + {"(Type).Underlying", Method, 5, ""}, {"(TypeAndValue).Addressable", Method, 5, ""}, {"(TypeAndValue).Assignable", Method, 5, ""}, {"(TypeAndValue).HasOk", Method, 5, ""}, @@ -6445,7 +6676,6 @@ var PackageSymbols = map[string][]Symbol{ {"NewUnion", Func, 18, "func(terms []*Term) *Union"}, {"NewVar", Func, 5, "func(pos token.Pos, pkg *Package, name string, typ Type) *Var"}, {"Nil", Type, 5, ""}, - {"Object", Type, 5, ""}, {"ObjectString", Func, 5, "func(obj Object, qf Qualifier) string"}, {"Package", Type, 5, ""}, {"PackageVar", Const, 25, ""}, @@ -6516,6 +6746,33 @@ var PackageSymbols = map[string][]Symbol{ {"Lang", Func, 22, "func(x string) string"}, }, "hash": { + {"(Cloner).BlockSize", Method, 25, ""}, + {"(Cloner).Clone", Method, 25, ""}, + {"(Cloner).Reset", Method, 25, ""}, + {"(Cloner).Size", Method, 25, ""}, + {"(Cloner).Sum", Method, 25, ""}, + {"(Cloner).Write", Method, 25, ""}, + {"(Hash).BlockSize", Method, 0, ""}, + {"(Hash).Reset", Method, 0, ""}, + {"(Hash).Size", Method, 0, ""}, + {"(Hash).Sum", Method, 0, ""}, + {"(Hash).Write", Method, 0, ""}, + {"(Hash32).BlockSize", Method, 0, ""}, + {"(Hash32).Reset", Method, 0, ""}, + {"(Hash32).Size", Method, 0, ""}, + {"(Hash32).Sum", Method, 0, ""}, + {"(Hash32).Sum32", Method, 0, ""}, + {"(Hash32).Write", Method, 0, ""}, + {"(Hash64).BlockSize", Method, 0, ""}, + {"(Hash64).Reset", Method, 0, ""}, + {"(Hash64).Size", Method, 0, ""}, + {"(Hash64).Sum", Method, 0, ""}, + {"(Hash64).Sum64", Method, 0, ""}, + {"(Hash64).Write", Method, 0, ""}, + {"(XOF).BlockSize", Method, 25, ""}, + {"(XOF).Read", Method, 25, ""}, + {"(XOF).Reset", Method, 25, ""}, + {"(XOF).Write", Method, 25, ""}, {"Cloner", Type, 25, ""}, {"Hash", Type, 0, ""}, {"Hash32", Type, 0, ""}, @@ -6781,6 +7038,13 @@ var PackageSymbols = map[string][]Symbol{ {"(*YCbCr).SubImage", Method, 0, ""}, {"(*YCbCr).YCbCrAt", Method, 4, ""}, {"(*YCbCr).YOffset", Method, 0, ""}, + {"(Image).At", Method, 0, ""}, + {"(Image).Bounds", Method, 0, ""}, + {"(Image).ColorModel", Method, 0, ""}, + {"(PalettedImage).At", Method, 0, ""}, + {"(PalettedImage).Bounds", Method, 0, ""}, + {"(PalettedImage).ColorIndexAt", Method, 0, ""}, + {"(PalettedImage).ColorModel", Method, 0, ""}, {"(Point).Add", Method, 0, ""}, {"(Point).Div", Method, 0, ""}, {"(Point).Eq", Method, 0, ""}, @@ -6789,6 +7053,10 @@ var PackageSymbols = map[string][]Symbol{ {"(Point).Mul", Method, 0, ""}, {"(Point).String", Method, 0, ""}, {"(Point).Sub", Method, 0, ""}, + {"(RGBA64Image).At", Method, 17, ""}, + {"(RGBA64Image).Bounds", Method, 17, ""}, + {"(RGBA64Image).ColorModel", Method, 17, ""}, + {"(RGBA64Image).RGBA64At", Method, 17, ""}, {"(Rectangle).Add", Method, 0, ""}, {"(Rectangle).At", Method, 5, ""}, {"(Rectangle).Bounds", Method, 5, ""}, @@ -6913,8 +7181,10 @@ var PackageSymbols = map[string][]Symbol{ {"(Alpha).RGBA", Method, 0, ""}, {"(Alpha16).RGBA", Method, 0, ""}, {"(CMYK).RGBA", Method, 5, ""}, + {"(Color).RGBA", Method, 0, ""}, {"(Gray).RGBA", Method, 0, ""}, {"(Gray16).RGBA", Method, 0, ""}, + {"(Model).Convert", Method, 0, ""}, {"(NRGBA).RGBA", Method, 0, ""}, {"(NRGBA64).RGBA", Method, 0, ""}, {"(NYCbCrA).RGBA", Method, 6, ""}, @@ -6992,7 +7262,19 @@ var PackageSymbols = map[string][]Symbol{ {"WebSafe", Var, 2, ""}, }, "image/draw": { + {"(Drawer).Draw", Method, 2, ""}, + {"(Image).At", Method, 0, ""}, + {"(Image).Bounds", Method, 0, ""}, + {"(Image).ColorModel", Method, 0, ""}, + {"(Image).Set", Method, 0, ""}, {"(Op).Draw", Method, 2, ""}, + {"(Quantizer).Quantize", Method, 2, ""}, + {"(RGBA64Image).At", Method, 17, ""}, + {"(RGBA64Image).Bounds", Method, 17, ""}, + {"(RGBA64Image).ColorModel", Method, 17, ""}, + {"(RGBA64Image).RGBA64At", Method, 17, ""}, + {"(RGBA64Image).Set", Method, 17, ""}, + {"(RGBA64Image).SetRGBA64", Method, 17, ""}, {"Draw", Func, 0, "func(dst Image, r image.Rectangle, src image.Image, sp image.Point, op Op)"}, {"DrawMask", Func, 0, "func(dst Image, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op)"}, {"Drawer", Type, 2, ""}, @@ -7027,6 +7309,8 @@ var PackageSymbols = map[string][]Symbol{ }, "image/jpeg": { {"(FormatError).Error", Method, 0, ""}, + {"(Reader).Read", Method, 0, ""}, + {"(Reader).ReadByte", Method, 0, ""}, {"(UnsupportedError).Error", Method, 0, ""}, {"Decode", Func, 0, "func(r io.Reader) (image.Image, error)"}, {"DecodeConfig", Func, 0, "func(r io.Reader) (image.Config, error)"}, @@ -7040,6 +7324,8 @@ var PackageSymbols = map[string][]Symbol{ }, "image/png": { {"(*Encoder).Encode", Method, 4, ""}, + {"(EncoderBufferPool).Get", Method, 9, ""}, + {"(EncoderBufferPool).Put", Method, 9, ""}, {"(FormatError).Error", Method, 0, ""}, {"(UnsupportedError).Error", Method, 0, ""}, {"BestCompression", Const, 4, ""}, @@ -7083,6 +7369,41 @@ var PackageSymbols = map[string][]Symbol{ {"(*SectionReader).ReadAt", Method, 0, ""}, {"(*SectionReader).Seek", Method, 0, ""}, {"(*SectionReader).Size", Method, 0, ""}, + {"(ByteReader).ReadByte", Method, 0, ""}, + {"(ByteScanner).ReadByte", Method, 0, ""}, + {"(ByteScanner).UnreadByte", Method, 0, ""}, + {"(ByteWriter).WriteByte", Method, 1, ""}, + {"(Closer).Close", Method, 0, ""}, + {"(ReadCloser).Close", Method, 0, ""}, + {"(ReadCloser).Read", Method, 0, ""}, + {"(ReadSeekCloser).Close", Method, 16, ""}, + {"(ReadSeekCloser).Read", Method, 16, ""}, + {"(ReadSeekCloser).Seek", Method, 16, ""}, + {"(ReadSeeker).Read", Method, 0, ""}, + {"(ReadSeeker).Seek", Method, 0, ""}, + {"(ReadWriteCloser).Close", Method, 0, ""}, + {"(ReadWriteCloser).Read", Method, 0, ""}, + {"(ReadWriteCloser).Write", Method, 0, ""}, + {"(ReadWriteSeeker).Read", Method, 0, ""}, + {"(ReadWriteSeeker).Seek", Method, 0, ""}, + {"(ReadWriteSeeker).Write", Method, 0, ""}, + {"(ReadWriter).Read", Method, 0, ""}, + {"(ReadWriter).Write", Method, 0, ""}, + {"(Reader).Read", Method, 0, ""}, + {"(ReaderAt).ReadAt", Method, 0, ""}, + {"(ReaderFrom).ReadFrom", Method, 0, ""}, + {"(RuneReader).ReadRune", Method, 0, ""}, + {"(RuneScanner).ReadRune", Method, 0, ""}, + {"(RuneScanner).UnreadRune", Method, 0, ""}, + {"(Seeker).Seek", Method, 0, ""}, + {"(StringWriter).WriteString", Method, 12, ""}, + {"(WriteCloser).Close", Method, 0, ""}, + {"(WriteCloser).Write", Method, 0, ""}, + {"(WriteSeeker).Seek", Method, 0, ""}, + {"(WriteSeeker).Write", Method, 0, ""}, + {"(Writer).Write", Method, 0, ""}, + {"(WriterAt).WriteAt", Method, 0, ""}, + {"(WriterTo).WriteTo", Method, 0, ""}, {"ByteReader", Type, 0, ""}, {"ByteScanner", Type, 0, ""}, {"ByteWriter", Type, 1, ""}, @@ -7142,11 +7463,42 @@ var PackageSymbols = map[string][]Symbol{ {"(*PathError).Error", Method, 16, ""}, {"(*PathError).Timeout", Method, 16, ""}, {"(*PathError).Unwrap", Method, 16, ""}, + {"(DirEntry).Info", Method, 16, ""}, + {"(DirEntry).IsDir", Method, 16, ""}, + {"(DirEntry).Name", Method, 16, ""}, + {"(DirEntry).Type", Method, 16, ""}, + {"(FS).Open", Method, 16, ""}, + {"(File).Close", Method, 16, ""}, + {"(File).Read", Method, 16, ""}, + {"(File).Stat", Method, 16, ""}, + {"(FileInfo).IsDir", Method, 16, ""}, + {"(FileInfo).ModTime", Method, 16, ""}, + {"(FileInfo).Mode", Method, 16, ""}, + {"(FileInfo).Name", Method, 16, ""}, + {"(FileInfo).Size", Method, 16, ""}, + {"(FileInfo).Sys", Method, 16, ""}, {"(FileMode).IsDir", Method, 16, ""}, {"(FileMode).IsRegular", Method, 16, ""}, {"(FileMode).Perm", Method, 16, ""}, {"(FileMode).String", Method, 16, ""}, {"(FileMode).Type", Method, 16, ""}, + {"(GlobFS).Glob", Method, 16, ""}, + {"(GlobFS).Open", Method, 16, ""}, + {"(ReadDirFS).Open", Method, 16, ""}, + {"(ReadDirFS).ReadDir", Method, 16, ""}, + {"(ReadDirFile).Close", Method, 16, ""}, + {"(ReadDirFile).Read", Method, 16, ""}, + {"(ReadDirFile).ReadDir", Method, 16, ""}, + {"(ReadDirFile).Stat", Method, 16, ""}, + {"(ReadFileFS).Open", Method, 16, ""}, + {"(ReadFileFS).ReadFile", Method, 16, ""}, + {"(ReadLinkFS).Lstat", Method, 25, ""}, + {"(ReadLinkFS).Open", Method, 25, ""}, + {"(ReadLinkFS).ReadLink", Method, 25, ""}, + {"(StatFS).Open", Method, 16, ""}, + {"(StatFS).Stat", Method, 16, ""}, + {"(SubFS).Open", Method, 16, ""}, + {"(SubFS).Sub", Method, 16, ""}, {"DirEntry", Type, 16, ""}, {"ErrClosed", Var, 16, ""}, {"ErrExist", Var, 16, ""}, @@ -7299,12 +7651,18 @@ var PackageSymbols = map[string][]Symbol{ {"(*TextHandler).WithGroup", Method, 21, ""}, {"(Attr).Equal", Method, 21, ""}, {"(Attr).String", Method, 21, ""}, + {"(Handler).Enabled", Method, 21, ""}, + {"(Handler).Handle", Method, 21, ""}, + {"(Handler).WithAttrs", Method, 21, ""}, + {"(Handler).WithGroup", Method, 21, ""}, {"(Kind).String", Method, 21, ""}, {"(Level).AppendText", Method, 24, ""}, {"(Level).Level", Method, 21, ""}, {"(Level).MarshalJSON", Method, 21, ""}, {"(Level).MarshalText", Method, 21, ""}, {"(Level).String", Method, 21, ""}, + {"(Leveler).Level", Method, 21, ""}, + {"(LogValuer).LogValue", Method, 21, ""}, {"(Record).Attrs", Method, 21, ""}, {"(Record).Clone", Method, 21, ""}, {"(Record).NumAttrs", Method, 21, ""}, @@ -7833,6 +8191,11 @@ var PackageSymbols = map[string][]Symbol{ {"(*Rand).Uint32", Method, 0, ""}, {"(*Rand).Uint64", Method, 8, ""}, {"(*Zipf).Uint64", Method, 0, ""}, + {"(Source).Int63", Method, 0, ""}, + {"(Source).Seed", Method, 0, ""}, + {"(Source64).Int63", Method, 8, ""}, + {"(Source64).Seed", Method, 8, ""}, + {"(Source64).Uint64", Method, 8, ""}, {"ExpFloat64", Func, 0, "func() float64"}, {"Float32", Func, 0, "func() float32"}, {"Float64", Func, 0, "func() float64"}, @@ -7888,6 +8251,7 @@ var PackageSymbols = map[string][]Symbol{ {"(*Rand).Uint64N", Method, 22, ""}, {"(*Rand).UintN", Method, 22, ""}, {"(*Zipf).Uint64", Method, 22, ""}, + {"(Source).Uint64", Method, 22, ""}, {"ChaCha8", Type, 22, ""}, {"ExpFloat64", Func, 22, "func() float64"}, {"Float32", Func, 22, "func() float32"}, @@ -7951,6 +8315,10 @@ var PackageSymbols = map[string][]Symbol{ {"(*Writer).FormDataContentType", Method, 0, ""}, {"(*Writer).SetBoundary", Method, 1, ""}, {"(*Writer).WriteField", Method, 0, ""}, + {"(File).Close", Method, 0, ""}, + {"(File).Read", Method, 0, ""}, + {"(File).ReadAt", Method, 0, ""}, + {"(File).Seek", Method, 0, ""}, {"ErrMessageTooLarge", Var, 9, ""}, {"File", Type, 0, ""}, {"FileContentDisposition", Func, 25, "func(fieldname string, filename string) string"}, @@ -8135,6 +8503,19 @@ var PackageSymbols = map[string][]Symbol{ {"(*UnixListener).SetDeadline", Method, 0, ""}, {"(*UnixListener).SetUnlinkOnClose", Method, 8, ""}, {"(*UnixListener).SyscallConn", Method, 10, ""}, + {"(Addr).Network", Method, 0, ""}, + {"(Addr).String", Method, 0, ""}, + {"(Conn).Close", Method, 0, ""}, + {"(Conn).LocalAddr", Method, 0, ""}, + {"(Conn).Read", Method, 0, ""}, + {"(Conn).RemoteAddr", Method, 0, ""}, + {"(Conn).SetDeadline", Method, 0, ""}, + {"(Conn).SetReadDeadline", Method, 0, ""}, + {"(Conn).SetWriteDeadline", Method, 0, ""}, + {"(Conn).Write", Method, 0, ""}, + {"(Error).Error", Method, 0, ""}, + {"(Error).Temporary", Method, 0, ""}, + {"(Error).Timeout", Method, 0, ""}, {"(Flags).String", Method, 0, ""}, {"(HardwareAddr).String", Method, 0, ""}, {"(IP).AppendText", Method, 24, ""}, @@ -8158,6 +8539,16 @@ var PackageSymbols = map[string][]Symbol{ {"(InvalidAddrError).Error", Method, 0, ""}, {"(InvalidAddrError).Temporary", Method, 0, ""}, {"(InvalidAddrError).Timeout", Method, 0, ""}, + {"(Listener).Accept", Method, 0, ""}, + {"(Listener).Addr", Method, 0, ""}, + {"(Listener).Close", Method, 0, ""}, + {"(PacketConn).Close", Method, 0, ""}, + {"(PacketConn).LocalAddr", Method, 0, ""}, + {"(PacketConn).ReadFrom", Method, 0, ""}, + {"(PacketConn).SetDeadline", Method, 0, ""}, + {"(PacketConn).SetReadDeadline", Method, 0, ""}, + {"(PacketConn).SetWriteDeadline", Method, 0, ""}, + {"(PacketConn).WriteTo", Method, 0, ""}, {"(UnknownNetworkError).Error", Method, 0, ""}, {"(UnknownNetworkError).Temporary", Method, 0, ""}, {"(UnknownNetworkError).Timeout", Method, 0, ""}, @@ -8333,6 +8724,14 @@ var PackageSymbols = map[string][]Symbol{ {"(*Client).Head", Method, 0, ""}, {"(*Client).Post", Method, 0, ""}, {"(*Client).PostForm", Method, 0, ""}, + {"(*ClientConn).Available", Method, 26, ""}, + {"(*ClientConn).Close", Method, 26, ""}, + {"(*ClientConn).Err", Method, 26, ""}, + {"(*ClientConn).InFlight", Method, 26, ""}, + {"(*ClientConn).Release", Method, 26, ""}, + {"(*ClientConn).Reserve", Method, 26, ""}, + {"(*ClientConn).RoundTrip", Method, 26, ""}, + {"(*ClientConn).SetStateHook", Method, 26, ""}, {"(*Cookie).String", Method, 0, ""}, {"(*Cookie).Valid", Method, 18, ""}, {"(*CrossOriginProtection).AddInsecureBypassPattern", Method, 25, ""}, @@ -8392,10 +8791,22 @@ var PackageSymbols = map[string][]Symbol{ {"(*Transport).CancelRequest", Method, 1, ""}, {"(*Transport).Clone", Method, 13, ""}, {"(*Transport).CloseIdleConnections", Method, 0, ""}, + {"(*Transport).NewClientConn", Method, 26, ""}, {"(*Transport).RegisterProtocol", Method, 0, ""}, {"(*Transport).RoundTrip", Method, 0, ""}, + {"(CloseNotifier).CloseNotify", Method, 1, ""}, {"(ConnState).String", Method, 3, ""}, + {"(CookieJar).Cookies", Method, 0, ""}, + {"(CookieJar).SetCookies", Method, 0, ""}, {"(Dir).Open", Method, 0, ""}, + {"(File).Close", Method, 0, ""}, + {"(File).Read", Method, 0, ""}, + {"(File).Readdir", Method, 0, ""}, + {"(File).Seek", Method, 0, ""}, + {"(File).Stat", Method, 0, ""}, + {"(FileSystem).Open", Method, 0, ""}, + {"(Flusher).Flush", Method, 0, ""}, + {"(Handler).ServeHTTP", Method, 0, ""}, {"(HandlerFunc).ServeHTTP", Method, 0, ""}, {"(Header).Add", Method, 0, ""}, {"(Header).Clone", Method, 13, ""}, @@ -8405,10 +8816,16 @@ var PackageSymbols = map[string][]Symbol{ {"(Header).Values", Method, 14, ""}, {"(Header).Write", Method, 0, ""}, {"(Header).WriteSubset", Method, 0, ""}, + {"(Hijacker).Hijack", Method, 0, ""}, {"(Protocols).HTTP1", Method, 24, ""}, {"(Protocols).HTTP2", Method, 24, ""}, {"(Protocols).String", Method, 24, ""}, {"(Protocols).UnencryptedHTTP2", Method, 24, ""}, + {"(Pusher).Push", Method, 8, ""}, + {"(ResponseWriter).Header", Method, 0, ""}, + {"(ResponseWriter).Write", Method, 0, ""}, + {"(ResponseWriter).WriteHeader", Method, 0, ""}, + {"(RoundTripper).RoundTrip", Method, 0, ""}, {"AllowQuerySemicolons", Func, 17, "func(h Handler) Handler"}, {"CanonicalHeaderKey", Func, 0, "func(s string) string"}, {"Client", Type, 0, ""}, @@ -8416,6 +8833,7 @@ var PackageSymbols = map[string][]Symbol{ {"Client.Jar", Field, 0, ""}, {"Client.Timeout", Field, 3, ""}, {"Client.Transport", Field, 0, ""}, + {"ClientConn", Type, 26, ""}, {"CloseNotifier", Type, 1, ""}, {"ConnState", Type, 3, ""}, {"Cookie", Type, 0, ""}, @@ -8726,6 +9144,8 @@ var PackageSymbols = map[string][]Symbol{ "net/http/cookiejar": { {"(*Jar).Cookies", Method, 1, ""}, {"(*Jar).SetCookies", Method, 1, ""}, + {"(PublicSuffixList).PublicSuffix", Method, 1, ""}, + {"(PublicSuffixList).String", Method, 1, ""}, {"Jar", Type, 1, ""}, {"New", Func, 1, "func(o *Options) (*Jar, error)"}, {"Options", Type, 1, ""}, @@ -8819,6 +9239,8 @@ var PackageSymbols = map[string][]Symbol{ {"(*ServerConn).Pending", Method, 0, ""}, {"(*ServerConn).Read", Method, 0, ""}, {"(*ServerConn).Write", Method, 0, ""}, + {"(BufferPool).Get", Method, 6, ""}, + {"(BufferPool).Put", Method, 6, ""}, {"BufferPool", Type, 6, ""}, {"ClientConn", Type, 0, ""}, {"DumpRequest", Func, 0, "func(req *http.Request, body bool) ([]byte, error)"}, @@ -8972,6 +9394,14 @@ var PackageSymbols = map[string][]Symbol{ {"(*Server).ServeConn", Method, 0, ""}, {"(*Server).ServeHTTP", Method, 0, ""}, {"(*Server).ServeRequest", Method, 0, ""}, + {"(ClientCodec).Close", Method, 0, ""}, + {"(ClientCodec).ReadResponseBody", Method, 0, ""}, + {"(ClientCodec).ReadResponseHeader", Method, 0, ""}, + {"(ClientCodec).WriteRequest", Method, 0, ""}, + {"(ServerCodec).Close", Method, 0, ""}, + {"(ServerCodec).ReadRequestBody", Method, 0, ""}, + {"(ServerCodec).ReadRequestHeader", Method, 0, ""}, + {"(ServerCodec).WriteResponse", Method, 0, ""}, {"(ServerError).Error", Method, 0, ""}, {"Accept", Func, 0, "func(lis net.Listener)"}, {"Call", Type, 0, ""}, @@ -9030,6 +9460,8 @@ var PackageSymbols = map[string][]Symbol{ {"(*Client).StartTLS", Method, 0, ""}, {"(*Client).TLSConnectionState", Method, 5, ""}, {"(*Client).Verify", Method, 0, ""}, + {"(Auth).Next", Method, 0, ""}, + {"(Auth).Start", Method, 0, ""}, {"Auth", Type, 0, ""}, {"CRAMMD5Auth", Func, 0, "func(username string, secret string) Auth"}, {"Client", Type, 0, ""}, @@ -9241,10 +9673,18 @@ var PackageSymbols = map[string][]Symbol{ {"(*SyscallError).Error", Method, 0, ""}, {"(*SyscallError).Timeout", Method, 10, ""}, {"(*SyscallError).Unwrap", Method, 13, ""}, + {"(FileInfo).IsDir", Method, 0, ""}, + {"(FileInfo).ModTime", Method, 0, ""}, + {"(FileInfo).Mode", Method, 0, ""}, + {"(FileInfo).Name", Method, 0, ""}, + {"(FileInfo).Size", Method, 0, ""}, + {"(FileInfo).Sys", Method, 0, ""}, {"(FileMode).IsDir", Method, 0, ""}, {"(FileMode).IsRegular", Method, 1, ""}, {"(FileMode).Perm", Method, 0, ""}, {"(FileMode).String", Method, 0, ""}, + {"(Signal).Signal", Method, 0, ""}, + {"(Signal).String", Method, 0, ""}, {"Args", Var, 0, ""}, {"Chdir", Func, 0, "func(dir string) error"}, {"Chmod", Func, 0, "func(name string, mode FileMode) error"}, @@ -9521,6 +9961,45 @@ var PackageSymbols = map[string][]Symbol{ {"(StructField).IsExported", Method, 17, ""}, {"(StructTag).Get", Method, 0, ""}, {"(StructTag).Lookup", Method, 7, ""}, + {"(Type).Align", Method, 0, ""}, + {"(Type).AssignableTo", Method, 0, ""}, + {"(Type).Bits", Method, 0, ""}, + {"(Type).CanSeq", Method, 23, ""}, + {"(Type).CanSeq2", Method, 23, ""}, + {"(Type).ChanDir", Method, 0, ""}, + {"(Type).Comparable", Method, 4, ""}, + {"(Type).ConvertibleTo", Method, 1, ""}, + {"(Type).Elem", Method, 0, ""}, + {"(Type).Field", Method, 0, ""}, + {"(Type).FieldAlign", Method, 0, ""}, + {"(Type).FieldByIndex", Method, 0, ""}, + {"(Type).FieldByName", Method, 0, ""}, + {"(Type).FieldByNameFunc", Method, 0, ""}, + {"(Type).Fields", Method, 26, ""}, + {"(Type).Implements", Method, 0, ""}, + {"(Type).In", Method, 0, ""}, + {"(Type).Ins", Method, 26, ""}, + {"(Type).IsVariadic", Method, 0, ""}, + {"(Type).Key", Method, 0, ""}, + {"(Type).Kind", Method, 0, ""}, + {"(Type).Len", Method, 0, ""}, + {"(Type).Method", Method, 0, ""}, + {"(Type).MethodByName", Method, 0, ""}, + {"(Type).Methods", Method, 26, ""}, + {"(Type).Name", Method, 0, ""}, + {"(Type).NumField", Method, 0, ""}, + {"(Type).NumIn", Method, 0, ""}, + {"(Type).NumMethod", Method, 0, ""}, + {"(Type).NumOut", Method, 0, ""}, + {"(Type).Out", Method, 0, ""}, + {"(Type).Outs", Method, 26, ""}, + {"(Type).OverflowComplex", Method, 23, ""}, + {"(Type).OverflowFloat", Method, 23, ""}, + {"(Type).OverflowInt", Method, 23, ""}, + {"(Type).OverflowUint", Method, 23, ""}, + {"(Type).PkgPath", Method, 0, ""}, + {"(Type).Size", Method, 0, ""}, + {"(Type).String", Method, 0, ""}, {"(Value).Addr", Method, 0, ""}, {"(Value).Bool", Method, 0, ""}, {"(Value).Bytes", Method, 0, ""}, @@ -9547,6 +10026,7 @@ var PackageSymbols = map[string][]Symbol{ {"(Value).FieldByIndexErr", Method, 18, ""}, {"(Value).FieldByName", Method, 0, ""}, {"(Value).FieldByNameFunc", Method, 0, ""}, + {"(Value).Fields", Method, 26, ""}, {"(Value).Float", Method, 0, ""}, {"(Value).Grow", Method, 20, ""}, {"(Value).Index", Method, 0, ""}, @@ -9563,6 +10043,7 @@ var PackageSymbols = map[string][]Symbol{ {"(Value).MapRange", Method, 12, ""}, {"(Value).Method", Method, 0, ""}, {"(Value).MethodByName", Method, 0, ""}, + {"(Value).Methods", Method, 26, ""}, {"(Value).NumField", Method, 0, ""}, {"(Value).NumMethod", Method, 0, ""}, {"(Value).OverflowComplex", Method, 0, ""}, @@ -9678,7 +10159,6 @@ var PackageSymbols = map[string][]Symbol{ {"StructOf", Func, 7, "func(fields []StructField) Type"}, {"StructTag", Type, 0, ""}, {"Swapper", Func, 8, "func(slice any) func(i int, j int)"}, - {"Type", Type, 0, ""}, {"TypeAssert", Func, 25, "func[T any](v Value) (T, bool)"}, {"TypeFor", Func, 22, "func[T any]() Type"}, {"TypeOf", Func, 0, "func(i any) Type"}, @@ -9880,6 +10360,8 @@ var PackageSymbols = map[string][]Symbol{ {"(*TypeAssertionError).Error", Method, 0, ""}, {"(*TypeAssertionError).RuntimeError", Method, 0, ""}, {"(Cleanup).Stop", Method, 24, ""}, + {"(Error).Error", Method, 0, ""}, + {"(Error).RuntimeError", Method, 0, ""}, {"AddCleanup", Func, 24, "func[T, S any](ptr *T, cleanup func(S), arg S) Cleanup"}, {"BlockProfile", Func, 1, "func(p []BlockProfileRecord) (n int, ok bool)"}, {"BlockProfileRecord", Type, 1, ""}, @@ -10154,6 +10636,9 @@ var PackageSymbols = map[string][]Symbol{ {"(IntSlice).Search", Method, 0, ""}, {"(IntSlice).Sort", Method, 0, ""}, {"(IntSlice).Swap", Method, 0, ""}, + {"(Interface).Len", Method, 0, ""}, + {"(Interface).Less", Method, 0, ""}, + {"(Interface).Swap", Method, 0, ""}, {"(StringSlice).Len", Method, 0, ""}, {"(StringSlice).Less", Method, 0, ""}, {"(StringSlice).Search", Method, 0, ""}, @@ -10345,6 +10830,8 @@ var PackageSymbols = map[string][]Symbol{ {"(*WaitGroup).Done", Method, 0, ""}, {"(*WaitGroup).Go", Method, 25, ""}, {"(*WaitGroup).Wait", Method, 0, ""}, + {"(Locker).Lock", Method, 0, ""}, + {"(Locker).Unlock", Method, 0, ""}, {"Cond", Type, 0, ""}, {"Cond.L", Field, 0, ""}, {"Locker", Type, 0, ""}, @@ -10486,10 +10973,14 @@ var PackageSymbols = map[string][]Symbol{ {"(*Timeval).Nano", Method, 0, ""}, {"(*Timeval).Nanoseconds", Method, 0, ""}, {"(*Timeval).Unix", Method, 0, ""}, + {"(Conn).SyscallConn", Method, 9, ""}, {"(Errno).Error", Method, 0, ""}, {"(Errno).Is", Method, 13, ""}, {"(Errno).Temporary", Method, 0, ""}, {"(Errno).Timeout", Method, 0, ""}, + {"(RawConn).Control", Method, 9, ""}, + {"(RawConn).Read", Method, 9, ""}, + {"(RawConn).Write", Method, 9, ""}, {"(Signal).Signal", Method, 0, ""}, {"(Signal).String", Method, 0, ""}, {"(Token).Close", Method, 0, ""}, @@ -14409,7 +14900,7 @@ var PackageSymbols = map[string][]Symbol{ {"RouteMessage.Data", Field, 0, ""}, {"RouteMessage.Header", Field, 0, ""}, {"RouteRIB", Func, 0, ""}, - {"RoutingMessage", Type, 0, ""}, + {"RoutingMessage", Type, 14, ""}, {"RtAttr", Type, 0, ""}, {"RtAttr.Len", Field, 0, ""}, {"RtAttr.Type", Field, 0, ""}, @@ -15895,7 +16386,6 @@ var PackageSymbols = map[string][]Symbol{ {"SockFprog.Filter", Field, 0, ""}, {"SockFprog.Len", Field, 0, ""}, {"SockFprog.Pad_cgo_0", Field, 0, ""}, - {"Sockaddr", Type, 0, ""}, {"SockaddrDatalink", Type, 0, ""}, {"SockaddrDatalink.Alen", Field, 0, ""}, {"SockaddrDatalink.Data", Field, 0, ""}, @@ -16801,6 +17291,29 @@ var PackageSymbols = map[string][]Symbol{ {"(BenchmarkResult).MemString", Method, 1, ""}, {"(BenchmarkResult).NsPerOp", Method, 0, ""}, {"(BenchmarkResult).String", Method, 0, ""}, + {"(TB).ArtifactDir", Method, 26, ""}, + {"(TB).Attr", Method, 25, ""}, + {"(TB).Chdir", Method, 24, ""}, + {"(TB).Cleanup", Method, 14, ""}, + {"(TB).Context", Method, 24, ""}, + {"(TB).Error", Method, 2, ""}, + {"(TB).Errorf", Method, 2, ""}, + {"(TB).Fail", Method, 2, ""}, + {"(TB).FailNow", Method, 2, ""}, + {"(TB).Failed", Method, 2, ""}, + {"(TB).Fatal", Method, 2, ""}, + {"(TB).Fatalf", Method, 2, ""}, + {"(TB).Helper", Method, 9, ""}, + {"(TB).Log", Method, 2, ""}, + {"(TB).Logf", Method, 2, ""}, + {"(TB).Name", Method, 8, ""}, + {"(TB).Output", Method, 25, ""}, + {"(TB).Setenv", Method, 17, ""}, + {"(TB).Skip", Method, 2, ""}, + {"(TB).SkipNow", Method, 2, ""}, + {"(TB).Skipf", Method, 2, ""}, + {"(TB).Skipped", Method, 2, ""}, + {"(TB).TempDir", Method, 15, ""}, {"AllocsPerRun", Func, 1, "func(runs int, f func()) (avg float64)"}, {"B", Type, 0, ""}, {"B.N", Field, 0, ""}, @@ -16851,7 +17364,6 @@ var PackageSymbols = map[string][]Symbol{ {"RunTests", Func, 0, "func(matchString func(pat string, str string) (bool, error), tests []InternalTest) (ok bool)"}, {"Short", Func, 0, "func() bool"}, {"T", Type, 0, ""}, - {"TB", Type, 2, ""}, {"Testing", Func, 21, "func() bool"}, {"Verbose", Func, 1, "func() bool"}, }, @@ -16887,6 +17399,7 @@ var PackageSymbols = map[string][]Symbol{ "testing/quick": { {"(*CheckEqualError).Error", Method, 0, ""}, {"(*CheckError).Error", Method, 0, ""}, + {"(Generator).Generate", Method, 0, ""}, {"(SetupError).Error", Method, 0, ""}, {"Check", Func, 0, "func(f any, config *Config) error"}, {"CheckEqual", Func, 0, "func(f any, g any, config *Config) error"}, @@ -17093,6 +17606,10 @@ var PackageSymbols = map[string][]Symbol{ {"(ListNode).Position", Method, 1, ""}, {"(ListNode).Type", Method, 0, ""}, {"(NilNode).Position", Method, 1, ""}, + {"(Node).Copy", Method, 0, ""}, + {"(Node).Position", Method, 1, ""}, + {"(Node).String", Method, 0, ""}, + {"(Node).Type", Method, 0, ""}, {"(NodeType).Type", Method, 0, ""}, {"(NumberNode).Position", Method, 1, ""}, {"(NumberNode).Type", Method, 0, ""}, diff --git a/vendor/golang.org/x/tools/internal/stdlib/stdlib.go b/vendor/golang.org/x/tools/internal/stdlib/stdlib.go index e223e0f340..59a5de36a2 100644 --- a/vendor/golang.org/x/tools/internal/stdlib/stdlib.go +++ b/vendor/golang.org/x/tools/internal/stdlib/stdlib.go @@ -39,7 +39,7 @@ const ( Var // "EOF" Const // "Pi" Field // "Point.X" - Method // "(*Buffer).Grow" + Method // "(*Buffer).Grow" or "(Reader).Read" ) func (kind Kind) String() string { diff --git a/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go b/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go index 3db2a135b9..7ebe9768bc 100644 --- a/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go +++ b/vendor/golang.org/x/tools/internal/typesinternal/classify_call.go @@ -8,7 +8,7 @@ import ( "fmt" "go/ast" "go/types" - _ "unsafe" + _ "unsafe" // for go:linkname hack ) // CallKind describes the function position of an [*ast.CallExpr]. diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go index fef74a7856..51001666ef 100644 --- a/vendor/golang.org/x/tools/internal/typesinternal/types.go +++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go @@ -23,7 +23,6 @@ import ( "go/token" "go/types" "reflect" - "unsafe" "golang.org/x/tools/go/ast/inspector" "golang.org/x/tools/internal/aliases" @@ -40,8 +39,7 @@ func SetUsesCgo(conf *types.Config) bool { } } - addr := unsafe.Pointer(f.UnsafeAddr()) - *(*bool)(addr) = true + *(*bool)(f.Addr().UnsafePointer()) = true return true } diff --git a/vendor/golang.org/x/tools/internal/versions/features.go b/vendor/golang.org/x/tools/internal/versions/features.go index a5f4e3252c..cdd36c388a 100644 --- a/vendor/golang.org/x/tools/internal/versions/features.go +++ b/vendor/golang.org/x/tools/internal/versions/features.go @@ -9,6 +9,7 @@ package versions // named constants, to avoid misspelling const ( + Go1_17 = "go1.17" Go1_18 = "go1.18" Go1_19 = "go1.19" Go1_20 = "go1.20" diff --git a/vendor/modules.txt b/vendor/modules.txt index 5a0e9b3e9b..26f21637f3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1529,7 +1529,7 @@ go.yaml.in/yaml/v2 # go.yaml.in/yaml/v3 v3.0.4 ## explicit; go 1.16 go.yaml.in/yaml/v3 -# golang.org/x/crypto v0.45.0 +# golang.org/x/crypto v0.46.0 ## explicit; go 1.24.0 golang.org/x/crypto/blake2b golang.org/x/crypto/blowfish @@ -1564,7 +1564,7 @@ golang.org/x/crypto/ssh/terminal # golang.org/x/exp v0.0.0-20250911091902-df9299821621 ## explicit; go 1.24.0 golang.org/x/exp/slices -# golang.org/x/mod v0.31.0 +# golang.org/x/mod v0.32.0 ## explicit; go 1.24.0 golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile @@ -1572,7 +1572,7 @@ golang.org/x/mod/module golang.org/x/mod/semver golang.org/x/mod/sumdb/dirhash golang.org/x/mod/sumdb/note -# golang.org/x/net v0.47.0 +# golang.org/x/net v0.48.0 ## explicit; go 1.24.0 golang.org/x/net/context/ctxhttp golang.org/x/net/http/httpguts @@ -1601,17 +1601,17 @@ golang.org/x/oauth2/jwt ## explicit; go 1.24.0 golang.org/x/sync/errgroup golang.org/x/sync/semaphore -# golang.org/x/sys v0.38.0 +# golang.org/x/sys v0.39.0 ## explicit; go 1.24.0 golang.org/x/sys/cpu golang.org/x/sys/plan9 golang.org/x/sys/unix golang.org/x/sys/windows golang.org/x/sys/windows/registry -# golang.org/x/term v0.37.0 +# golang.org/x/term v0.38.0 ## explicit; go 1.24.0 golang.org/x/term -# golang.org/x/text v0.31.0 +# golang.org/x/text v0.32.0 ## explicit; go 1.24.0 golang.org/x/text/cases golang.org/x/text/encoding @@ -1633,7 +1633,7 @@ golang.org/x/text/width # golang.org/x/time v0.13.0 ## explicit; go 1.24.0 golang.org/x/time/rate -# golang.org/x/tools v0.39.0 +# golang.org/x/tools v0.40.0 ## explicit; go 1.24.0 golang.org/x/tools/go/ast/astutil golang.org/x/tools/go/ast/edge From 13e12504b82dbde650afc400fa3394c5d9a80e85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 20:34:02 +0000 Subject: [PATCH 04/13] chore(deps): bump chainguard-dev/actions from 1.5.10 to 1.5.11 Bumps [chainguard-dev/actions](https://github.com/chainguard-dev/actions) from 1.5.10 to 1.5.11. - [Release notes](https://github.com/chainguard-dev/actions/releases) - [Commits](https://github.com/chainguard-dev/actions/compare/3e8a2a226fad9e1ecbf2d359b8a7697554a4ac6d...7d647f470c4d3692286221bd17ca78206976a61c) --- updated-dependencies: - dependency-name: chainguard-dev/actions dependency-version: 1.5.11 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/e2e-matrix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-matrix.yml b/.github/workflows/e2e-matrix.yml index e5718d6b3b..45e1bbcee7 100644 --- a/.github/workflows/e2e-matrix.yml +++ b/.github/workflows/e2e-matrix.yml @@ -68,7 +68,7 @@ jobs: name: ${{ matrix.k8s-version }}-${{ matrix.feature-flags }} path: ${{ env.ARTIFACTS }} - - uses: chainguard-dev/actions/kind-diag@3e8a2a226fad9e1ecbf2d359b8a7697554a4ac6d # v1.5.10 + - uses: chainguard-dev/actions/kind-diag@7d647f470c4d3692286221bd17ca78206976a61c # v1.5.11 if: ${{ failure() }} with: artifact-name: ${{ matrix.k8s-version }}-${{ matrix.feature-flags }}-logs From 50846ec8af273754f737a321bcace8907f4c7d8f Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Tue, 13 Jan 2026 10:14:45 +0100 Subject: [PATCH 05/13] Fix CI SIGPIPE error by disabling pipefail for git diff pipes The categorize changes job was failing with exit code 141 (SIGPIPE). This occurred because with pipefail enabled, when git diff pipes to commands like head or grep that exit early, git diff receives SIGPIPE and the entire pipeline fails with exit code 141. The issue manifests in two places: 1. `git diff | head -50` - head exits after 50 lines 2. `git diff | grep > /dev/null` - grep exits after finding matches With pipefail, these SIGPIPE failures cause the whole script to fail. Solution: Temporarily disable pipefail for the detection logic since we only care about the exit status of head/grep, not the pipe status. This completes the fix for the SIGPIPE issues identified in PRs #3150 and #3152, which addressed variable size limits and grep -q issues. Signed-off-by: Vincent Demeester --- .github/workflows/ci.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3621e4bd32..9f997c1787 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -41,6 +41,10 @@ jobs: # Store git diff command for reuse GIT_DIFF_CMD="git diff --name-only ${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }}" + # Disable pipefail to avoid SIGPIPE (exit 141) when commands like head/grep exit early + # SIGPIPE occurs when git diff tries to write but the reading end of the pipe has closed + set +o pipefail + # Show changed files for debugging (limit to first 50 for readability) echo "Changed files (first 50):" $GIT_DIFF_CMD | head -50 @@ -50,12 +54,16 @@ jobs: # If no files are changed at all, skip detection # Use git diff output directly to avoid bash variable size limits with large PRs if [[ $FILE_COUNT -gt 0 ]]; then + # We only care about grep's exit status (did it find matches?), not the pipe status NON_DOCS=$($GIT_DIFF_CMD | grep -Ev '\.md$' > /dev/null && echo 'true' || echo 'false') YAML=$($GIT_DIFF_CMD | grep -E '\.ya?ml$' > /dev/null && echo 'true' || echo 'false') echo "non-docs=${NON_DOCS}" | tee -a $GITHUB_OUTPUT echo "yaml=${YAML}" | tee -a $GITHUB_OUTPUT fi + # Re-enable pipefail for subsequent commands + set -o pipefail + build: name: build needs: [changes] From 938a2ab57b44bf4f2db86bb9015a215fec032fb8 Mon Sep 17 00:00:00 2001 From: Jawed khelil Date: Tue, 13 Jan 2026 12:23:12 +0100 Subject: [PATCH 06/13] Fix golangci-lint action step for large diff --- .github/workflows/ci.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9f997c1787..776128e54e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -83,6 +83,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + fetch-depth: 0 - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: go-version-file: "go.mod" @@ -98,9 +100,8 @@ jobs: if: ${{ needs.changes.outputs.non-docs == 'true' }} uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0 with: - version: v2.1.0 - only-new-issues: true - args: --timeout=10m + version: v2.7.2 + args: --new-from-merge-base=origin/${{ github.base_ref }} --timeout=10m - name: yamllint if: ${{ needs.changes.outputs.yaml == 'true' }} run: | From 5989be61966b656e102d15afb5dedea6f0f99a4c Mon Sep 17 00:00:00 2001 From: Jawed khelil Date: Thu, 8 Jan 2026 14:15:48 +0100 Subject: [PATCH 07/13] bump fulcio and cosign to fix cve CVE-2025-66506 --- go.mod | 224 +- go.sum | 574 +- vendor/cel.dev/expr/BUILD.bazel | 1 - vendor/cel.dev/expr/MODULE.bazel | 22 +- vendor/cel.dev/expr/checked.pb.go | 749 +- vendor/cel.dev/expr/eval.pb.go | 77 +- vendor/cel.dev/expr/explain.pb.go | 113 +- vendor/cel.dev/expr/syntax.pb.go | 879 +- vendor/cel.dev/expr/value.pb.go | 348 +- vendor/cloud.google.com/go/auth/CHANGES.md | 7 + vendor/cloud.google.com/go/auth/auth.go | 2 + .../go/auth/credentials/compute.go | 6 +- .../go/auth/credentials/detect.go | 25 +- .../go/auth/credentials/filetypes.go | 125 +- .../internal/impersonate/impersonate.go | 38 +- .../go/auth/httptransport/httptransport.go | 14 +- .../go/auth/httptransport/transport.go | 3 +- .../go/auth/internal/internal.go | 59 + .../go/auth/internal/retry/retry.go | 117 + .../internal/transport/headers/headers.go | 61 + .../external_accounts_config_providers.go | 100 + .../internal/trustboundary/trust_boundary.go | 392 + .../go/auth/internal/version.go | 20 + .../go/compute/metadata/CHANGES.md | 35 + .../go/compute/metadata/metadata.go | 65 +- .../go/compute/metadata/retry.go | 3 + .../ociregistry/internal/ocirequest/create.go | 8 +- .../internal/ocirequest/request.go | 97 +- vendor/cuelabs.dev/go/oci/ociregistry/iter.go | 15 +- .../go/oci/ociregistry/ociauth/challenge.go | 2 +- .../go/oci/ociregistry/ociclient/client.go | 7 +- .../go/oci/ociregistry/ociclient/lister.go | 148 +- vendor/cuelang.org/go/cue/ast/ast.go | 156 +- .../cuelang.org/go/cue/ast/astutil/apply.go | 91 +- .../cuelang.org/go/cue/ast/astutil/resolve.go | 247 +- .../go/cue/ast/astutil/sanitize.go | 54 +- vendor/cuelang.org/go/cue/ast/astutil/util.go | 43 +- vendor/cuelang.org/go/cue/ast/astutil/walk.go | 54 - vendor/cuelang.org/go/cue/ast/ident.go | 29 +- vendor/cuelang.org/go/cue/ast/importpath.go | 156 + vendor/cuelang.org/go/cue/ast/walk.go | 14 + vendor/cuelang.org/go/cue/build.go | 65 - vendor/cuelang.org/go/cue/build/context.go | 11 +- vendor/cuelang.org/go/cue/build/file.go | 1 + vendor/cuelang.org/go/cue/build/import.go | 9 +- vendor/cuelang.org/go/cue/build/instance.go | 17 +- vendor/cuelang.org/go/cue/context.go | 24 +- .../go/cue/cuecontext/cuecontext.go | 26 +- vendor/cuelang.org/go/cue/decode.go | 75 +- vendor/cuelang.org/go/cue/errors/errors.go | 194 +- vendor/cuelang.org/go/cue/format/node.go | 83 +- vendor/cuelang.org/go/cue/format/simplify.go | 5 +- vendor/cuelang.org/go/cue/instance.go | 4 +- .../go/cue/interpreter/embed/embed.go | 414 + vendor/cuelang.org/go/cue/literal/quote.go | 14 +- vendor/cuelang.org/go/cue/load/config.go | 63 +- vendor/cuelang.org/go/cue/load/errors.go | 32 +- vendor/cuelang.org/go/cue/load/fs.go | 45 +- vendor/cuelang.org/go/cue/load/import.go | 112 +- vendor/cuelang.org/go/cue/load/instances.go | 164 +- vendor/cuelang.org/go/cue/load/loader.go | 36 +- .../cuelang.org/go/cue/load/loader_common.go | 17 +- .../cuelang.org/go/cue/load/modfilecache.go | 57 + vendor/cuelang.org/go/cue/load/search.go | 106 +- vendor/cuelang.org/go/cue/load/tags.go | 27 +- vendor/cuelang.org/go/cue/marshal.go | 18 +- vendor/cuelang.org/go/cue/op.go | 2 + vendor/cuelang.org/go/cue/parser/interface.go | 196 +- vendor/cuelang.org/go/cue/parser/parser.go | 346 +- vendor/cuelang.org/go/cue/path.go | 60 +- vendor/cuelang.org/go/cue/query.go | 14 +- vendor/cuelang.org/go/cue/scanner/scanner.go | 52 +- vendor/cuelang.org/go/cue/stats/stats.go | 90 +- vendor/cuelang.org/go/cue/token/position.go | 220 +- .../cuelang.org/go/cue/token/relpos_string.go | 5 +- vendor/cuelang.org/go/cue/token/token.go | 3 +- .../cuelang.org/go/cue/token/token_string.go | 32 +- vendor/cuelang.org/go/cue/types.go | 457 +- vendor/cuelang.org/go/encoding/json/json.go | 6 +- .../cuelang.org/go/encoding/json/pointer.go | 98 + .../go/encoding/jsonschema/constraints.go | 76 +- .../encoding/jsonschema/constraints_array.go | 9 +- .../jsonschema/constraints_combinator.go | 12 +- .../encoding/jsonschema/constraints_format.go | 64 +- .../jsonschema/constraints_generic.go | 18 + .../encoding/jsonschema/constraints_meta.go | 9 +- .../encoding/jsonschema/constraints_object.go | 341 +- .../go/encoding/jsonschema/crd.cue | 61 + .../cuelang.org/go/encoding/jsonschema/crd.go | 155 + .../go/encoding/jsonschema/cue_types_gen.go | 43 + .../go/encoding/jsonschema/decode.go | 315 +- .../jsonschema/external_teststats.txt | 33 +- .../go/encoding/jsonschema/generate.go | 1253 ++ .../go/encoding/jsonschema/generate_items.go | 916 + .../go/encoding/jsonschema/jsonschema.go | 32 +- .../go/encoding/jsonschema/pointer.go | 45 - .../cuelang.org/go/encoding/jsonschema/ref.go | 51 +- .../encoding/jsonschema/resolveref_v1.22.go | 46 - .../encoding/jsonschema/resolveref_v1.23.go | 11 - .../go/encoding/jsonschema/structbuilder.go | 5 +- .../go/encoding/jsonschema/util.go | 62 +- .../go/encoding/jsonschema/version.go | 21 +- .../go/encoding/jsonschema/version_string.go | 11 +- .../cuelang.org/go/encoding/openapi/build.go | 49 +- .../cuelang.org/go/encoding/openapi/cycle.go | 20 +- .../cuelang.org/go/encoding/openapi/decode.go | 6 +- .../go/encoding/openapi/openapi.go | 13 +- .../cuelang.org/go/encoding/protobuf/parse.go | 21 +- .../go/encoding/protobuf/protobuf.go | 8 +- .../go/encoding/protobuf/textproto/decoder.go | 9 +- .../go/encoding/protobuf/textproto/encoder.go | 2 +- .../cuelang.org/go/encoding/protobuf/types.go | 32 +- .../cuelang.org/go/encoding/protobuf/util.go | 7 +- vendor/cuelang.org/go/encoding/toml/decode.go | 49 +- .../go/encoding/xml/koala/decode.go | 327 + vendor/cuelang.org/go/encoding/yaml/yaml.go | 46 +- .../go/internal/anyunique/unique.go | 122 + .../go/internal/astinternal/debug.go | 31 +- .../cuelang.org/go/internal/core/adt/adt.go | 14 +- .../go/internal/core/adt/arctype_string.go | 28 + .../cuelang.org/go/internal/core/adt/binop.go | 123 +- .../cuelang.org/go/internal/core/adt/call.go | 112 + .../go/internal/core/adt/closed.go | 453 +- .../go/internal/core/adt/closed2.go | 69 - .../go/internal/core/adt/composite.go | 595 +- .../go/internal/core/adt/comprehension.go | 208 +- .../go/internal/core/adt/conjunct.go | 530 +- .../go/internal/core/adt/constraints.go | 33 +- .../go/internal/core/adt/context.go | 625 +- .../cuelang.org/go/internal/core/adt/cycle.go | 456 +- .../cuelang.org/go/internal/core/adt/debug.go | 357 +- .../go/internal/core/adt/default.go | 10 +- .../go/internal/core/adt/defidtype_string.go | 27 + .../cuelang.org/go/internal/core/adt/dep.go | 371 - .../go/internal/core/adt/depkind_string.go | 35 - .../cuelang.org/go/internal/core/adt/dev.go | 79 - .../go/internal/core/adt/disjunct.go | 426 +- .../go/internal/core/adt/disjunct2.go | 493 +- .../go/internal/core/adt/equality.go | 47 +- .../go/internal/core/adt/errorcode_string.go | 16 +- .../go/internal/core/adt/errors.go | 136 +- .../cuelang.org/go/internal/core/adt/eval.go | 2117 +-- .../cuelang.org/go/internal/core/adt/expr.go | 622 +- .../go/internal/core/adt/feature.go | 14 +- .../go/internal/core/adt/fields.go | 733 +- .../cuelang.org/go/internal/core/adt/flags.go | 41 + .../cuelang.org/go/internal/core/adt/kind.go | 66 +- .../cuelang.org/go/internal/core/adt/log.go | 130 +- .../cuelang.org/go/internal/core/adt/mem.go | 232 + vendor/cuelang.org/go/internal/core/adt/op.go | 4 +- .../go/internal/core/adt/op_string.go | 10 +- .../go/internal/core/adt/optional.go | 154 - .../go/internal/core/adt/overlay.go | 581 +- .../go/internal/core/adt/runmode_string.go | 8 +- .../cuelang.org/go/internal/core/adt/sched.go | 46 +- .../cuelang.org/go/internal/core/adt/share.go | 43 +- .../go/internal/core/adt/simplify.go | 62 +- .../go/internal/core/adt/states.go | 48 +- .../cuelang.org/go/internal/core/adt/tasks.go | 77 +- .../go/internal/core/adt/typocheck.go | 1065 ++ .../cuelang.org/go/internal/core/adt/unify.go | 460 +- .../go/internal/core/adt/validate.go | 202 + .../internal/core/adt/vertexstatus_string.go | 12 +- .../go/internal/core/compile/builtin.go | 211 +- .../go/internal/core/compile/compile.go | 253 +- .../go/internal/core/compile/label.go | 4 +- .../go/internal/core/compile/predeclared.go | 13 + .../go/internal/core/compile/validator.go | 45 +- .../go/internal/core/convert/go.go | 46 +- .../go/internal/core/debug/compact.go | 37 +- .../go/internal/core/debug/debug.go | 138 +- .../cuelang.org/go/internal/core/dep/dep.go | 50 +- .../cuelang.org/go/internal/core/dep/mixed.go | 12 +- .../go/internal/core/export/adt.go | 15 +- .../go/internal/core/export/export.go | 64 +- .../go/internal/core/export/expr.go | 30 +- .../go/internal/core/export/extract.go | 29 +- .../go/internal/core/export/label.go | 14 +- .../go/internal/core/export/toposort.go | 52 +- .../go/internal/core/export/value.go | 27 +- .../go/internal/core/format/printer.go | 26 + .../go/internal/core/layer/layer.go | 30 + .../go/internal/core/runtime/build.go | 31 +- .../go/internal/core/runtime/extern.go | 5 +- .../go/internal/core/runtime/imports.go | 8 +- .../go/internal/core/runtime/resolve.go | 11 +- .../go/internal/core/runtime/runtime.go | 42 +- .../go/internal/core/subsume/subsume.go | 5 +- .../go/internal/core/subsume/value.go | 2 +- .../go/internal/core/subsume/vertex.go | 221 +- .../go/internal/core/toposort/cycles.go | 153 - .../go/internal/core/toposort/graph.go | 203 +- .../go/internal/core/toposort/vertex.go | 131 +- .../go/internal/core/validate/validate.go | 131 - .../cuelang.org/go/internal/core/walk/walk.go | 3 + .../go/internal/cueconfig/config.go | 23 +- .../go/internal/cuedebug/cuedebug.go | 33 +- .../go/internal/cueexperiment/exp.go | 79 +- .../go/internal/cueexperiment/file.go | 318 + .../go/internal/cueexperiment/parse.go | 143 + .../go/internal/cueversion/version.go | 32 +- .../go/internal/encoding/encoder.go | 59 +- .../go/internal/encoding/encoding.go | 20 +- .../go/internal/encoding/yaml/decode.go | 78 +- .../go/internal/encoding/yaml/encode.go | 6 +- .../go/internal/encoding/yaml/validate.go | 103 + .../cuelang.org/go/internal/envflag/flag.go | 96 +- .../go/internal/filetypes/fileinfo.dat | Bin 0 -> 153648 bytes .../go/internal/filetypes/filetypes.go | 277 +- .../go/internal/filetypes/fromfile.dat | Bin 0 -> 11502 bytes .../filetypes/internal/genstruct/gen.go | 244 + .../filetypes/internal/genstruct/struct.go | 385 + .../internal/filetypes/internal/internal.go | 107 + .../go/internal/filetypes/internal/opt/opt.go | 39 + .../go/internal/filetypes/tagtype_string.go | 27 + .../go/internal/filetypes/tofile.go | 33 + .../go/internal/filetypes/tofile_bootstrap.go | 27 + .../go/internal/filetypes/types.cue | 94 +- .../go/internal/filetypes/types.go | 40 +- .../go/internal/filetypes/types_gen.go | 446 + .../go/internal/filetypes/types_gen.go.tmpl | 141 + .../cuelang.org/go/internal/filetypes/util.go | 31 +- .../tools/robustio/robustio_flaky.go | 92 - .../tools/robustio/robustio_other.go | 28 - vendor/cuelang.org/go/internal/internal.go | 195 +- .../cuelang.org/go/internal/iterutil/iter.go | 25 + .../go/internal/mod/modfiledata/modfile.go | 249 + .../go/internal/mod/modimports/modimports.go | 79 +- .../go/internal/mod/modload/query.go | 9 +- .../go/internal/mod/modload/tidy.go | 33 +- .../go/internal/mod/modload/update.go | 220 +- .../go/internal/mod/modpkgload/import.go | 256 +- .../go/internal/mod/modpkgload/pkgload.go | 50 +- .../mod/modrequirements/requirements.go | 3 +- .../go/internal/mod/modresolve/resolve.go | 4 +- vendor/cuelang.org/go/internal/mod/mvs/mvs.go | 5 +- .../go/internal/mod/semver/semver.go | 29 +- vendor/cuelang.org/go/internal/par/work.go | 45 +- vendor/cuelang.org/go/internal/pkg/builtin.go | 42 +- vendor/cuelang.org/go/internal/pkg/context.go | 20 +- vendor/cuelang.org/go/internal/pkg/types.go | 14 +- .../cuelang.org/go/internal/robustio/doc.go | 4 + .../tools => }/robustio/gopls_windows.go | 0 .../tools => }/robustio/robustio.go | 0 .../tools => }/robustio/robustio_darwin.go | 0 .../go/internal}/robustio/robustio_flaky.go | 0 .../go/internal/robustio/robustio_js.go | 24 + .../go/internal}/robustio/robustio_other.go | 0 .../tools => }/robustio/robustio_plan9.go | 3 - .../robustio_unix.go} | 5 +- .../tools => }/robustio/robustio_windows.go | 0 .../cuelang.org/go/internal/source/source.go | 12 +- vendor/cuelang.org/go/internal/task/task.go | 79 +- vendor/cuelang.org/go/internal/tools.mod | 17 + vendor/cuelang.org/go/internal/tools.sum | 13 + vendor/cuelang.org/go/internal/value/value.go | 45 +- vendor/cuelang.org/go/mod/modcache/cache.go | 16 +- vendor/cuelang.org/go/mod/modcache/fetch.go | 52 +- .../cuelang.org/go/mod/modconfig/modconfig.go | 37 +- vendor/cuelang.org/go/mod/modfile/modfile.go | 242 +- .../cuelang.org/go/mod/modregistry/client.go | 191 +- vendor/cuelang.org/go/mod/module/dirfs.go | 8 +- vendor/cuelang.org/go/mod/module/module.go | 52 +- vendor/cuelang.org/go/mod/module/path.go | 175 +- vendor/cuelang.org/go/mod/module/versions.go | 3 - vendor/cuelang.org/go/mod/modzip/zip.go | 2 +- .../go/pkg/encoding/json/manual.go | 26 +- .../cuelang.org/go/pkg/encoding/json/pkg.go | 2 +- .../go/pkg/encoding/yaml/manual.go | 78 +- .../cuelang.org/go/pkg/encoding/yaml/pkg.go | 4 +- vendor/cuelang.org/go/pkg/list/list.go | 34 +- vendor/cuelang.org/go/pkg/list/pkg.go | 2 +- vendor/cuelang.org/go/pkg/list/sort.go | 47 +- vendor/cuelang.org/go/pkg/net/ip.go | 64 +- vendor/cuelang.org/go/pkg/net/pkg.go | 26 + vendor/cuelang.org/go/pkg/net/url.go | 2 +- vendor/cuelang.org/go/pkg/regexp/manual.go | 8 +- vendor/cuelang.org/go/pkg/regexp/regexp.go | 1 - vendor/cuelang.org/go/pkg/strconv/strconv.go | 123 +- vendor/cuelang.org/go/pkg/strings/manual.go | 5 +- vendor/cuelang.org/go/pkg/strings/strings.go | 4 +- vendor/cuelang.org/go/pkg/tool/cli/cli.cue | 6 +- vendor/cuelang.org/go/pkg/tool/cli/pkg.go | 12 +- vendor/cuelang.org/go/pkg/tool/exec/exec.cue | 3 +- vendor/cuelang.org/go/pkg/tool/exec/pkg.go | 6 +- vendor/cuelang.org/go/pkg/tool/file/file.cue | 21 +- vendor/cuelang.org/go/pkg/tool/file/pkg.go | 42 +- vendor/cuelang.org/go/pkg/tool/http/http.cue | 13 +- vendor/cuelang.org/go/pkg/tool/http/http.go | 23 + vendor/cuelang.org/go/pkg/tool/http/pkg.go | 15 +- vendor/cuelang.org/go/pkg/tool/os/os.cue | 12 +- vendor/cuelang.org/go/pkg/tool/os/pkg.go | 24 +- vendor/cuelang.org/go/pkg/tool/pkg.go | 10 +- vendor/cuelang.org/go/pkg/tool/tool.cue | 10 +- vendor/cuelang.org/go/pkg/uuid/pkg.go | 12 - vendor/cuelang.org/go/pkg/uuid/uuid.go | 25 +- vendor/cuelang.org/go/tools/flow/cycle.go | 107 + vendor/cuelang.org/go/tools/flow/flow.go | 494 + vendor/cuelang.org/go/tools/flow/run.go | 251 + .../cuelang.org/go/tools/flow/state_string.go | 27 + vendor/cuelang.org/go/tools/flow/tasks.go | 285 + .../go-ansiterm}/LICENSE | 2 +- vendor/github.com/Azure/go-ansiterm/README.md | 12 + .../github.com/Azure/go-ansiterm/SECURITY.md | 41 + .../github.com/Azure/go-ansiterm/constants.go | 188 + .../github.com/Azure/go-ansiterm/context.go | 7 + .../Azure/go-ansiterm/csi_entry_state.go | 49 + .../Azure/go-ansiterm/csi_param_state.go | 38 + .../go-ansiterm/escape_intermediate_state.go | 36 + .../Azure/go-ansiterm/escape_state.go | 47 + .../Azure/go-ansiterm/event_handler.go | 90 + .../Azure/go-ansiterm/ground_state.go | 24 + .../Azure/go-ansiterm/osc_string_state.go | 23 + vendor/github.com/Azure/go-ansiterm/parser.go | 151 + .../go-ansiterm/parser_action_helpers.go | 99 + .../Azure/go-ansiterm/parser_actions.go | 119 + vendor/github.com/Azure/go-ansiterm/states.go | 71 + .../github.com/Azure/go-ansiterm/utilities.go | 21 + .../Azure/go-ansiterm/winterm/ansi.go | 196 + .../Azure/go-ansiterm/winterm/api.go | 327 + .../go-ansiterm/winterm/attr_translation.go | 100 + .../go-ansiterm/winterm/cursor_helpers.go | 101 + .../go-ansiterm/winterm/erase_helpers.go | 84 + .../go-ansiterm/winterm/scroll_helper.go | 118 + .../Azure/go-ansiterm/winterm/utilities.go | 9 + .../go-ansiterm/winterm/win_event_handler.go | 743 + .../aws/aws-sdk-go-v2/aws/config.go | 12 + .../aws/aws-sdk-go-v2/aws/credentials.go | 4 + .../aws-sdk-go-v2/aws/go_module_metadata.go | 2 +- .../aws/middleware/user_agent.go | 7 + .../aws/aws-sdk-go-v2/aws/retry/middleware.go | 2 +- .../aws/transport/http/timeout_read_closer.go | 5 + .../aws/aws-sdk-go-v2/config/CHANGELOG.md | 131 + .../config/auth_scheme_preference.go | 19 + .../aws/aws-sdk-go-v2/config/config.go | 7 + .../aws/aws-sdk-go-v2/config/env_config.go | 14 + .../config/go_module_metadata.go | 2 +- .../aws/aws-sdk-go-v2/config/load_options.go | 146 + .../aws/aws-sdk-go-v2/config/provider.go | 31 + .../aws/aws-sdk-go-v2/config/resolve.go | 31 + .../config/resolve_credentials.go | 25 +- .../aws/aws-sdk-go-v2/config/shared_config.go | 25 + .../aws-sdk-go-v2/credentials/CHANGELOG.md | 130 + .../credentials/go_module_metadata.go | 2 +- .../credentials/logincreds/dpop.go | 150 + .../credentials/logincreds/file.go | 14 + .../credentials/logincreds/provider.go | 172 + .../credentials/logincreds/token.go | 110 + .../feature/ec2/imds/CHANGELOG.md | 77 + .../feature/ec2/imds/api_client.go | 8 +- .../feature/ec2/imds/go_module_metadata.go | 2 +- .../internal/configsources/CHANGELOG.md | 73 + .../configsources/go_module_metadata.go | 2 +- .../endpoints/awsrulesfn/partitions.go | 157 +- .../endpoints/awsrulesfn/partitions.json | 83 +- .../internal/endpoints/v2/CHANGELOG.md | 73 + .../endpoints/v2/go_module_metadata.go | 2 +- .../aws-sdk-go-v2/internal/ini/CHANGELOG.md | 4 + .../internal/ini/go_module_metadata.go | 2 +- .../aws-sdk-go-v2/service/ecr/CHANGELOG.md | 142 + .../aws-sdk-go-v2/service/ecr/api_client.go | 127 +- .../ecr/api_op_BatchCheckLayerAvailability.go | 33 + .../service/ecr/api_op_BatchDeleteImage.go | 33 + .../service/ecr/api_op_BatchGetImage.go | 33 + ...BatchGetRepositoryScanningConfiguration.go | 33 + .../service/ecr/api_op_CompleteLayerUpload.go | 33 + .../ecr/api_op_CreatePullThroughCacheRule.go | 68 +- .../service/ecr/api_op_CreateRepository.go | 37 + ...api_op_CreateRepositoryCreationTemplate.go | 37 + .../ecr/api_op_DeleteLifecyclePolicy.go | 33 + .../ecr/api_op_DeletePullThroughCacheRule.go | 39 + .../ecr/api_op_DeleteRegistryPolicy.go | 33 + .../service/ecr/api_op_DeleteRepository.go | 33 + ...api_op_DeleteRepositoryCreationTemplate.go | 33 + .../ecr/api_op_DeleteRepositoryPolicy.go | 33 + .../api_op_DescribeImageReplicationStatus.go | 33 + .../ecr/api_op_DescribeImageScanFindings.go | 33 + .../service/ecr/api_op_DescribeImages.go | 45 +- .../api_op_DescribePullThroughCacheRules.go | 33 + .../service/ecr/api_op_DescribeRegistry.go | 33 + .../ecr/api_op_DescribeRepositories.go | 33 + ..._op_DescribeRepositoryCreationTemplates.go | 33 + .../service/ecr/api_op_GetAccountSetting.go | 33 + .../ecr/api_op_GetAuthorizationToken.go | 36 + .../ecr/api_op_GetDownloadUrlForLayer.go | 33 + .../service/ecr/api_op_GetLifecyclePolicy.go | 33 + .../ecr/api_op_GetLifecyclePolicyPreview.go | 41 +- .../service/ecr/api_op_GetRegistryPolicy.go | 33 + ...api_op_GetRegistryScanningConfiguration.go | 33 + .../service/ecr/api_op_GetRepositoryPolicy.go | 33 + .../service/ecr/api_op_InitiateLayerUpload.go | 33 + .../service/ecr/api_op_ListImages.go | 33 + .../service/ecr/api_op_ListTagsForResource.go | 33 + .../service/ecr/api_op_PutAccountSetting.go | 33 + .../service/ecr/api_op_PutImage.go | 33 + .../api_op_PutImageScanningConfiguration.go | 33 + .../ecr/api_op_PutImageTagMutability.go | 42 + .../service/ecr/api_op_PutLifecyclePolicy.go | 33 + .../service/ecr/api_op_PutRegistryPolicy.go | 33 + ...api_op_PutRegistryScanningConfiguration.go | 33 + .../ecr/api_op_PutReplicationConfiguration.go | 33 + .../service/ecr/api_op_SetRepositoryPolicy.go | 33 + .../service/ecr/api_op_StartImageScan.go | 46 +- .../ecr/api_op_StartLifecyclePolicyPreview.go | 33 + .../service/ecr/api_op_TagResource.go | 33 + .../service/ecr/api_op_UntagResource.go | 33 + .../ecr/api_op_UpdatePullThroughCacheRule.go | 54 +- ...api_op_UpdateRepositoryCreationTemplate.go | 37 + .../service/ecr/api_op_UploadLayerPart.go | 33 + .../api_op_ValidatePullThroughCacheRule.go | 39 + .../aws/aws-sdk-go-v2/service/ecr/auth.go | 28 +- .../service/ecr/deserializers.go | 226 +- .../aws-sdk-go-v2/service/ecr/endpoints.go | 97 + .../aws-sdk-go-v2/service/ecr/generated.json | 3 +- .../service/ecr/go_module_metadata.go | 2 +- .../ecr/internal/endpoints/endpoints.go | 42 + .../aws/aws-sdk-go-v2/service/ecr/options.go | 7 + .../aws-sdk-go-v2/service/ecr/serializers.go | 73 + .../aws-sdk-go-v2/service/ecr/types/enums.go | 30 +- .../aws-sdk-go-v2/service/ecr/types/types.go | 49 +- .../aws-sdk-go-v2/service/ecr/validators.go | 58 +- .../service/ecrpublic/CHANGELOG.md | 107 + .../service/ecrpublic/api_client.go | 127 +- .../api_op_BatchCheckLayerAvailability.go | 33 + .../ecrpublic/api_op_BatchDeleteImage.go | 33 + .../ecrpublic/api_op_CompleteLayerUpload.go | 33 + .../ecrpublic/api_op_CreateRepository.go | 33 + .../ecrpublic/api_op_DeleteRepository.go | 33 + .../api_op_DeleteRepositoryPolicy.go | 33 + .../ecrpublic/api_op_DescribeImageTags.go | 33 + .../ecrpublic/api_op_DescribeImages.go | 33 + .../ecrpublic/api_op_DescribeRegistries.go | 33 + .../ecrpublic/api_op_DescribeRepositories.go | 33 + .../ecrpublic/api_op_GetAuthorizationToken.go | 33 + .../api_op_GetRegistryCatalogData.go | 33 + .../api_op_GetRepositoryCatalogData.go | 33 + .../ecrpublic/api_op_GetRepositoryPolicy.go | 33 + .../ecrpublic/api_op_InitiateLayerUpload.go | 33 + .../ecrpublic/api_op_ListTagsForResource.go | 33 + .../service/ecrpublic/api_op_PutImage.go | 33 + .../api_op_PutRegistryCatalogData.go | 33 + .../api_op_PutRepositoryCatalogData.go | 33 + .../ecrpublic/api_op_SetRepositoryPolicy.go | 33 + .../service/ecrpublic/api_op_TagResource.go | 33 + .../service/ecrpublic/api_op_UntagResource.go | 33 + .../ecrpublic/api_op_UploadLayerPart.go | 33 + .../aws-sdk-go-v2/service/ecrpublic/auth.go | 28 +- .../service/ecrpublic/deserializers.go | 9 - .../service/ecrpublic/endpoints.go | 21 + .../service/ecrpublic/generated.json | 3 +- .../service/ecrpublic/go_module_metadata.go | 2 +- .../ecrpublic/internal/endpoints/endpoints.go | 23 + .../service/ecrpublic/options.go | 7 + .../internal/accept-encoding/CHANGELOG.md | 20 + .../accept-encoding/go_module_metadata.go | 2 +- .../internal/presigned-url/CHANGELOG.md | 73 + .../presigned-url/go_module_metadata.go | 2 +- .../aws-sdk-go-v2/service/signin/CHANGELOG.md | 13 + .../aws-sdk-go-v2/service/signin/LICENSE.txt} | 0 .../service/signin/api_client.go | 949 ++ .../signin/api_op_CreateOAuth2Token.go | 209 + .../aws/aws-sdk-go-v2/service/signin/auth.go | 351 + .../service/signin/deserializers.go | 655 + .../aws/aws-sdk-go-v2/service/signin/doc.go | 9 + .../aws-sdk-go-v2/service/signin/endpoints.go | 624 + .../service/signin/generated.json | 34 + .../service/signin/go_module_metadata.go | 6 + .../signin/internal/endpoints/endpoints.go | 333 + .../aws-sdk-go-v2/service/signin/options.go | 239 + .../service/signin/serializers.go | 135 + .../service/signin/types/enums.go | 37 + .../service/signin/types/errors.go | 151 + .../service/signin/types/types.go | 115 + .../service/signin/validators.go | 72 + .../aws-sdk-go-v2/service/sso/CHANGELOG.md | 106 + .../aws-sdk-go-v2/service/sso/api_client.go | 198 +- .../service/sso/api_op_GetRoleCredentials.go | 9 +- .../service/sso/api_op_ListAccountRoles.go | 9 +- .../service/sso/api_op_ListAccounts.go | 9 +- .../service/sso/api_op_Logout.go | 9 +- .../aws/aws-sdk-go-v2/service/sso/auth.go | 44 +- .../service/sso/deserializers.go | 10 - .../aws-sdk-go-v2/service/sso/endpoints.go | 33 +- .../aws-sdk-go-v2/service/sso/generated.json | 2 +- .../service/sso/go_module_metadata.go | 2 +- .../sso/internal/endpoints/endpoints.go | 20 + .../aws/aws-sdk-go-v2/service/sso/options.go | 7 + .../service/ssooidc/CHANGELOG.md | 110 + .../service/ssooidc/api_client.go | 198 +- .../service/ssooidc/api_op_CreateToken.go | 16 +- .../ssooidc/api_op_CreateTokenWithIAM.go | 31 +- .../service/ssooidc/api_op_RegisterClient.go | 9 +- .../api_op_StartDeviceAuthorization.go | 9 +- .../aws/aws-sdk-go-v2/service/ssooidc/auth.go | 44 +- .../service/ssooidc/deserializers.go | 31 +- .../aws/aws-sdk-go-v2/service/ssooidc/doc.go | 2 +- .../service/ssooidc/endpoints.go | 29 +- .../service/ssooidc/generated.json | 3 +- .../service/ssooidc/go_module_metadata.go | 2 +- .../ssooidc/internal/endpoints/endpoints.go | 23 + .../aws-sdk-go-v2/service/ssooidc/options.go | 7 + .../service/ssooidc/types/enums.go | 44 + .../service/ssooidc/types/errors.go | 2 + .../service/ssooidc/types/types.go | 15 +- .../aws-sdk-go-v2/service/sts/CHANGELOG.md | 112 + .../aws-sdk-go-v2/service/sts/api_client.go | 198 +- .../service/sts/api_op_AssumeRole.go | 15 +- .../service/sts/api_op_AssumeRoleWithSAML.go | 12 +- .../sts/api_op_AssumeRoleWithWebIdentity.go | 13 +- .../service/sts/api_op_AssumeRoot.go | 27 +- .../sts/api_op_DecodeAuthorizationMessage.go | 9 +- .../service/sts/api_op_GetAccessKeyInfo.go | 9 +- .../service/sts/api_op_GetCallerIdentity.go | 9 +- .../sts/api_op_GetDelegatedAccessToken.go | 172 + .../service/sts/api_op_GetFederationToken.go | 9 +- .../service/sts/api_op_GetSessionToken.go | 9 +- .../service/sts/api_op_GetWebIdentityToken.go | 195 + .../aws/aws-sdk-go-v2/service/sts/auth.go | 44 +- .../service/sts/deserializers.go | 805 +- .../aws-sdk-go-v2/service/sts/endpoints.go | 30 +- .../aws-sdk-go-v2/service/sts/generated.json | 4 +- .../service/sts/go_module_metadata.go | 2 +- .../sts/internal/endpoints/endpoints.go | 20 + .../aws/aws-sdk-go-v2/service/sts/options.go | 7 + .../aws-sdk-go-v2/service/sts/serializers.go | 193 + .../aws-sdk-go-v2/service/sts/types/errors.go | 117 +- .../aws-sdk-go-v2/service/sts/validators.go | 86 + vendor/github.com/aws/smithy-go/CHANGELOG.md | 63 +- vendor/github.com/aws/smithy-go/Makefile | 51 +- vendor/github.com/aws/smithy-go/README.md | 17 +- .../aws/smithy-go/endpoints/endpoint.go | 2 +- .../endpoints/private/rulesfn/doc.go | 4 + .../endpoints/private/rulesfn/strings.go | 25 + .../endpoints/private/rulesfn/uri.go | 130 + .../aws/smithy-go/go_module_metadata.go | 2 +- .../github.com/aws/smithy-go/metrics/nop.go | 93 +- .../aws/smithy-go/middleware/ordered_group.go | 14 +- .../aws/smithy-go/middleware/step_build.go | 185 +- .../smithy-go/middleware/step_deserialize.go | 175 +- .../aws/smithy-go/middleware/step_finalize.go | 167 +- .../smithy-go/middleware/step_initialize.go | 160 +- .../smithy-go/middleware/step_serialize.go | 166 +- vendor/github.com/aws/smithy-go/modman.toml | 1 - .../smithy-go/transport/http/interceptor.go | 321 + .../transport/http/interceptor_middleware.go | 325 + .../aws/smithy-go/transport/http/metrics.go | 6 + .../ecr-login/api/client.go | 2 +- .../ecr-login/config/log.go | 2 +- .../go-osc52/v2/LICENSE} | 2 +- .../aymanbagabas/go-osc52/v2/README.md | 83 + .../aymanbagabas/go-osc52/v2/osc52.go | 305 + .../buildkite/agent/v3/api/annotations.go | 12 +- .../buildkite/agent/v3/api/chunks.go | 4 +- .../buildkite/agent/v3/api/client.go | 24 +- .../agent/v3/api/github_code_access_token.go | 1 - .../github.com/buildkite/agent/v3/api/jobs.go | 34 +- .../buildkite/agent/v3/api/token.go | 35 + .../agent/v3/internal/agenthttp/auth.go | 2 +- .../agent/v3/internal/agenthttp/do.go | 11 +- .../buildkite/agent/v3/logger/buffer.go | 6 + .../buildkite/agent/v3/logger/log.go | 9 +- .../buildkite/agent/v3/version/VERSION | 2 +- .../buildkite/agent/v3/version/version.go | 4 - .../buildkite/go-pipeline/parser.go | 44 + .../buildkite/go-pipeline/pipeline.go | 5 +- .../buildkite/go-pipeline/secret.go | 43 + .../buildkite/go-pipeline/secrets.go | 141 + .../buildkite/go-pipeline/step_command.go | 12 +- .../go-pipeline/step_command_matrix.go | 10 +- vendor/github.com/buildkite/roko/README.md | 2 - vendor/github.com/buildkite/roko/retrier.go | 18 +- .../cenkalti/backoff/v5/exponential.go | 11 +- .../github.com/cenkalti/backoff/v5/retry.go | 4 +- .../stargz-snapshotter/estargz/build.go | 119 +- .../stargz-snapshotter/estargz/estargz.go | 9 + .../stargz-snapshotter/estargz/gzip.go | 6 +- .../stargz-snapshotter/estargz/testutil.go | 168 +- .../github.com/coreos/go-oidc/v3/oidc/jwks.go | 10 +- .../github.com/coreos/go-oidc/v3/oidc/oidc.go | 4 +- .../decred/dcrd/dcrec/secp256k1/v4/LICENSE | 17 + .../decred/dcrd/dcrec/secp256k1/v4/README.md | 72 + .../secp256k1/v4/compressedbytepoints.go | 18 + .../decred/dcrd/dcrec/secp256k1/v4/curve.go | 1310 ++ .../dcrd/dcrec/secp256k1/v4/curve_embedded.go | 14 + .../dcrec/secp256k1/v4/curve_precompute.go | 14 + .../decred/dcrd/dcrec/secp256k1/v4/doc.go | 59 + .../decred/dcrd/dcrec/secp256k1/v4/ecdh.go | 21 + .../dcrec/secp256k1/v4/ellipticadaptor.go | 255 + .../decred/dcrd/dcrec/secp256k1/v4/error.go | 67 + .../decred/dcrd/dcrec/secp256k1/v4/field.go | 1696 ++ .../dcrec/secp256k1/v4/loadprecomputed.go | 91 + .../dcrd/dcrec/secp256k1/v4/modnscalar.go | 1105 ++ .../decred/dcrd/dcrec/secp256k1/v4/nonce.go | 263 + .../decred/dcrd/dcrec/secp256k1/v4/privkey.go | 111 + .../decred/dcrd/dcrec/secp256k1/v4/pubkey.go | 236 + vendor/github.com/docker/cli/AUTHORS | 12 +- .../docker/cli/cli/config/config.go | 9 +- .../docker/cli/cli/config/configfile/file.go | 96 +- .../cli/cli/config/memorystore/store.go | 131 + .../docker/cli/cli/config/types/authconfig.go | 5 - vendor/github.com/emicklei/proto/CHANGES.md | 12 + vendor/github.com/emicklei/proto/README.md | 9 +- vendor/github.com/emicklei/proto/edition.go | 65 + .../github.com/emicklei/proto/extensions.go | 28 + vendor/github.com/emicklei/proto/literals.go | 301 + .../github.com/emicklei/proto/noop_visitor.go | 5 + vendor/github.com/emicklei/proto/option.go | 352 +- .../emicklei/proto/parent_accessor.go | 3 + vendor/github.com/emicklei/proto/parser.go | 32 +- vendor/github.com/emicklei/proto/proto.go | 8 + vendor/github.com/emicklei/proto/range.go | 4 +- vendor/github.com/emicklei/proto/token.go | 3 + vendor/github.com/emicklei/proto/visitor.go | 3 +- vendor/github.com/go-chi/chi/.travis.yml | 20 - .../go-chi/chi/middleware/content_type.go | 51 - .../go-chi/chi/middleware/profiler.go | 55 - .../github.com/go-chi/chi/{ => v5}/.gitignore | 0 .../go-chi/chi/{ => v5}/CHANGELOG.md | 157 +- .../go-chi/chi/{ => v5}/CONTRIBUTING.md | 12 +- vendor/github.com/go-chi/chi/{ => v5}/LICENSE | 0 vendor/github.com/go-chi/chi/v5/Makefile | 22 + .../github.com/go-chi/chi/{ => v5}/README.md | 180 +- vendor/github.com/go-chi/chi/v5/SECURITY.md | 5 + .../github.com/go-chi/chi/{ => v5}/chain.go | 6 +- vendor/github.com/go-chi/chi/{ => v5}/chi.go | 51 +- .../github.com/go-chi/chi/{ => v5}/context.go | 82 +- .../chi/{ => v5}/middleware/basic_auth.go | 3 +- .../go-chi/chi/v5/middleware/clean_path.go | 28 + .../chi/{ => v5}/middleware/compress.go | 79 +- .../{ => v5}/middleware/content_charset.go | 9 +- .../{ => v5}/middleware/content_encoding.go | 0 .../go-chi/chi/v5/middleware/content_type.go | 45 + .../chi/{ => v5}/middleware/get_head.go | 2 +- .../chi/{ => v5}/middleware/heartbeat.go | 2 +- .../go-chi/chi/{ => v5}/middleware/logger.go | 19 +- .../go-chi/chi/v5/middleware/maybe.go | 18 + .../chi/{ => v5}/middleware/middleware.go | 0 .../go-chi/chi/{ => v5}/middleware/nocache.go | 11 +- .../go-chi/chi/v5/middleware/page_route.go | 20 + .../go-chi/chi/v5/middleware/path_rewrite.go | 16 + .../go-chi/chi/v5/middleware/profiler.go | 49 + .../go-chi/chi/{ => v5}/middleware/realip.go | 22 +- .../chi/{ => v5}/middleware/recoverer.go | 51 +- .../chi/{ => v5}/middleware/request_id.go | 0 .../go-chi/chi/v5/middleware/request_size.go | 18 + .../chi/{ => v5}/middleware/route_headers.go | 71 +- .../go-chi/chi/{ => v5}/middleware/strip.go | 28 +- .../go-chi/chi/v5/middleware/sunset.go | 25 + .../chi/v5/middleware/supress_notfound.go | 27 + .../chi/{ => v5}/middleware/terminal.go | 0 .../chi/{ => v5}/middleware/throttle.go | 39 +- .../go-chi/chi/{ => v5}/middleware/timeout.go | 23 +- .../chi/{ => v5}/middleware/url_format.go | 51 +- .../go-chi/chi/{ => v5}/middleware/value.go | 2 +- .../chi/{ => v5}/middleware/wrap_writer.go | 83 +- vendor/github.com/go-chi/chi/{ => v5}/mux.go | 146 +- vendor/github.com/go-chi/chi/v5/path_value.go | 21 + .../go-chi/chi/v5/path_value_fallback.go | 19 + vendor/github.com/go-chi/chi/v5/pattern.go | 16 + .../go-chi/chi/v5/pattern_fallback.go | 17 + vendor/github.com/go-chi/chi/{ => v5}/tree.go | 90 +- .../github.com/go-jose/go-jose/v3/.gitignore | 2 - .../go-jose/go-jose/v3/.golangci.yml | 53 - .../github.com/go-jose/go-jose/v3/.travis.yml | 33 - .../go-jose/go-jose/v3/CHANGELOG.md | 78 - .../go-jose/go-jose/v3/CONTRIBUTING.md | 15 - .../github.com/go-jose/go-jose/v3/README.md | 108 - .../github.com/go-jose/go-jose/v3/SECURITY.md | 13 - .../go-jose/go-jose/v3/asymmetric.go | 595 - .../go-jose/go-jose/v3/cipher/cbc_hmac.go | 196 - .../go-jose/go-jose/v3/cipher/concat_kdf.go | 75 - .../go-jose/go-jose/v3/cipher/ecdh_es.go | 86 - .../go-jose/go-jose/v3/cipher/key_wrap.go | 109 - .../github.com/go-jose/go-jose/v3/crypter.go | 593 - .../github.com/go-jose/go-jose/v3/encoding.go | 237 - .../go-jose/go-jose/v3/json/LICENSE | 27 - .../go-jose/go-jose/v3/json/README.md | 13 - .../go-jose/go-jose/v3/json/decode.go | 1216 -- .../go-jose/go-jose/v3/json/encode.go | 1197 -- .../go-jose/go-jose/v3/json/indent.go | 141 - .../go-jose/go-jose/v3/json/scanner.go | 623 - .../go-jose/go-jose/v3/json/stream.go | 484 - .../go-jose/go-jose/v3/json/tags.go | 44 - vendor/github.com/go-jose/go-jose/v3/jwe.go | 296 - vendor/github.com/go-jose/go-jose/v3/jwk.go | 812 - vendor/github.com/go-jose/go-jose/v3/jws.go | 370 - .../go-jose/go-jose/v3/jwt/builder.go | 334 - .../go-jose/go-jose/v3/jwt/claims.go | 130 - .../github.com/go-jose/go-jose/v3/jwt/doc.go | 20 - .../go-jose/go-jose/v3/jwt/errors.go | 53 - .../github.com/go-jose/go-jose/v3/jwt/jwt.go | 133 - .../go-jose/go-jose/v3/jwt/validation.go | 120 - .../github.com/go-jose/go-jose/v3/opaque.go | 144 - .../github.com/go-jose/go-jose/v3/shared.go | 525 - .../github.com/go-jose/go-jose/v3/signing.go | 487 - .../go-jose/go-jose/v3/symmetric.go | 505 - .../go-openapi/analysis/.golangci.yml | 120 +- .../go-openapi/analysis/analyzer.go | 1352 +- .../github.com/go-openapi/analysis/debug.go | 15 +- vendor/github.com/go-openapi/analysis/doc.go | 15 +- .../github.com/go-openapi/analysis/errors.go | 56 + .../github.com/go-openapi/analysis/fixer.go | 17 +- .../github.com/go-openapi/analysis/flatten.go | 50 +- .../go-openapi/analysis/flatten_name.go | 21 +- .../go-openapi/analysis/flatten_options.go | 3 + .../analysis/internal/debug/debug.go | 21 +- .../internal/flatten/normalize/normalize.go | 3 + .../internal/flatten/operations/operations.go | 11 +- .../internal/flatten/replace/errors.go | 64 + .../internal/flatten/replace/replace.go | 90 +- .../flatten/schutils/flatten_schema.go | 11 +- .../analysis/internal/flatten/sortref/keys.go | 40 +- .../internal/flatten/sortref/sort_ref.go | 7 +- .../github.com/go-openapi/analysis/mixin.go | 55 +- .../github.com/go-openapi/analysis/schema.go | 11 +- .../go-openapi/errors/.golangci.yml | 114 +- vendor/github.com/go-openapi/errors/README.md | 4 + vendor/github.com/go-openapi/errors/api.go | 29 +- vendor/github.com/go-openapi/errors/auth.go | 15 +- vendor/github.com/go-openapi/errors/doc.go | 15 +- .../github.com/go-openapi/errors/headers.go | 25 +- .../go-openapi/errors/middleware.go | 19 +- .../github.com/go-openapi/errors/parsing.go | 53 +- vendor/github.com/go-openapi/errors/schema.go | 51 +- .../go-openapi/jsonpointer/.golangci.yml | 2 +- .../go-openapi/jsonpointer/README.md | 9 +- .../go-openapi/jsonpointer/pointer.go | 42 +- .../go-openapi/jsonreference/.golangci.yml | 2 +- .../go-openapi/jsonreference/NOTICE | 36 + .../go-openapi/jsonreference/README.md | 7 + .../jsonreference/internal/normalize_url.go | 3 + .../go-openapi/jsonreference/reference.go | 26 +- .../github.com/go-openapi/loads/.golangci.yml | 120 +- vendor/github.com/go-openapi/loads/README.md | 28 +- vendor/github.com/go-openapi/loads/doc.go | 17 +- vendor/github.com/go-openapi/loads/errors.go | 18 + vendor/github.com/go-openapi/loads/loaders.go | 46 +- vendor/github.com/go-openapi/loads/options.go | 20 +- vendor/github.com/go-openapi/loads/spec.go | 89 +- .../go-openapi/runtime/.golangci.yml | 123 +- .../github.com/go-openapi/runtime/README.md | 33 + .../go-openapi/runtime/bytestream.go | 23 +- .../go-openapi/runtime/client/auth_info.go | 15 +- .../go-openapi/runtime/client/keepalive.go | 3 + .../runtime/client/opentelemetry.go | 19 +- .../go-openapi/runtime/client/opentracing.go | 99 - .../go-openapi/runtime/client/request.go | 315 +- .../go-openapi/runtime/client/response.go | 15 +- .../go-openapi/runtime/client/runtime.go | 244 +- .../go-openapi/runtime/client_auth_info.go | 15 +- .../go-openapi/runtime/client_operation.go | 17 +- .../go-openapi/runtime/client_request.go | 25 +- .../go-openapi/runtime/client_response.go | 67 +- .../go-openapi/runtime/constants.go | 15 +- vendor/github.com/go-openapi/runtime/csv.go | 19 +- .../go-openapi/runtime/csv_options.go | 5 +- .../github.com/go-openapi/runtime/discard.go | 7 +- vendor/github.com/go-openapi/runtime/file.go | 19 +- vendor/github.com/go-openapi/runtime/go.work | 6 + .../github.com/go-openapi/runtime/go.work.sum | 93 + .../github.com/go-openapi/runtime/headers.go | 15 +- .../go-openapi/runtime/interfaces.go | 45 +- vendor/github.com/go-openapi/runtime/json.go | 19 +- .../go-openapi/runtime/logger/logger.go | 7 +- .../go-openapi/runtime/logger/standard.go | 7 +- .../go-openapi/runtime/middleware/context.go | 62 +- .../runtime/middleware/denco/router.go | 42 +- .../runtime/middleware/denco/server.go | 3 + .../runtime/middleware/denco/util.go | 3 + .../go-openapi/runtime/middleware/doc.go | 15 +- .../runtime/middleware/header/header.go | 21 +- .../runtime/middleware/negotiate.go | 6 +- .../runtime/middleware/not_implemented.go | 19 +- .../runtime/middleware/operation.go | 15 +- .../runtime/middleware/parameter.go | 201 +- .../go-openapi/runtime/middleware/rapidoc.go | 3 + .../go-openapi/runtime/middleware/redoc.go | 3 + .../go-openapi/runtime/middleware/request.go | 23 +- .../go-openapi/runtime/middleware/router.go | 69 +- .../go-openapi/runtime/middleware/security.go | 15 +- .../go-openapi/runtime/middleware/spec.go | 15 +- .../runtime/middleware/swaggerui.go | 3 + .../runtime/middleware/swaggerui_oauth2.go | 3 + .../runtime/middleware/ui_options.go | 7 +- .../runtime/middleware/untyped/api.go | 65 +- .../runtime/middleware/validation.go | 32 +- .../github.com/go-openapi/runtime/request.go | 21 +- .../runtime/security/authenticator.go | 59 +- .../go-openapi/runtime/security/authorizer.go | 17 +- .../github.com/go-openapi/runtime/statuses.go | 15 +- vendor/github.com/go-openapi/runtime/text.go | 23 +- .../github.com/go-openapi/runtime/values.go | 3 + vendor/github.com/go-openapi/runtime/xml.go | 19 +- .../go-openapi/runtime/yamlpc/yaml.go | 21 +- .../github.com/go-openapi/spec/.golangci.yml | 120 +- vendor/github.com/go-openapi/spec/README.md | 4 + vendor/github.com/go-openapi/spec/cache.go | 34 +- .../go-openapi/spec/contact_info.go | 19 +- vendor/github.com/go-openapi/spec/debug.go | 17 +- vendor/github.com/go-openapi/spec/embed.go | 3 + vendor/github.com/go-openapi/spec/errors.go | 6 + vendor/github.com/go-openapi/spec/expander.go | 39 +- .../go-openapi/spec/external_docs.go | 15 +- vendor/github.com/go-openapi/spec/header.go | 43 +- vendor/github.com/go-openapi/spec/info.go | 37 +- vendor/github.com/go-openapi/spec/items.go | 57 +- vendor/github.com/go-openapi/spec/license.go | 19 +- .../github.com/go-openapi/spec/normalizer.go | 19 +- .../go-openapi/spec/normalizer_nonwindows.go | 16 +- .../go-openapi/spec/normalizer_windows.go | 15 +- .../github.com/go-openapi/spec/operation.go | 52 +- .../github.com/go-openapi/spec/parameter.go | 43 +- .../github.com/go-openapi/spec/path_item.go | 21 +- vendor/github.com/go-openapi/spec/paths.go | 28 +- .../github.com/go-openapi/spec/properties.go | 6 +- vendor/github.com/go-openapi/spec/ref.go | 59 +- vendor/github.com/go-openapi/spec/resolver.go | 31 +- vendor/github.com/go-openapi/spec/response.go | 71 +- .../github.com/go-openapi/spec/responses.go | 23 +- vendor/github.com/go-openapi/spec/schema.go | 89 +- .../go-openapi/spec/schema_loader.go | 65 +- .../go-openapi/spec/security_scheme.go | 21 +- vendor/github.com/go-openapi/spec/spec.go | 15 +- vendor/github.com/go-openapi/spec/swagger.go | 39 +- vendor/github.com/go-openapi/spec/tag.go | 31 +- vendor/github.com/go-openapi/spec/url_go19.go | 3 + .../github.com/go-openapi/spec/validations.go | 51 +- .../github.com/go-openapi/spec/xml_object.go | 15 +- .../go-openapi/strfmt/.golangci.yml | 120 +- vendor/github.com/go-openapi/strfmt/README.md | 13 +- vendor/github.com/go-openapi/strfmt/bson.go | 62 +- vendor/github.com/go-openapi/strfmt/date.go | 44 +- .../github.com/go-openapi/strfmt/default.go | 1041 +- vendor/github.com/go-openapi/strfmt/doc.go | 15 +- .../github.com/go-openapi/strfmt/duration.go | 87 +- vendor/github.com/go-openapi/strfmt/errors.go | 13 + vendor/github.com/go-openapi/strfmt/format.go | 80 +- vendor/github.com/go-openapi/strfmt/ifaces.go | 32 + vendor/github.com/go-openapi/strfmt/mongo.go | 646 + vendor/github.com/go-openapi/strfmt/time.go | 135 +- vendor/github.com/go-openapi/strfmt/ulid.go | 38 +- .../github.com/go-openapi/swag/.codecov.yml | 4 + .../github.com/go-openapi/swag/.golangci.yml | 4 +- .../github.com/go-openapi/swag/.mockery.yml | 30 + vendor/github.com/go-openapi/swag/README.md | 184 +- vendor/github.com/go-openapi/swag/SECURITY.md | 19 + .../go-openapi/swag/cmdutils/cmd_utils.go | 17 +- .../go-openapi/swag/cmdutils/doc.go | 15 +- .../go-openapi/swag/cmdutils_iface.go | 15 +- .../go-openapi/swag/conv/convert.go | 15 +- .../go-openapi/swag/conv/convert_types.go | 21 +- vendor/github.com/go-openapi/swag/conv/doc.go | 15 +- .../github.com/go-openapi/swag/conv/format.go | 15 +- .../github.com/go-openapi/swag/conv/sizeof.go | 3 + .../go-openapi/swag/conv/type_constraints.go | 15 +- .../github.com/go-openapi/swag/conv_iface.go | 15 +- vendor/github.com/go-openapi/swag/doc.go | 75 +- .../go-openapi/swag/fileutils/doc.go | 15 +- .../go-openapi/swag/fileutils/file.go | 15 +- .../go-openapi/swag/fileutils/path.go | 21 +- .../go-openapi/swag/fileutils_iface.go | 15 +- vendor/github.com/go-openapi/swag/go.work | 20 + vendor/github.com/go-openapi/swag/go.work.sum | 7 + .../go-openapi/swag/jsonname/doc.go | 15 +- .../go-openapi/swag/jsonname/name_provider.go | 21 +- .../go-openapi/swag/jsonname_iface.go | 15 +- .../go-openapi/swag/jsonutils/README.md | 108 + .../go-openapi/swag/jsonutils/adapters/doc.go | 8 + .../swag/jsonutils/adapters/ifaces/doc.go | 5 + .../swag/jsonutils/adapters/ifaces/ifaces.go | 84 + .../adapters/ifaces/registry_iface.go | 91 + .../swag/jsonutils/adapters/registry.go | 229 + .../jsonutils/adapters/stdlib/json/adapter.go | 115 + .../jsonutils/adapters/stdlib/json/doc.go | 5 + .../jsonutils/adapters/stdlib/json/lexer.go | 320 + .../adapters/stdlib/json/ordered_map.go | 266 + .../jsonutils/adapters/stdlib/json/pool.go | 143 + .../adapters/stdlib/json/register.go | 26 + .../jsonutils/adapters/stdlib/json/writer.go | 75 + .../go-openapi/swag/jsonutils/concat.go | 20 +- .../go-openapi/swag/jsonutils/doc.go | 15 +- .../go-openapi/swag/jsonutils/json.go | 116 +- .../go-openapi/swag/jsonutils/ordered_map.go | 233 +- .../go-openapi/swag/jsonutils_iface.go | 33 +- .../github.com/go-openapi/swag/loading/doc.go | 15 +- .../go-openapi/swag/loading/errors.go | 15 +- .../go-openapi/swag/loading/json.go | 3 + .../go-openapi/swag/loading/loading.go | 15 +- .../go-openapi/swag/loading/options.go | 19 +- .../go-openapi/swag/loading/yaml.go | 17 +- .../go-openapi/swag/loading_iface.go | 17 +- .../go-openapi/swag/mangling/doc.go | 15 +- .../swag/mangling/initialism_index.go | 28 +- .../go-openapi/swag/mangling/name_lexem.go | 15 +- .../go-openapi/swag/mangling/name_mangler.go | 15 +- .../go-openapi/swag/mangling/options.go | 15 +- .../go-openapi/swag/mangling/pools.go | 15 +- .../go-openapi/swag/mangling/split.go | 223 +- .../go-openapi/swag/mangling/string_bytes.go | 15 +- .../go-openapi/swag/mangling/util.go | 15 +- .../go-openapi/swag/mangling_iface.go | 15 +- .../go-openapi/swag/netutils/doc.go | 15 +- .../go-openapi/swag/netutils/net.go | 15 +- .../go-openapi/swag/netutils_iface.go | 15 +- .../swag/stringutils/collection_formats.go | 15 +- .../go-openapi/swag/stringutils/doc.go | 15 +- .../go-openapi/swag/stringutils/strings.go | 15 +- .../go-openapi/swag/stringutils_iface.go | 15 +- .../go-openapi/swag/typeutils/doc.go | 15 +- .../go-openapi/swag/typeutils/types.go | 51 +- .../go-openapi/swag/typeutils_iface.go | 17 +- .../go-openapi/swag/yamlutils/doc.go | 23 +- .../go-openapi/swag/yamlutils/errors.go | 15 +- .../go-openapi/swag/yamlutils/ordered_map.go | 248 +- .../go-openapi/swag/yamlutils/yaml.go | 122 +- .../go-openapi/swag/yamlutils_iface.go | 19 +- .../go-openapi/validate/.golangci.yml | 121 +- .../github.com/go-openapi/validate/README.md | 4 + .../github.com/go-openapi/validate/context.go | 5 +- .../github.com/go-openapi/validate/debug.go | 17 +- .../go-openapi/validate/default_validator.go | 44 +- vendor/github.com/go-openapi/validate/doc.go | 15 +- .../go-openapi/validate/example_validator.go | 55 +- .../github.com/go-openapi/validate/formats.go | 19 +- .../github.com/go-openapi/validate/helpers.go | 31 +- .../go-openapi/validate/object_validator.go | 167 +- .../github.com/go-openapi/validate/options.go | 15 +- .../github.com/go-openapi/validate/pools.go | 3 + .../go-openapi/validate/pools_debug.go | 3 + .../github.com/go-openapi/validate/result.go | 317 +- vendor/github.com/go-openapi/validate/rexp.go | 20 +- .../github.com/go-openapi/validate/schema.go | 41 +- .../go-openapi/validate/schema_messages.go | 15 +- .../go-openapi/validate/schema_option.go | 15 +- .../go-openapi/validate/schema_props.go | 37 +- .../go-openapi/validate/slice_validator.go | 27 +- vendor/github.com/go-openapi/validate/spec.go | 59 +- .../go-openapi/validate/spec_messages.go | 27 +- vendor/github.com/go-openapi/validate/type.go | 150 +- .../go-openapi/validate/validator.go | 71 +- .../github.com/go-openapi/validate/values.go | 144 +- .../piv-go/v2/piv/certs/yubico-ca-1.pem | 20 + .../v2/piv/certs/yubico-intermediate.pem | 202 + vendor/github.com/go-piv/piv-go/v2/piv/key.go | 34 +- .../github.com/go-piv/piv-go/v2/piv/pcsc.go | 5 +- vendor/github.com/goccy/go-json/.codecov.yml | 32 + vendor/github.com/goccy/go-json/.gitignore | 2 + vendor/github.com/goccy/go-json/.golangci.yml | 86 + vendor/github.com/goccy/go-json/CHANGELOG.md | 425 + vendor/github.com/goccy/go-json/LICENSE | 21 + vendor/github.com/goccy/go-json/Makefile | 39 + vendor/github.com/goccy/go-json/README.md | 529 + vendor/github.com/goccy/go-json/color.go | 68 + vendor/github.com/goccy/go-json/decode.go | 263 + .../goccy/go-json/docker-compose.yml | 13 + vendor/github.com/goccy/go-json/encode.go | 326 + vendor/github.com/goccy/go-json/error.go | 41 + .../internal/decoder/anonymous_field.go | 41 + .../goccy/go-json/internal/decoder/array.go | 176 + .../goccy/go-json/internal/decoder/assign.go | 438 + .../goccy/go-json/internal/decoder/bool.go | 83 + .../goccy/go-json/internal/decoder/bytes.go | 118 + .../goccy/go-json/internal/decoder/compile.go | 493 + .../internal/decoder/compile_norace.go | 30 + .../go-json/internal/decoder/compile_race.go | 38 + .../goccy/go-json/internal/decoder/context.go | 254 + .../goccy/go-json/internal/decoder/float.go | 170 + .../goccy/go-json/internal/decoder/func.go | 146 + .../goccy/go-json/internal/decoder/int.go | 246 + .../go-json/internal/decoder/interface.go | 528 + .../goccy/go-json/internal/decoder/invalid.go | 55 + .../goccy/go-json/internal/decoder/map.go | 280 + .../goccy/go-json/internal/decoder/number.go | 123 + .../goccy/go-json/internal/decoder/option.go | 17 + .../goccy/go-json/internal/decoder/path.go | 670 + .../goccy/go-json/internal/decoder/ptr.go | 97 + .../goccy/go-json/internal/decoder/slice.go | 380 + .../goccy/go-json/internal/decoder/stream.go | 556 + .../goccy/go-json/internal/decoder/string.go | 452 + .../goccy/go-json/internal/decoder/struct.go | 845 + .../goccy/go-json/internal/decoder/type.go | 30 + .../goccy/go-json/internal/decoder/uint.go | 194 + .../internal/decoder/unmarshal_json.go | 104 + .../internal/decoder/unmarshal_text.go | 285 + .../internal/decoder/wrapped_string.go | 73 + .../goccy/go-json/internal/encoder/code.go | 1023 ++ .../goccy/go-json/internal/encoder/compact.go | 286 + .../go-json/internal/encoder/compiler.go | 939 ++ .../internal/encoder/compiler_norace.go | 33 + .../go-json/internal/encoder/compiler_race.go | 46 + .../goccy/go-json/internal/encoder/context.go | 105 + .../go-json/internal/encoder/decode_rune.go | 126 + .../goccy/go-json/internal/encoder/encoder.go | 601 + .../goccy/go-json/internal/encoder/indent.go | 211 + .../goccy/go-json/internal/encoder/int.go | 176 + .../goccy/go-json/internal/encoder/map112.go | 9 + .../goccy/go-json/internal/encoder/map113.go | 9 + .../goccy/go-json/internal/encoder/opcode.go | 752 + .../goccy/go-json/internal/encoder/option.go | 48 + .../goccy/go-json/internal/encoder/optype.go | 932 + .../goccy/go-json/internal/encoder/query.go | 135 + .../goccy/go-json/internal/encoder/string.go | 483 + .../go-json/internal/encoder/string_table.go | 415 + .../go-json/internal/encoder/vm/debug_vm.go | 41 + .../goccy/go-json/internal/encoder/vm/hack.go | 9 + .../goccy/go-json/internal/encoder/vm/util.go | 207 + .../goccy/go-json/internal/encoder/vm/vm.go | 4859 ++++++ .../internal/encoder/vm_color/debug_vm.go | 35 + .../go-json/internal/encoder/vm_color/hack.go | 9 + .../go-json/internal/encoder/vm_color/util.go | 274 + .../go-json/internal/encoder/vm_color/vm.go | 4859 ++++++ .../encoder/vm_color_indent/debug_vm.go | 35 + .../internal/encoder/vm_color_indent/util.go | 297 + .../internal/encoder/vm_color_indent/vm.go | 4859 ++++++ .../internal/encoder/vm_indent/debug_vm.go | 35 + .../internal/encoder/vm_indent/hack.go | 9 + .../internal/encoder/vm_indent/util.go | 230 + .../go-json/internal/encoder/vm_indent/vm.go | 4859 ++++++ .../goccy/go-json/internal/errors/error.go | 183 + .../goccy/go-json/internal/runtime/rtype.go | 262 + .../go-json/internal/runtime/struct_field.go | 91 + .../goccy/go-json/internal/runtime/type.go | 98 + vendor/github.com/goccy/go-json/json.go | 368 + vendor/github.com/goccy/go-json/option.go | 79 + vendor/github.com/goccy/go-json/path.go | 84 + vendor/github.com/goccy/go-json/query.go | 47 + .../go-containerregistry/pkg/v1/config.go | 9 +- .../pkg/v1/mutate/mutate.go | 2 +- .../pkg/v1/remote/options.go | 9 +- .../pkg/v1/remote/transport/error.go | 6 +- .../go-github/v72/github/dependency_graph.go | 82 - .../google/go-github/{v72 => v73}/AUTHORS | 0 .../google/go-github/{v72 => v73}/LICENSE | 0 .../go-github/{v72 => v73}/github/actions.go | 0 .../{v72 => v73}/github/actions_artifacts.go | 0 .../{v72 => v73}/github/actions_cache.go | 0 .../github/actions_hosted_runners.go | 0 .../{v72 => v73}/github/actions_oidc.go | 0 .../github/actions_permissions_enterprise.go | 0 .../github/actions_permissions_orgs.go | 0 .../github/actions_runner_groups.go | 0 .../{v72 => v73}/github/actions_runners.go | 0 .../{v72 => v73}/github/actions_secrets.go | 4 +- .../{v72 => v73}/github/actions_variables.go | 0 .../github/actions_workflow_jobs.go | 0 .../github/actions_workflow_runs.go | 0 .../{v72 => v73}/github/actions_workflows.go | 2 +- .../go-github/{v72 => v73}/github/activity.go | 0 .../{v72 => v73}/github/activity_events.go | 0 .../github/activity_notifications.go | 0 .../{v72 => v73}/github/activity_star.go | 6 +- .../{v72 => v73}/github/activity_watching.go | 0 .../go-github/{v72 => v73}/github/admin.go | 4 +- .../{v72 => v73}/github/admin_orgs.go | 6 +- .../{v72 => v73}/github/admin_stats.go | 2 +- .../{v72 => v73}/github/admin_users.go | 8 +- .../go-github/{v72 => v73}/github/apps.go | 0 .../{v72 => v73}/github/apps_hooks.go | 0 .../github/apps_hooks_deliveries.go | 0 .../{v72 => v73}/github/apps_installation.go | 0 .../{v72 => v73}/github/apps_manifest.go | 0 .../{v72 => v73}/github/apps_marketplace.go | 0 .../{v72 => v73}/github/attestations.go | 0 .../{v72 => v73}/github/authorizations.go | 4 +- .../go-github/{v72 => v73}/github/billing.go | 0 .../go-github/{v72 => v73}/github/checks.go | 0 .../{v72 => v73}/github/code_scanning.go | 0 .../{v72 => v73}/github/codesofconduct.go | 0 .../{v72 => v73}/github/codespaces.go | 0 .../{v72 => v73}/github/codespaces_secrets.go | 0 .../go-github/{v72 => v73}/github/copilot.go | 18 +- .../{v72 => v73}/github/dependabot.go | 0 .../{v72 => v73}/github/dependabot_alerts.go | 0 .../{v72 => v73}/github/dependabot_secrets.go | 0 .../go-github/v73/github/dependency_graph.go | 125 + .../github/dependency_graph_snapshots.go | 0 .../go-github/{v72 => v73}/github/doc.go | 32 +- .../go-github/{v72 => v73}/github/emojis.go | 0 .../{v72 => v73}/github/enterprise.go | 0 .../enterprise_actions_hosted_runners.go | 0 .../enterprise_actions_runner_groups.go | 0 .../github/enterprise_actions_runners.go | 0 .../github/enterprise_audit_log.go | 0 .../enterprise_code_security_and_analysis.go | 0 .../github/enterprise_manage_ghes.go | 8 +- .../github/enterprise_manage_ghes_config.go | 20 +- .../enterprise_manage_ghes_maintenance.go | 4 +- .../github/enterprise_manage_ghes_ssh.go | 6 +- .../enterprise_network_configurations.go | 0 .../github/enterprise_properties.go | 0 .../{v72 => v73}/github/enterprise_rules.go | 0 .../go-github/{v72 => v73}/github/event.go | 4 +- .../{v72 => v73}/github/event_types.go | 76 +- .../go-github/{v72 => v73}/github/gists.go | 0 .../{v72 => v73}/github/gists_comments.go | 0 .../go-github/{v72 => v73}/github/git.go | 0 .../{v72 => v73}/github/git_blobs.go | 0 .../{v72 => v73}/github/git_commits.go | 0 .../go-github/{v72 => v73}/github/git_refs.go | 0 .../go-github/{v72 => v73}/github/git_tags.go | 0 .../{v72 => v73}/github/git_trees.go | 6 +- .../{v72 => v73}/github/github-accessors.go | 72 + .../go-github/{v72 => v73}/github/github.go | 24 +- .../{v72 => v73}/github/gitignore.go | 0 .../{v72 => v73}/github/interactions.go | 0 .../{v72 => v73}/github/interactions_orgs.go | 0 .../{v72 => v73}/github/interactions_repos.go | 0 .../{v72 => v73}/github/issue_import.go | 0 .../go-github/{v72 => v73}/github/issues.go | 0 .../{v72 => v73}/github/issues_assignees.go | 0 .../{v72 => v73}/github/issues_comments.go | 0 .../{v72 => v73}/github/issues_events.go | 0 .../{v72 => v73}/github/issues_labels.go | 0 .../{v72 => v73}/github/issues_milestones.go | 0 .../{v72 => v73}/github/issues_timeline.go | 0 .../go-github/{v72 => v73}/github/licenses.go | 0 .../go-github/{v72 => v73}/github/markdown.go | 0 .../go-github/{v72 => v73}/github/messages.go | 46 +- .../go-github/{v72 => v73}/github/meta.go | 0 .../{v72 => v73}/github/migrations.go | 0 .../github/migrations_source_import.go | 0 .../{v72 => v73}/github/migrations_user.go | 0 .../go-github/{v72 => v73}/github/orgs.go | 0 .../github/orgs_actions_allowed.go | 0 .../github/orgs_actions_permissions.go | 0 .../{v72 => v73}/github/orgs_attestations.go | 0 .../{v72 => v73}/github/orgs_audit_log.go | 8 +- .../orgs_codesecurity_configurations.go | 0 .../github/orgs_credential_authorizations.go | 0 .../github/orgs_custom_repository_roles.go | 0 .../{v72 => v73}/github/orgs_hooks.go | 0 .../github/orgs_hooks_configuration.go | 0 .../github/orgs_hooks_deliveries.go | 0 .../{v72 => v73}/github/orgs_issue_types.go | 0 .../{v72 => v73}/github/orgs_members.go | 0 .../github/orgs_network_configurations.go | 0 .../github/orgs_organization_roles.go | 0 .../github/orgs_outside_collaborators.go | 0 .../{v72 => v73}/github/orgs_packages.go | 0 .../github/orgs_personal_access_tokens.go | 0 .../{v72 => v73}/github/orgs_properties.go | 15 +- .../{v72 => v73}/github/orgs_rules.go | 0 .../github/orgs_security_managers.go | 0 .../github/orgs_users_blocking.go | 0 .../go-github/{v72 => v73}/github/packages.go | 6 +- .../go-github/{v72 => v73}/github/pulls.go | 0 .../{v72 => v73}/github/pulls_comments.go | 0 .../{v72 => v73}/github/pulls_reviewers.go | 0 .../{v72 => v73}/github/pulls_reviews.go | 0 .../{v72 => v73}/github/pulls_threads.go | 0 .../{v72 => v73}/github/rate_limit.go | 0 .../{v72 => v73}/github/reactions.go | 0 .../go-github/{v72 => v73}/github/repos.go | 106 +- .../github/repos_actions_access.go | 0 .../github/repos_actions_allowed.go | 0 .../github/repos_actions_permissions.go | 0 .../{v72 => v73}/github/repos_attestations.go | 0 .../{v72 => v73}/github/repos_autolinks.go | 0 .../{v72 => v73}/github/repos_codeowners.go | 0 .../github/repos_collaborators.go | 0 .../{v72 => v73}/github/repos_comments.go | 0 .../{v72 => v73}/github/repos_commits.go | 0 .../github/repos_community_health.go | 0 .../{v72 => v73}/github/repos_contents.go | 26 +- .../repos_deployment_branch_policies.go | 0 .../repos_deployment_protection_rules.go | 0 .../{v72 => v73}/github/repos_deployments.go | 18 +- .../{v72 => v73}/github/repos_environments.go | 4 +- .../{v72 => v73}/github/repos_forks.go | 0 .../{v72 => v73}/github/repos_hooks.go | 18 +- .../github/repos_hooks_configuration.go | 0 .../github/repos_hooks_deliveries.go | 2 +- .../{v72 => v73}/github/repos_invitations.go | 0 .../{v72 => v73}/github/repos_keys.go | 0 .../{v72 => v73}/github/repos_lfs.go | 0 .../{v72 => v73}/github/repos_merging.go | 0 .../{v72 => v73}/github/repos_pages.go | 0 .../github/repos_prereceive_hooks.go | 8 +- .../{v72 => v73}/github/repos_properties.go | 0 .../{v72 => v73}/github/repos_releases.go | 0 .../{v72 => v73}/github/repos_rules.go | 0 .../{v72 => v73}/github/repos_stats.go | 0 .../{v72 => v73}/github/repos_statuses.go | 0 .../{v72 => v73}/github/repos_tags.go | 0 .../{v72 => v73}/github/repos_traffic.go | 0 .../go-github/{v72 => v73}/github/rules.go | 0 .../go-github/{v72 => v73}/github/scim.go | 0 .../go-github/{v72 => v73}/github/search.go | 12 +- .../{v72 => v73}/github/secret_scanning.go | 0 .../github/security_advisories.go | 0 .../go-github/{v72 => v73}/github/strings.go | 2 +- .../google/go-github/v73/github/sub_issue.go | 140 + .../go-github/{v72 => v73}/github/teams.go | 0 .../github/teams_discussion_comments.go | 0 .../{v72 => v73}/github/teams_discussions.go | 0 .../{v72 => v73}/github/teams_members.go | 0 .../{v72 => v73}/github/timestamp.go | 0 .../go-github/{v72 => v73}/github/users.go | 0 .../github/users_administration.go | 8 +- .../{v72 => v73}/github/users_attestations.go | 0 .../{v72 => v73}/github/users_blocking.go | 0 .../{v72 => v73}/github/users_emails.go | 0 .../{v72 => v73}/github/users_followers.go | 0 .../{v72 => v73}/github/users_gpg_keys.go | 0 .../{v72 => v73}/github/users_keys.go | 0 .../{v72 => v73}/github/users_packages.go | 0 .../github/users_ssh_signing_keys.go | 0 .../{v72 => v73}/github/with_appengine.go | 0 .../{v72 => v73}/github/without_appengine.go | 0 vendor/github.com/gorilla/mux/.editorconfig | 20 - vendor/github.com/gorilla/mux/.gitignore | 1 - vendor/github.com/gorilla/mux/LICENSE | 27 - vendor/github.com/gorilla/mux/Makefile | 34 - vendor/github.com/gorilla/mux/README.md | 812 - vendor/github.com/gorilla/mux/doc.go | 305 - vendor/github.com/gorilla/mux/middleware.go | 74 - vendor/github.com/gorilla/mux/mux.go | 608 - vendor/github.com/gorilla/mux/regexp.go | 388 - vendor/github.com/gorilla/mux/route.go | 765 - vendor/github.com/gorilla/mux/test_helpers.go | 19 - .../protoc-gen-openapiv2/options/BUILD.bazel | 44 + .../options/annotations.pb.go | 269 + .../options/annotations.proto | 51 + .../options/annotations_protoopaque.pb.go | 269 + .../protoc-gen-openapiv2/options/buf.gen.yaml | 7 + .../options/openapiv2.pb.go | 4263 +++++ .../options/openapiv2.proto | 759 + .../options/openapiv2_protoopaque.pb.go | 4055 +++++ .../grpc-gateway/v2/runtime/BUILD.bazel | 1 + .../grpc-gateway/v2/runtime/context.go | 6 +- .../grpc-gateway/v2/runtime/marshal_jsonpb.go | 6 +- .../grpc-gateway/v2/runtime/mux.go | 16 +- .../go/v1/resource_descriptor.pb.go | 63 +- .../in-toto/attestation/go/v1/statement.pb.go | 48 +- vendor/github.com/josharian/intern/README.md | 5 - vendor/github.com/josharian/intern/intern.go | 44 - .../klauspost/compress/fse/bitwriter.go | 2 +- .../klauspost/compress/fse/compress.go | 2 +- .../klauspost/compress/huff0/bitwriter.go | 2 +- .../klauspost/compress/huff0/compress.go | 6 +- .../klauspost/compress/huff0/decompress.go | 14 +- .../compress/huff0/decompress_amd64.go | 7 +- .../klauspost/compress/huff0/huff0.go | 4 +- .../compress/internal/le/unsafe_disabled.go | 4 +- .../compress/internal/le/unsafe_enabled.go | 9 +- .../compress/internal/snapref/decode.go | 2 +- .../compress/internal/snapref/encode.go | 4 +- .../klauspost/compress/zstd/bitwriter.go | 2 +- .../klauspost/compress/zstd/blockdec.go | 6 +- .../klauspost/compress/zstd/decoder.go | 8 +- .../klauspost/compress/zstd/dict.go | 20 +- .../klauspost/compress/zstd/enc_base.go | 10 +- .../klauspost/compress/zstd/enc_best.go | 23 +- .../klauspost/compress/zstd/enc_better.go | 30 +- .../klauspost/compress/zstd/enc_dfast.go | 32 +- .../klauspost/compress/zstd/enc_fast.go | 30 +- .../klauspost/compress/zstd/framedec.go | 5 +- .../klauspost/compress/zstd/fse_encoder.go | 2 +- .../klauspost/compress/zstd/seqdec.go | 5 +- .../klauspost/compress/zstd/seqdec_amd64.go | 10 +- .../klauspost/compress/zstd/simple_go124.go | 56 + .../klauspost/compress/zstd/snappy.go | 2 +- .../github.com/klauspost/compress/zstd/zip.go | 2 +- .../klauspost/compress/zstd/zstd.go | 4 +- .../lestrrat-go/blackmagic/.gitignore | 15 + .../github.com/lestrrat-go/blackmagic/LICENSE | 21 + .../lestrrat-go/blackmagic/README.md | 3 + .../lestrrat-go/blackmagic/blackmagic.go | 125 + .../lestrrat-go/dsig-secp256k1/.gitignore | 32 + .../lestrrat-go/dsig-secp256k1/Changes | 5 + .../lestrrat-go/dsig-secp256k1/LICENSE | 21 + .../lestrrat-go/dsig-secp256k1/secp256k1.go | 29 + vendor/github.com/lestrrat-go/dsig/.gitignore | 32 + vendor/github.com/lestrrat-go/dsig/Changes | 5 + vendor/github.com/lestrrat-go/dsig/LICENSE | 21 + vendor/github.com/lestrrat-go/dsig/README.md | 163 + .../github.com/lestrrat-go/dsig/algorithms.go | 37 + .../lestrrat-go/dsig/crypto_signer.go | 45 + vendor/github.com/lestrrat-go/dsig/dsig.go | 224 + vendor/github.com/lestrrat-go/dsig/ecdsa.go | 200 + vendor/github.com/lestrrat-go/dsig/eddsa.go | 44 + vendor/github.com/lestrrat-go/dsig/hmac.go | 45 + .../dsig/internal/ecutil/ecutil.go | 76 + vendor/github.com/lestrrat-go/dsig/rsa.go | 63 + vendor/github.com/lestrrat-go/dsig/sign.go | 100 + .../github.com/lestrrat-go/dsig/validation.go | 66 + vendor/github.com/lestrrat-go/dsig/verify.go | 134 + .../github.com/lestrrat-go/httpcc/.gitignore | 15 + vendor/github.com/lestrrat-go/httpcc/LICENSE | 21 + .../github.com/lestrrat-go/httpcc/README.md | 35 + .../lestrrat-go/httpcc/directives.go | 117 + .../github.com/lestrrat-go/httpcc/httpcc.go | 310 + .../lestrrat-go/httprc/v3/.gitignore | 15 + .../lestrrat-go/httprc/v3/.golangci.yml | 95 + .../github.com/lestrrat-go/httprc/v3/Changes | 30 + .../httprc/v3/LICENSE} | 2 +- .../lestrrat-go/httprc/v3/README.md | 172 + .../lestrrat-go/httprc/v3/backend.go | 235 + .../lestrrat-go/httprc/v3/client.go | 183 + .../lestrrat-go/httprc/v3/controller.go | 186 + .../lestrrat-go/httprc/v3/errors.go | 57 + .../lestrrat-go/httprc/v3/errsink/errsink.go | 59 + .../lestrrat-go/httprc/v3/httprc.go | 90 + .../lestrrat-go/httprc/v3/options.go | 144 + .../httprc/v3/proxysink/proxysink.go | 135 + .../lestrrat-go/httprc/v3/resource.go | 359 + .../httprc/v3/tracesink/tracesink.go | 52 + .../lestrrat-go/httprc/v3/transformer.go | 37 + .../lestrrat-go/httprc/v3/whitelist.go | 113 + .../lestrrat-go/httprc/v3/worker.go | 62 + .../lestrrat-go/jwx/v3/.bazelignore | 4 + vendor/github.com/lestrrat-go/jwx/v3/.bazelrc | 1 + .../lestrrat-go/jwx/v3/.bazelversion | 1 + .../ksuid => lestrrat-go/jwx/v3}/.gitignore | 16 +- .../lestrrat-go/jwx/v3/.golangci.yml | 125 + vendor/github.com/lestrrat-go/jwx/v3/BUILD | 47 + vendor/github.com/lestrrat-go/jwx/v3/Changes | 222 + .../lestrrat-go/jwx/v3/Changes-v2.md | 390 + .../lestrrat-go/jwx/v3/Changes-v3.md | 140 + .../jwx => lestrrat-go/jwx/v3}/LICENSE | 1 + .../lestrrat-go/jwx/v3/MODULE.bazel | 34 + .../lestrrat-go/jwx/v3/MODULE.bazel.lock | 230 + vendor/github.com/lestrrat-go/jwx/v3/Makefile | 98 + .../github.com/lestrrat-go/jwx/v3/README.md | 263 + .../github.com/lestrrat-go/jwx/v3/SECURITY.md | 18 + .../github.com/lestrrat-go/jwx/v3/WORKSPACE | 2 + .../lestrrat-go/jwx/v3/cert/BUILD.bazel | 34 + .../lestrrat-go/jwx/v3/cert/cert.go | 48 + .../lestrrat-go/jwx/v3/cert/chain.go | 80 + .../github.com/lestrrat-go/jwx/v3/codecov.yml | 2 + .../github.com/lestrrat-go/jwx/v3/format.go | 104 + .../jwx/v3/formatkind_string_gen.go | 29 + .../jwx/v3/internal/base64/BUILD.bazel | 21 + .../jwx/v3/internal/base64/asmbase64.go | 51 + .../jwx/v3/internal/base64/base64.go | 139 + .../jwx/v3/internal/ecutil/BUILD.bazel | 14 + .../jwx/v3/internal/ecutil/ecutil.go | 76 + .../jwx/v3/internal/json/BUILD.bazel | 19 + .../lestrrat-go/jwx/v3/internal/json/goccy.go | 49 + .../lestrrat-go/jwx/v3/internal/json/json.go | 127 + .../jwx/v3/internal/json/registry.go | 90 + .../jwx/v3/internal/json/stdlib.go | 47 + .../jwx/v3/internal/jwxio/BUILD.bazel | 8 + .../jwx/v3/internal/jwxio/jwxio.go | 29 + .../jwx/v3/internal/keyconv/BUILD.bazel | 31 + .../jwx/v3/internal/keyconv/keyconv.go | 354 + .../jwx/v3/internal/pool/BUILD.bazel | 32 + .../jwx/v3/internal/pool/big_int.go | 19 + .../jwx/v3/internal/pool/byte_slice.go | 19 + .../jwx/v3/internal/pool/bytes_buffer.go | 18 + .../jwx/v3/internal/pool/error_slice.go | 16 + .../jwx/v3/internal/pool/key_to_error_map.go | 19 + .../lestrrat-go/jwx/v3/internal/pool/pool.go | 70 + .../jwx/v3/internal/tokens/BUILD.bazel | 17 + .../jwx/v3/internal/tokens/jwe_tokens.go | 48 + .../jwx/v3/internal/tokens/tokens.go | 51 + .../lestrrat-go/jwx/v3/jwa/BUILD.bazel | 45 + .../lestrrat-go/jwx/v3/jwa/README.md | 3 + .../lestrrat-go/jwx/v3/jwa/compression_gen.go | 153 + .../jwx/v3/jwa/content_encryption_gen.go | 179 + .../lestrrat-go/jwx/v3/jwa/elliptic_gen.go | 190 + .../github.com/lestrrat-go/jwx/v3/jwa/jwa.go | 68 + .../jwx/v3/jwa/key_encryption_gen.go | 268 + .../lestrrat-go/jwx/v3/jwa/key_type_gen.go | 172 + .../lestrrat-go/jwx/v3/jwa/options.yaml | 41 + .../lestrrat-go/jwx/v3/jwa/options_gen.go | 91 + .../lestrrat-go/jwx/v3/jwa/secp2561k.go | 15 + .../lestrrat-go/jwx/v3/jwa/signature_gen.go | 242 + .../lestrrat-go/jwx/v3/jwe/BUILD.bazel | 70 + .../lestrrat-go/jwx/v3/jwe/README.md | 94 + .../lestrrat-go/jwx/v3/jwe/compress.go | 62 + .../lestrrat-go/jwx/v3/jwe/decrypt.go | 227 + .../lestrrat-go/jwx/v3/jwe/encrypt.go | 193 + .../lestrrat-go/jwx/v3/jwe/errors.go | 90 + .../lestrrat-go/jwx/v3/jwe/filter.go | 36 + .../lestrrat-go/jwx/v3/jwe/headers.go | 95 + .../lestrrat-go/jwx/v3/jwe/headers_gen.go | 899 + .../lestrrat-go/jwx/v3/jwe/interface.go | 207 + .../jwx/v3/jwe/internal/aescbc/BUILD.bazel | 22 + .../jwx/v3/jwe/internal/aescbc/aescbc.go | 270 + .../jwx/v3/jwe/internal/cipher/BUILD.bazel | 34 + .../jwx/v3/jwe/internal/cipher/cipher.go | 169 + .../jwx/v3/jwe/internal/cipher/interface.go | 32 + .../jwx/v3/jwe/internal/concatkdf/BUILD.bazel | 24 + .../v3/jwe/internal/concatkdf/concatkdf.go | 66 + .../v3/jwe/internal/content_crypt/BUILD.bazel | 21 + .../internal/content_crypt/content_crypt.go | 43 + .../jwe/internal/content_crypt/interface.go | 20 + .../jwx/v3/jwe/internal/keygen/BUILD.bazel | 24 + .../jwx/v3/jwe/internal/keygen/interface.go | 40 + .../jwx/v3/jwe/internal/keygen/keygen.go | 139 + .../github.com/lestrrat-go/jwx/v3/jwe/io.go | 36 + .../github.com/lestrrat-go/jwx/v3/jwe/jwe.go | 1036 ++ .../lestrrat-go/jwx/v3/jwe/jwebb/BUILD.bazel | 43 + .../jwx/v3/jwe/jwebb/content_cipher.go | 34 + .../lestrrat-go/jwx/v3/jwe/jwebb/jwebb.go | 15 + .../v3/jwe/jwebb/key_decrypt_asymmetric.go | 177 + .../jwx/v3/jwe/jwebb/key_decrypt_symmetric.go | 91 + .../v3/jwe/jwebb/key_encrypt_asymmetric.go | 147 + .../jwx/v3/jwe/jwebb/key_encrypt_symmetric.go | 115 + .../jwx/v3/jwe/jwebb/key_encryption.go | 70 + .../lestrrat-go/jwx/v3/jwe/jwebb/keywrap.go | 110 + .../lestrrat-go/jwx/v3/jwe/key_provider.go | 163 + .../lestrrat-go/jwx/v3/jwe/message.go | 546 + .../lestrrat-go/jwx/v3/jwe/options.go | 108 + .../lestrrat-go/jwx/v3/jwe/options.yaml | 172 + .../lestrrat-go/jwx/v3/jwe/options_gen.go | 350 + .../lestrrat-go/jwx/v3/jwk/BUILD.bazel | 87 + .../lestrrat-go/jwx/v3/jwk/README.md | 215 + .../lestrrat-go/jwx/v3/jwk/cache.go | 362 + .../lestrrat-go/jwx/v3/jwk/convert.go | 399 + .../github.com/lestrrat-go/jwx/v3/jwk/doc.go | 294 + .../lestrrat-go/jwx/v3/jwk/ecdsa.go | 402 + .../lestrrat-go/jwx/v3/jwk/ecdsa/BUILD.bazel | 15 + .../lestrrat-go/jwx/v3/jwk/ecdsa/ecdsa.go | 76 + .../lestrrat-go/jwx/v3/jwk/ecdsa_gen.go | 1432 ++ .../lestrrat-go/jwx/v3/jwk/errors.go | 79 + .../lestrrat-go/jwx/v3/jwk/es256k.go | 14 + .../lestrrat-go/jwx/v3/jwk/fetch.go | 117 + .../lestrrat-go/jwx/v3/jwk/filter.go | 28 + .../lestrrat-go/jwx/v3/jwk/interface.go | 143 + .../lestrrat-go/jwx/v3/jwk/interface_gen.go | 109 + .../github.com/lestrrat-go/jwx/v3/jwk/io.go | 42 + .../github.com/lestrrat-go/jwx/v3/jwk/jwk.go | 709 + .../lestrrat-go/jwx/v3/jwk/jwkbb/BUILD.bazel | 17 + .../lestrrat-go/jwx/v3/jwk/jwkbb/x509.go | 111 + .../lestrrat-go/jwx/v3/jwk/key_ops.go | 58 + .../github.com/lestrrat-go/jwx/v3/jwk/okp.go | 321 + .../lestrrat-go/jwx/v3/jwk/okp_gen.go | 1347 ++ .../lestrrat-go/jwx/v3/jwk/options.go | 76 + .../lestrrat-go/jwx/v3/jwk/options.yaml | 143 + .../lestrrat-go/jwx/v3/jwk/options_gen.go | 297 + .../lestrrat-go/jwx/v3/jwk/parser.go | 244 + .../github.com/lestrrat-go/jwx/v3/jwk/rsa.go | 360 + .../lestrrat-go/jwx/v3/jwk/rsa_gen.go | 1543 ++ .../github.com/lestrrat-go/jwx/v3/jwk/set.go | 311 + .../lestrrat-go/jwx/v3/jwk/symmetric.go | 105 + .../lestrrat-go/jwx/v3/jwk/symmetric_gen.go | 620 + .../lestrrat-go/jwx/v3/jwk/usage.go | 74 + .../lestrrat-go/jwx/v3/jwk/whitelist.go | 38 + .../github.com/lestrrat-go/jwx/v3/jwk/x509.go | 249 + .../lestrrat-go/jwx/v3/jws/BUILD.bazel | 76 + .../lestrrat-go/jwx/v3/jws/README.md | 111 + .../lestrrat-go/jwx/v3/jws/errors.go | 112 + .../lestrrat-go/jwx/v3/jws/es256k.go | 13 + .../lestrrat-go/jwx/v3/jws/filter.go | 36 + .../lestrrat-go/jwx/v3/jws/headers.go | 52 + .../lestrrat-go/jwx/v3/jws/headers_gen.go | 704 + .../lestrrat-go/jwx/v3/jws/interface.go | 80 + .../jwx/v3/jws/internal/keytype/BUILD.bazel | 11 + .../jwx/v3/jws/internal/keytype/keytype.go | 57 + .../github.com/lestrrat-go/jwx/v3/jws/io.go | 36 + .../github.com/lestrrat-go/jwx/v3/jws/jws.go | 662 + .../lestrrat-go/jwx/v3/jws/jwsbb/BUILD.bazel | 38 + .../jwx/v3/jws/jwsbb/crypto_signer.go | 45 + .../lestrrat-go/jwx/v3/jws/jwsbb/ecdsa.go | 179 + .../lestrrat-go/jwx/v3/jws/jwsbb/eddsa.go | 30 + .../lestrrat-go/jwx/v3/jws/jwsbb/es256k.go | 14 + .../lestrrat-go/jwx/v3/jws/jwsbb/format.go | 235 + .../lestrrat-go/jwx/v3/jws/jwsbb/header.go | 222 + .../lestrrat-go/jwx/v3/jws/jwsbb/hmac.go | 52 + .../lestrrat-go/jwx/v3/jws/jwsbb/jwsbb.go | 94 + .../lestrrat-go/jwx/v3/jws/jwsbb/rsa.go | 71 + .../lestrrat-go/jwx/v3/jws/jwsbb/sign.go | 110 + .../lestrrat-go/jwx/v3/jws/jwsbb/verify.go | 105 + .../lestrrat-go/jwx/v3/jws/key_provider.go | 291 + .../lestrrat-go/jwx/v3/jws/legacy.go | 88 + .../lestrrat-go/jwx/v3/jws/legacy/BUILD.bazel | 21 + .../lestrrat-go/jwx/v3/jws/legacy/ecdsa.go | 204 + .../lestrrat-go/jwx/v3/jws/legacy/eddsa.go | 79 + .../lestrrat-go/jwx/v3/jws/legacy/hmac.go | 90 + .../lestrrat-go/jwx/v3/jws/legacy/legacy.go | 36 + .../lestrrat-go/jwx/v3/jws/legacy/rsa.go | 145 + .../lestrrat-go/jwx/v3/jws/message.go | 550 + .../lestrrat-go/jwx/v3/jws/options.go | 259 + .../lestrrat-go/jwx/v3/jws/options.yaml | 234 + .../lestrrat-go/jwx/v3/jws/options_gen.go | 449 + .../lestrrat-go/jwx/v3/jws/sign_context.go | 141 + .../jwx/v3/jws/signature_builder.go | 118 + .../lestrrat-go/jwx/v3/jws/signer.go | 158 + .../lestrrat-go/jwx/v3/jws/verifier.go | 154 + .../lestrrat-go/jwx/v3/jws/verify_context.go | 211 + .../lestrrat-go/jwx/v3/jwt/BUILD.bazel | 72 + .../lestrrat-go/jwx/v3/jwt/README.md | 224 + .../lestrrat-go/jwx/v3/jwt/builder_gen.go | 88 + .../lestrrat-go/jwx/v3/jwt/errors.go | 95 + .../lestrrat-go/jwx/v3/jwt/fastpath.go | 71 + .../lestrrat-go/jwx/v3/jwt/filter.go | 34 + .../github.com/lestrrat-go/jwx/v3/jwt/http.go | 295 + .../lestrrat-go/jwx/v3/jwt/interface.go | 8 + .../jwx/v3/jwt/internal/errors/BUILD.bazel | 16 + .../jwx/v3/jwt/internal/errors/errors.go | 183 + .../jwx/v3/jwt/internal/types/BUILD.bazel | 35 + .../jwx/v3/jwt/internal/types/date.go | 192 + .../jwx/v3/jwt/internal/types/string.go | 43 + .../github.com/lestrrat-go/jwx/v3/jwt/io.go | 42 + .../github.com/lestrrat-go/jwx/v3/jwt/jwt.go | 592 + .../lestrrat-go/jwx/v3/jwt/options.go | 322 + .../lestrrat-go/jwx/v3/jwt/options.yaml | 274 + .../lestrrat-go/jwx/v3/jwt/options_gen.go | 495 + .../lestrrat-go/jwx/v3/jwt/serialize.go | 264 + .../lestrrat-go/jwx/v3/jwt/token_gen.go | 635 + .../lestrrat-go/jwx/v3/jwt/token_options.go | 78 + .../jwx/v3/jwt/token_options_gen.go | 25 + .../lestrrat-go/jwx/v3/jwt/validate.go | 418 + vendor/github.com/lestrrat-go/jwx/v3/jwx.go | 45 + .../github.com/lestrrat-go/jwx/v3/options.go | 30 + .../lestrrat-go/jwx/v3/transform/BUILD.bazel | 32 + .../lestrrat-go/jwx/v3/transform/filter.go | 115 + .../lestrrat-go/jwx/v3/transform/map.go | 46 + .../github.com/lestrrat-go/option/.gitignore | 15 + vendor/github.com/lestrrat-go/option/LICENSE | 21 + .../github.com/lestrrat-go/option/README.md | 245 + .../github.com/lestrrat-go/option/option.go | 38 + .../lestrrat-go/option/v2/.gitignore | 15 + .../github.com/lestrrat-go/option/v2/LICENSE | 21 + .../lestrrat-go/option/v2/README.md | 245 + .../lestrrat-go/option/v2/option.go | 47 + .../github.com/lestrrat-go/option/v2/set.go | 92 + .../letsencrypt/boulder/LICENSE.txt | 375 - .../letsencrypt/boulder/core/challenges.go | 41 - .../letsencrypt/boulder/core/interfaces.go | 14 - .../letsencrypt/boulder/core/objects.go | 505 - .../letsencrypt/boulder/core/util.go | 383 - .../letsencrypt/boulder/goodkey/blocked.go | 95 - .../letsencrypt/boulder/goodkey/good_key.go | 460 - .../letsencrypt/boulder/goodkey/weak.go | 66 - .../boulder/identifier/identifier.go | 32 - .../letsencrypt/boulder/probs/probs.go | 343 - .../letsencrypt/boulder/revocation/reasons.go | 72 - .../letsencrypt/boulder/strictyaml/yaml.go | 46 - .../lucasb-eyer/go-colorful/CHANGELOG.md | 24 + .../lucasb-eyer/go-colorful/README.md | 39 +- .../lucasb-eyer/go-colorful/colorgens.go | 36 +- .../lucasb-eyer/go-colorful/colors.go | 221 +- .../go-colorful/happy_palettegen.go | 18 +- .../lucasb-eyer/go-colorful/hexcolor.go | 20 + .../lucasb-eyer/go-colorful/hsluv.go | 5 +- .../lucasb-eyer/go-colorful/rand.go | 22 + .../go-colorful/soft_palettegen.go | 17 +- .../lucasb-eyer/go-colorful/sort.go | 191 + .../go-colorful/warm_palettegen.go | 18 +- vendor/github.com/mailru/easyjson/.gitignore | 6 - vendor/github.com/mailru/easyjson/LICENSE | 7 - vendor/github.com/mailru/easyjson/Makefile | 76 - vendor/github.com/mailru/easyjson/README.md | 408 - .../github.com/mailru/easyjson/buffer/pool.go | 278 - vendor/github.com/mailru/easyjson/helpers.go | 114 - .../mailru/easyjson/jlexer/bytestostr.go | 21 - .../easyjson/jlexer/bytestostr_nounsafe.go | 13 - .../mailru/easyjson/jlexer/error.go | 15 - .../mailru/easyjson/jlexer/lexer.go | 1257 -- .../mailru/easyjson/jwriter/writer.go | 417 - vendor/github.com/mailru/easyjson/raw.go | 46 - .../mailru/easyjson/unknown_fields.go | 32 - .../github.com/mattn/go-runewidth/README.md | 27 - .../mattn/go-runewidth/runewidth.go | 358 - .../mattn/go-runewidth/runewidth_appengine.go | 9 - .../mattn/go-runewidth/runewidth_js.go | 9 - .../mattn/go-runewidth/runewidth_posix.go | 81 - .../mattn/go-runewidth/runewidth_table.go | 450 - .../mattn/go-runewidth/runewidth_windows.go | 28 - .../mitchellh/mapstructure/CHANGELOG.md | 101 - .../mitchellh/mapstructure/README.md | 46 - .../mitchellh/mapstructure/decode_hooks.go | 283 - .../mitchellh/mapstructure/error.go | 50 - .../mitchellh/mapstructure/mapstructure.go | 1542 -- vendor/github.com/moby/term/.gitignore | 8 + vendor/github.com/moby/term/LICENSE | 191 + vendor/github.com/moby/term/README.md | 36 + vendor/github.com/moby/term/ascii.go | 66 + vendor/github.com/moby/term/doc.go | 3 + vendor/github.com/moby/term/proxy.go | 88 + vendor/github.com/moby/term/term.go | 85 + vendor/github.com/moby/term/term_unix.go | 98 + vendor/github.com/moby/term/term_windows.go | 176 + vendor/github.com/moby/term/termios_bsd.go | 13 + vendor/github.com/moby/term/termios_nonbsd.go | 13 + vendor/github.com/moby/term/termios_unix.go | 35 + .../github.com/moby/term/termios_windows.go | 37 + .../moby/term/windows/ansi_reader.go | 252 + .../moby/term/windows/ansi_writer.go | 57 + .../github.com/moby/term/windows/console.go | 43 + vendor/github.com/moby/term/windows/doc.go | 5 + .../muesli/termenv/.golangci-soft.yml | 6 +- .../github.com/muesli/termenv/.golangci.yml | 1 - vendor/github.com/muesli/termenv/README.md | 246 +- .../github.com/muesli/termenv/ansi_compat.md | 17 + .../github.com/muesli/termenv/ansicolors.go | 2 +- vendor/github.com/muesli/termenv/color.go | 99 +- .../muesli/termenv/constants_zos.go | 8 + vendor/github.com/muesli/termenv/copy.go | 37 + vendor/github.com/muesli/termenv/hyperlink.go | 11 + .../github.com/muesli/termenv/notification.go | 11 + vendor/github.com/muesli/termenv/output.go | 205 + vendor/github.com/muesli/termenv/profile.go | 112 + vendor/github.com/muesli/termenv/screen.go | 442 +- vendor/github.com/muesli/termenv/style.go | 11 +- .../muesli/termenv/templatehelper.go | 59 +- vendor/github.com/muesli/termenv/termenv.go | 92 +- .../muesli/termenv/termenv_other.go | 18 +- .../muesli/termenv/termenv_posix.go | 4 +- .../github.com/muesli/termenv/termenv_unix.go | 147 +- .../muesli/termenv/termenv_windows.go | 63 +- .../opa/capabilities/v1.10.0.json | 4867 ++++++ .../opa/capabilities/v1.10.1.json | 4867 ++++++ .../opa/capabilities/v1.6.0.json | 4850 ++++++ .../opa/capabilities/v1.7.0.json | 4850 ++++++ .../opa/capabilities/v1.8.0.json | 4867 ++++++ .../opa/capabilities/v1.9.0.json | 4867 ++++++ .../opa/internal/bundle/utils.go | 2 +- .../opa/internal/config/config.go | 18 +- .../opa/internal/edittree/edittree.go | 83 +- .../opa/internal/future/filter_imports.go | 6 +- .../opa/internal/jwx/buffer/buffer.go | 112 - .../opa/internal/jwx/jwa/elliptic.go | 11 - .../opa/internal/jwx/jwa/key_type.go | 67 - .../opa/internal/jwx/jwa/parameters.go | 29 - .../opa/internal/jwx/jwa/signature.go | 78 - .../opa/internal/jwx/jwk/ecdsa.go | 120 - .../opa/internal/jwx/jwk/headers.go | 178 - .../opa/internal/jwx/jwk/interface.go | 71 - .../opa/internal/jwx/jwk/jwk.go | 153 - .../opa/internal/jwx/jwk/key_ops.go | 67 - .../opa/internal/jwx/jwk/rsa.go | 133 - .../opa/internal/jwx/jwk/symmetric.go | 41 - .../opa/internal/jwx/jws/headers.go | 154 - .../opa/internal/jwx/jws/interface.go | 22 - .../opa/internal/jwx/jws/jws.go | 220 - .../opa/internal/jwx/jws/message.go | 26 - .../opa/internal/jwx/jws/sign/ecdsa.go | 90 - .../opa/internal/jwx/jws/sign/hmac.go | 66 - .../opa/internal/jwx/jws/sign/interface.go | 46 - .../opa/internal/jwx/jws/sign/rsa.go | 97 - .../opa/internal/jwx/jws/sign/sign.go | 66 - .../opa/internal/jwx/jws/verify/ecdsa.go | 67 - .../opa/internal/jwx/jws/verify/hmac.go | 33 - .../opa/internal/jwx/jws/verify/interface.go | 39 - .../opa/internal/jwx/jws/verify/rsa.go | 88 - .../opa/internal/jwx/jws/verify/verify.go | 56 - .../opa/internal/report/report.go | 118 +- .../opa/internal/runtime/init/init.go | 12 +- .../opa/internal/semver/semver.go | 15 + .../opa/v1/ast/annotations.go | 90 +- .../open-policy-agent/opa/v1/ast/builtins.go | 453 +- .../opa/v1/ast/capabilities.go | 42 +- .../open-policy-agent/opa/v1/ast/check.go | 16 +- .../open-policy-agent/opa/v1/ast/compare.go | 193 +- .../open-policy-agent/opa/v1/ast/compile.go | 491 +- .../opa/v1/ast/default_module_loader.go | 14 + .../open-policy-agent/opa/v1/ast/index.go | 58 +- .../opa/v1/ast/internal/scanner/scanner.go | 5 + .../open-policy-agent/opa/v1/ast/interning.go | 1948 ++- .../open-policy-agent/opa/v1/ast/parser.go | 327 +- .../opa/v1/ast/parser_ext.go | 2 +- .../opa/v1/ast/performance.go | 85 + .../open-policy-agent/opa/v1/ast/policy.go | 14 +- .../opa/v1/ast/rego_compiler.go | 17 + .../open-policy-agent/opa/v1/ast/rego_v1.go | 2 +- .../open-policy-agent/opa/v1/ast/syncpools.go | 23 + .../open-policy-agent/opa/v1/ast/term.go | 566 +- .../open-policy-agent/opa/v1/ast/unify.go | 35 +- .../open-policy-agent/opa/v1/ast/varset.go | 14 +- .../opa/v1/ast/version_index.json | 14 + .../open-policy-agent/opa/v1/ast/visit.go | 105 +- .../open-policy-agent/opa/v1/bundle/bundle.go | 100 +- .../open-policy-agent/opa/v1/bundle/file.go | 2 +- .../open-policy-agent/opa/v1/bundle/keys.go | 59 +- .../open-policy-agent/opa/v1/bundle/sign.go | 58 +- .../open-policy-agent/opa/v1/bundle/store.go | 134 +- .../open-policy-agent/opa/v1/bundle/verify.go | 120 +- .../open-policy-agent/opa/v1/config/config.go | 215 +- .../open-policy-agent/opa/v1/format/format.go | 198 +- .../open-policy-agent/opa/v1/hooks/hooks.go | 22 +- .../open-policy-agent/opa/v1/loader/loader.go | 59 +- .../opa/v1/logging/logging.go | 11 + .../opa/v1/metrics/metrics.go | 108 +- .../opa/v1/plugins/plugins.go | 137 +- .../opa/v1/plugins/rest/auth.go | 65 +- .../open-policy-agent/opa/v1/rego/rego.go | 154 +- .../opa/v1/resolver/wasm/wasm.go | 2 +- .../opa/v1/storage/inmem/ast.go | 23 +- .../opa/v1/storage/inmem/inmem.go | 66 +- .../opa/v1/storage/inmem/txn.go | 198 +- .../opa/v1/storage/interface.go | 5 + .../opa/v1/storage/internal/errors/errors.go | 31 +- .../opa/v1/storage/internal/ptr/ptr.go | 51 +- .../open-policy-agent/opa/v1/storage/path.go | 54 +- .../opa/v1/storage/storage.go | 3 + .../opa/v1/topdown/aggregates.go | 44 +- .../opa/v1/topdown/arithmetic.go | 8 +- .../opa/v1/topdown/builtins/builtins.go | 2 +- .../opa/v1/topdown/cache/cache.go | 77 + .../open-policy-agent/opa/v1/topdown/casts.go | 6 +- .../open-policy-agent/opa/v1/topdown/cidr.go | 14 +- .../opa/v1/topdown/comparison.go | 2 +- .../copypropagation/copypropagation.go | 8 +- .../opa/v1/topdown/crypto.go | 18 +- .../opa/v1/topdown/encoding.go | 16 +- .../open-policy-agent/opa/v1/topdown/eval.go | 132 +- .../open-policy-agent/opa/v1/topdown/glob.go | 2 +- .../opa/v1/topdown/graphql.go | 26 +- .../open-policy-agent/opa/v1/topdown/http.go | 53 +- .../opa/v1/topdown/jsonschema.go | 2 +- .../opa/v1/topdown/numbers.go | 57 +- .../open-policy-agent/opa/v1/topdown/query.go | 6 +- .../open-policy-agent/opa/v1/topdown/regex.go | 14 +- .../opa/v1/topdown/runtime.go | 2 +- .../opa/v1/topdown/semver.go | 6 +- .../opa/v1/topdown/strings.go | 176 +- .../opa/v1/topdown/subset.go | 8 +- .../open-policy-agent/opa/v1/topdown/time.go | 8 +- .../opa/v1/topdown/tokens.go | 290 +- .../open-policy-agent/opa/v1/topdown/trace.go | 4 +- .../open-policy-agent/opa/v1/topdown/type.go | 28 +- .../opa/v1/topdown/type_name.go | 14 +- .../open-policy-agent/opa/v1/topdown/walk.go | 4 +- .../open-policy-agent/opa/v1/types/types.go | 37 +- .../open-policy-agent/opa/v1/util/backoff.go | 2 + .../open-policy-agent/opa/v1/util/json.go | 78 +- .../opa/v1/util/performance.go | 69 + .../opa/v1/util/read_gzip_body.go | 59 +- .../opa/v1/version/version.go | 2 +- .../opentracing/opentracing-go/.gitignore | 1 - .../opentracing/opentracing-go/.travis.yml | 20 - .../opentracing/opentracing-go/CHANGELOG.md | 63 - .../opentracing/opentracing-go/Makefile | 20 - .../opentracing/opentracing-go/README.md | 171 - .../opentracing/opentracing-go/ext.go | 24 - .../opentracing/opentracing-go/ext/field.go | 17 - .../opentracing/opentracing-go/ext/tags.go | 215 - .../opentracing-go/globaltracer.go | 42 - .../opentracing/opentracing-go/gocontext.go | 65 - .../opentracing/opentracing-go/log/field.go | 282 - .../opentracing/opentracing-go/log/util.go | 61 - .../opentracing/opentracing-go/noop.go | 64 - .../opentracing/opentracing-go/propagation.go | 176 - .../opentracing/opentracing-go/span.go | 189 - .../opentracing/opentracing-go/tracer.go | 304 - vendor/github.com/pkg/browser/LICENSE | 23 + vendor/github.com/pkg/browser/README.md | 55 + vendor/github.com/pkg/browser/browser.go | 57 + .../github.com/pkg/browser/browser_darwin.go | 5 + .../github.com/pkg/browser/browser_freebsd.go | 14 + .../github.com/pkg/browser/browser_linux.go | 21 + .../github.com/pkg/browser/browser_netbsd.go | 14 + .../github.com/pkg/browser/browser_openbsd.go | 14 + .../pkg/browser/browser_unsupported.go | 12 + .../github.com/pkg/browser/browser_windows.go | 7 + .../prometheus/common/expfmt/decode.go | 14 +- .../common/expfmt/openmetrics_create.go | 59 +- .../prometheus/common/expfmt/text_create.go | 58 +- .../prometheus/common/expfmt/text_parse.go | 102 +- .../protocolbuffers/txtpbfmt/ast/ast.go | 139 +- .../protocolbuffers/txtpbfmt/config/config.go | 119 + .../txtpbfmt/descriptor/descriptor.go | 83 + .../protocolbuffers/txtpbfmt/impl/impl.go | 1081 ++ .../protocolbuffers/txtpbfmt/logger/logger.go | 8 + .../protocolbuffers/txtpbfmt/parser/parser.go | 1779 +- .../txtpbfmt/printer/printer.go | 347 + .../protocolbuffers/txtpbfmt/quote/quote.go | 56 + .../protocolbuffers/txtpbfmt/sort/sort.go | 251 + .../txtpbfmt/unquote/unquote.go | 88 +- .../protocolbuffers/txtpbfmt/wrap/wrap.go | 267 + .../github.com/rcrowley/go-metrics/README.md | 9 + .../rogpeppe/go-internal/robustio/robustio.go | 53 - .../go-internal/robustio/robustio_darwin.go | 21 - .../go-internal/robustio/robustio_windows.go | 28 - .../signerverifier/utils.go | 10 - vendor/github.com/segmentio/asm/LICENSE | 21 + .../github.com/segmentio/asm/base64/base64.go | 67 + .../segmentio/asm/base64/base64_amd64.go | 78 + .../segmentio/asm/base64/base64_arm64.go | 42 + .../segmentio/asm/base64/base64_asm.go | 94 + .../segmentio/asm/base64/base64_default.go | 14 + .../segmentio/asm/base64/decode_amd64.go | 9 + .../segmentio/asm/base64/decode_amd64.s | 143 + .../segmentio/asm/base64/decode_arm64.go | 7 + .../segmentio/asm/base64/decode_arm64.s | 203 + .../segmentio/asm/base64/encode_amd64.go | 7 + .../segmentio/asm/base64/encode_amd64.s | 87 + .../segmentio/asm/base64/encode_arm64.go | 6 + .../segmentio/asm/base64/encode_arm64.s | 97 + .../github.com/segmentio/asm/cpu/arm/arm.go | 80 + .../segmentio/asm/cpu/arm64/arm64.go | 74 + vendor/github.com/segmentio/asm/cpu/cpu.go | 22 + .../segmentio/asm/cpu/cpuid/cpuid.go | 32 + .../github.com/segmentio/asm/cpu/x86/x86.go | 76 + .../asm/internal/unsafebytes/unsafebytes.go | 20 + vendor/github.com/segmentio/ksuid/README.md | 234 - vendor/github.com/segmentio/ksuid/base62.go | 202 - vendor/github.com/segmentio/ksuid/ksuid.go | 352 - vendor/github.com/segmentio/ksuid/rand.go | 55 - vendor/github.com/segmentio/ksuid/sequence.go | 55 - vendor/github.com/segmentio/ksuid/set.go | 343 - vendor/github.com/segmentio/ksuid/uint128.go | 141 - .../cosign/v2/cmd/cosign/cli/fulcio/fulcio.go | 127 +- .../v2/cmd/cosign/cli/options/attest.go | 20 + .../v2/cmd/cosign/cli/options/attest_blob.go | 26 +- .../cosign/v2/cmd/cosign/cli/options/key.go | 13 + .../v2/cmd/cosign/cli/options/predicate.go | 10 +- .../cosign/v2/cmd/cosign/cli/options/sign.go | 19 + .../v2/cmd/cosign/cli/options/signblob.go | 16 + .../cmd/cosign/cli/options/signingconfig.go | 49 + .../cosign/v2/cmd/cosign/cli/options/tree.go | 10 +- .../v2/cmd/cosign/cli/options/trustedroot.go | 36 + .../v2/cmd/cosign/cli/options/verify.go | 19 +- .../cosign/v2/cmd/cosign/cli/sign/sign.go | 230 +- .../v2/cmd/cosign/cli/sign/sign_blob.go | 183 +- .../cosign/v2/cmd/cosign/cli/verify/verify.go | 127 +- .../cosign/cli/verify/verify_attestation.go | 30 +- .../v2/cmd/cosign/cli/verify/verify_blob.go | 8 +- .../cli/verify/verify_blob_attestation.go | 81 +- .../sigstore/cosign/v2/internal/auth/auth.go | 172 + .../cosign/v2/internal/key/svkeypair.go | 137 + .../cosign/v2/internal/pkg/cosign/common.go | 17 +- .../sigstore/cosign/v2/internal/ui/spinner.go | 66 + .../v2/pkg/cosign/bundle/protobundle.go | 68 + .../cosign/v2/pkg/cosign/bundle/sign.go | 132 + .../cosign/v2/pkg/cosign/git/github/github.go | 2 +- .../sigstore/cosign/v2/pkg/cosign/keys.go | 83 +- .../sigstore/cosign/v2/pkg/cosign/tlog.go | 63 +- .../sigstore/cosign/v2/pkg/cosign/tsa.go | 15 + .../sigstore/cosign/v2/pkg/cosign/tuf.go | 12 + .../sigstore/cosign/v2/pkg/cosign/verify.go | 37 +- .../cosign/v2/pkg/oci/remote/remote.go | 11 +- .../cosign/v2/pkg/oci/remote/write.go | 125 +- .../sigstore/cosign/v2/pkg/signature/keys.go | 14 +- .../sigstore/cosign/v2/pkg/types/media.go | 2 +- .../sigstore/cosign/v2/pkg/types/payload.go | 2 +- .../sigstore/cosign/v2/pkg/types/predicate.go | 20 + .../trustroot/v1/sigstore_trustroot.pb.go | 275 +- .../sigstore/rekor-tiles/v2/COPYRIGHT.txt | 13 + .../rekor-tiles/v2}/LICENSE | 4 +- .../v2/internal/safeint/safeint.go | 68 + .../rekor-tiles/v2/pkg/client/option.go | 41 + .../rekor-tiles/v2/pkg/client/transport.go | 47 + .../rekor-tiles/v2/pkg/client/write/write.go | 130 + .../v2/pkg/generated/protobuf/dsse.pb.go | 248 + .../v2/pkg/generated/protobuf/entry.pb.go | 395 + .../pkg/generated/protobuf/hashedrekord.pb.go | 243 + .../generated/protobuf/rekor_service.pb.go | 287 + .../generated/protobuf/rekor_service.pb.gw.go | 381 + .../protobuf/rekor_service_grpc.pb.go | 266 + .../v2/pkg/generated/protobuf/verifier.pb.go | 338 + .../sigstore/rekor-tiles/v2/pkg/note/note.go | 219 + .../v2/pkg/types/verifier/verifier.go | 41 + .../rekor-tiles/v2/pkg/verify/verify.go | 89 + .../entries/create_log_entry_responses.go | 11 +- .../client/entries/entries_client.go | 44 +- .../get_log_entry_by_index_responses.go | 7 +- .../get_log_entry_by_uuid_responses.go | 7 +- .../entries/search_log_query_responses.go | 11 +- .../generated/client/index/index_client.go | 11 +- .../client/index/search_index_responses.go | 9 +- .../client/pubkey/get_public_key_responses.go | 7 +- .../generated/client/pubkey/pubkey_client.go | 11 +- .../client/tlog/get_log_info_parameters.go | 49 +- .../client/tlog/get_log_info_responses.go | 7 +- .../client/tlog/get_log_proof_responses.go | 9 +- .../pkg/generated/client/tlog/tlog_client.go | 22 +- .../pkg/generated/models/alpine_schema.go | 2 +- .../generated/models/alpine_v001_schema.go | 51 +- .../rekor/pkg/generated/models/cose_schema.go | 2 +- .../pkg/generated/models/cose_v001_schema.go | 53 +- .../rekor/pkg/generated/models/dsse_schema.go | 2 +- .../pkg/generated/models/dsse_v001_schema.go | 71 +- .../generated/models/hashedrekord_schema.go | 2 +- .../models/hashedrekord_v001_schema.go | 67 +- .../rekor/pkg/generated/models/helm_schema.go | 2 +- .../pkg/generated/models/helm_v001_schema.go | 87 +- .../pkg/generated/models/intoto_schema.go | 2 +- .../generated/models/intoto_v001_schema.go | 53 +- .../generated/models/intoto_v002_schema.go | 85 +- .../rekor/pkg/generated/models/jar_schema.go | 2 +- .../pkg/generated/models/jar_v001_schema.go | 71 +- .../rekor/pkg/generated/models/log_entry.go | 59 +- .../rekor/pkg/generated/models/log_info.go | 17 +- .../pkg/generated/models/rekord_schema.go | 2 +- .../generated/models/rekord_v001_schema.go | 69 +- .../pkg/generated/models/rfc3161_schema.go | 2 +- .../generated/models/rfc3161_v001_schema.go | 17 +- .../rekor/pkg/generated/models/rpm_schema.go | 2 +- .../pkg/generated/models/rpm_v001_schema.go | 51 +- .../pkg/generated/models/search_index.go | 21 +- .../pkg/generated/models/search_log_query.go | 19 +- .../rekor/pkg/generated/models/tuf_schema.go | 2 +- .../pkg/generated/models/tuf_v001_schema.go | 39 +- .../sigstore/rekor/pkg/internal/log/logger.go | 36 + .../github.com/sigstore/rekor/pkg/log/log.go | 4 +- .../github.com/sigstore/rekor/pkg/pki/pki.go | 20 +- .../sigstore/rekor/pkg/pki/pkitypes/types.go | 40 + .../sigstore/rekor/pkg/pki/x509/e2e.go | 193 - .../rekor/pkg/types/dsse/v0.0.1/entry.go | 129 +- .../sigstore/rekor/pkg/types/entries.go | 10 +- .../pkg/types/hashedrekord/v0.0.1/entry.go | 100 +- .../sigstore/rekor/pkg/types/intoto/intoto.go | 8 +- .../rekor/pkg/types/intoto/v0.0.1/entry.go | 101 +- .../rekor/pkg/types/intoto/v0.0.2/entry.go | 157 +- .../rekor/pkg/types/rekord/v0.0.1/entry.go | 244 +- .../sigstore/rekor/pkg/types/test_util.go | 4 +- .../sigstore/rekor/pkg/types/types.go | 18 +- .../sigstore/rekor/pkg/types/versionmap.go | 2 +- .../sigstore/rekor/pkg/util/util.go | 446 - .../sigstore/rekor/pkg/verify/verify.go | 12 +- .../sigstore/sigstore-go/pkg/bundle/bundle.go | 2 +- .../sigstore-go/pkg/root/signing_config.go | 115 +- .../pkg/root/timestamping_authority.go | 9 +- .../sigstore-go/pkg/root/trusted_root.go | 59 +- .../sigstore-go/pkg/sign/certificate.go | 236 + .../sigstore/sigstore-go/pkg/sign/content.go | 74 + .../sigstore/sigstore-go/pkg/sign/keys.go | 181 + .../sigstore/sigstore-go/pkg/sign/signer.go | 188 + .../sigstore-go/pkg/sign/timestamping.go | 126 + .../sigstore-go/pkg/sign/transparency.go | 280 + .../sigstore/sigstore-go/pkg/tlog/entry.go | 367 +- .../sigstore/sigstore-go/pkg/tuf/client.go | 4 +- .../sigstore/sigstore-go/pkg/tuf/options.go | 5 +- .../sigstore-go/pkg/tuf/repository/root.json | 44 +- .../pkg/tuf/repository/staging_root.json | 8 +- .../sigstore/sigstore-go/pkg/util/util.go | 2 +- .../sigstore-go/pkg/verify/signed_entity.go | 36 +- .../sigstore/sigstore-go/pkg/verify/tlog.go | 42 +- .../sigstore/pkg/cryptoutils/publickey.go | 62 +- .../sigstore/pkg/cryptoutils/safestring.go | 34 + .../sigstore/sigstore/pkg/cryptoutils/sans.go | 3 + .../sigstore/pkg/oauthflow/interactive.go | 18 +- .../sigstore/sigstore/pkg/oauthflow/pkce.go | 6 +- .../sigstore/pkg/signature/message.go | 8 +- .../sigstore/sigstore/pkg/signature/signer.go | 3 - .../pkg/verification/verify.go | 13 +- .../timestamp-authority/v2/CONTRIBUTORS.md | 132 + .../timestamp-authority/v2/COPYRIGHT.txt | 13 + .../sigstore/timestamp-authority/v2/LICENSE | 201 + .../v2/pkg/verification/verify.go | 340 + .../v2/pkg/verification/verify_request.go | 47 + .../sirupsen/logrus/terminal_check_bsd.go | 2 +- .../sirupsen/logrus/terminal_check_unix.go | 2 + .../sirupsen/logrus/terminal_check_wasi.go | 8 + .../sirupsen/logrus/terminal_check_wasip1.go | 8 + .../github.com/skratchdot/open-golang/LICENSE | 22 - .../skratchdot/open-golang/open/exec.go | 18 - .../open-golang/open/exec_darwin.go | 15 - .../open-golang/open/exec_windows.go | 33 - .../skratchdot/open-golang/open/open.go | 50 - .../tchap/go-patricia/v2/patricia/patricia.go | 2 +- .../go-tuf/v2/metadata/updater/updater.go | 4 +- vendor/github.com/titanous/rocacheck/LICENSE | 22 - .../github.com/titanous/rocacheck/README.md | 7 - .../titanous/rocacheck/rocacheck.go | 52 - .../transparency-dev/formats/LICENSE | 202 + .../transparency-dev/formats/log/README.md | 127 + .../formats/log/checkpoint.go | 79 + .../formats/log/identifier.go | 30 + .../transparency-dev/formats/log/note.go | 56 + vendor/github.com/valyala/fastjson/.gitignore | 1 + .../github.com/valyala/fastjson/.travis.yml | 19 + .../go-runewidth => valyala/fastjson}/LICENSE | 3 +- vendor/github.com/valyala/fastjson/README.md | 227 + vendor/github.com/valyala/fastjson/arena.go | 126 + vendor/github.com/valyala/fastjson/doc.go | 9 + .../valyala/fastjson/fastfloat/parse.go | 515 + vendor/github.com/valyala/fastjson/fuzz.go | 22 + vendor/github.com/valyala/fastjson/handy.go | 170 + vendor/github.com/valyala/fastjson/parser.go | 976 ++ vendor/github.com/valyala/fastjson/pool.go | 52 + vendor/github.com/valyala/fastjson/scanner.go | 94 + vendor/github.com/valyala/fastjson/update.go | 110 + vendor/github.com/valyala/fastjson/util.go | 30 + .../github.com/valyala/fastjson/validate.go | 308 + .../vbatts/tar-split/archive/tar/common.go | 1 + .../vbatts/tar-split/archive/tar/reader.go | 9 +- .../vektah/gqlparser/v2/gqlerror/error.go | 9 + .../vektah/gqlparser/v2/parser/parser.go | 3 +- .../gqlparser/v2/validator/core/core.go | 24 + .../gqlparser/v2/validator/core/helpers.go | 154 + .../gqlparser/v2/validator/{ => core}/walk.go | 2 +- .../vektah/gqlparser/v2/validator/error.go | 55 - .../gqlparser/v2/validator/messaging.go | 39 - .../validator/rules/fields_on_correct_type.go | 6 +- .../rules/fragments_on_composite_types.go | 6 +- .../validator/rules/known_argument_names.go | 6 +- .../v2/validator/rules/known_directives.go | 6 +- .../validator/rules/known_fragment_names.go | 6 +- .../v2/validator/rules/known_root_type.go | 6 +- .../v2/validator/rules/known_type_names.go | 6 +- .../rules/lone_anonymous_operation.go | 6 +- .../rules/max_introspection_depth.go | 6 +- .../v2/validator/rules/no_fragment_cycles.go | 6 +- .../validator/rules/no_undefined_variables.go | 6 +- .../v2/validator/rules/no_unused_fragments.go | 6 +- .../v2/validator/rules/no_unused_variables.go | 6 +- .../rules/overlapping_fields_can_be_merged.go | 6 +- .../rules/possible_fragment_spreads.go | 6 +- .../rules/provided_required_arguments.go | 6 +- .../gqlparser/v2/validator/rules/rules.go | 119 + .../v2/validator/rules/scalar_leafs.go | 6 +- .../rules/single_field_subscriptions.go | 6 +- .../validator/rules/unique_argument_names.go | 6 +- .../rules/unique_directives_per_location.go | 6 +- .../validator/rules/unique_fragment_names.go | 6 +- .../rules/unique_input_field_names.go | 6 +- .../validator/rules/unique_operation_names.go | 6 +- .../validator/rules/unique_variable_names.go | 6 +- .../validator/rules/values_of_correct_type.go | 6 +- .../rules/variables_are_input_types.go | 6 +- .../rules/variables_in_allowed_position.go | 6 +- .../gqlparser/v2/validator/suggestionList.go | 69 - .../gqlparser/v2/validator/validator.go | 77 +- .../gitlab-org/api/client-go/.gitlab-ci.yml | 69 +- .../gitlab-org/api/client-go/.golangci.yml | 8 + .../gitlab-org/api/client-go/.releaserc.json | 20 +- .../gitlab-org/api/client-go/.tool-versions | 2 +- .../gitlab-org/api/client-go/AGENTS.md | 384 + .../gitlab-org/api/client-go/CHANGELOG.md | 301 + .../gitlab-org/api/client-go/CONTRIBUTING.md | 10 +- .../gitlab-org/api/client-go/README.md | 44 +- .../api/client-go/access_requests.go | 79 +- .../api/client-go/alert_management.go | 35 +- .../gitlab-org/api/client-go/appearance.go | 23 +- .../api/client-go/application_statistics.go | 8 +- .../gitlab-org/api/client-go/applications.go | 28 +- .../gitlab-org/api/client-go/audit_events.go | 53 +- .../gitlab-org/api/client-go/avatar.go | 8 +- .../gitlab-org/api/client-go/award_emojis.go | 227 +- .../gitlab-org/api/client-go/boards.go | 84 +- .../gitlab-org/api/client-go/branches.go | 45 +- .../api/client-go/broadcast_messages.go | 44 +- .../gitlab-org/api/client-go/buf.gen.yaml | 2 +- .../gitlab-org/api/client-go/bulk_imports.go | 3 - .../api/client-go/ci_yml_templates.go | 17 +- .../api/client-go/cluster_agents.go | 138 +- .../gitlab-org/api/client-go/commits.go | 116 +- .../api/client-go/container_registry.go | 72 +- .../container_registry_protection_rules.go | 43 +- .../api/client-go/custom_attributes.go | 107 +- .../api/client-go/database_migrations.go | 12 +- .../gitlab-org/api/client-go/dependencies.go | 12 +- .../api/client-go/dependency_list_export.go | 56 +- .../api/client-go/dependency_proxy.go | 10 +- .../gitlab-org/api/client-go/deploy_keys.go | 86 +- .../gitlab-org/api/client-go/deploy_tokens.go | 80 +- .../gitlab-org/api/client-go/deployments.go | 59 +- .../client-go/deployments_merge_requests.go | 9 +- .../gitlab-org/api/client-go/discussions.go | 292 +- .../api/client-go/dockerfile_templates.go | 17 +- .../gitlab-org/api/client-go/dora_metrics.go | 21 +- .../gitlab-org/api/client-go/draft_notes.go | 65 +- .../api/client-go/enterprise_users.go | 57 +- .../gitlab-org/api/client-go/environments.go | 59 +- .../gitlab-org/api/client-go/epic_issues.go | 43 +- .../gitlab-org/api/client-go/epics.go | 51 +- .../api/client-go/error_tracking.go | 46 +- .../gitlab-org/api/client-go/event_parsing.go | 2 +- .../api/client-go/event_webhook_types.go | 14 +- .../gitlab-org/api/client-go/events.go | 22 +- .../api/client-go/external_status_checks.go | 135 +- .../gitlab-org/api/client-go/gitlab.go | 102 +- .../gitlab-org/api/client-go/graphql.go | 3 +- .../gitlab-org/api/client-go/group_hooks.go | 2 +- .../gitlab-org/api/client-go/group_members.go | 6 +- .../api/client-go/group_relations_export.go | 145 + .../api/client-go/group_security_settings.go | 4 +- .../api/client-go/group_ssh_certificates.go | 6 +- .../gitlab-org/api/client-go/group_wikis.go | 2 +- .../gitlab-org/api/client-go/integrations.go | 213 +- .../api/client-go/job_token_scope.go | 1 + .../gitlab-org/api/client-go/markdown.go | 6 +- .../api/client-go/markdown_uploads.go | 4 +- .../gitlab-org/api/client-go/member_roles.go | 12 +- .../merge_request_context_commits.go | 116 + .../api/client-go/merge_requests.go | 36 +- .../gitlab-org/api/client-go/merge_trains.go | 4 +- .../api/client-go/model_registry.go | 61 + .../gitlab-org/api/client-go/notifications.go | 2 +- .../gitlab-org/api/client-go/pagination.go | 1 - .../api/client-go/pipeline_schedules.go | 2 +- .../api/client-go/pipeline_triggers.go | 4 + .../gitlab-org/api/client-go/pipelines.go | 125 + .../api/client-go/project_aliases.go | 121 + .../api/client-go/project_feature_flags.go | 18 +- .../api/client-go/project_members.go | 6 +- .../client-go/project_security_settings.go | 4 +- .../api/client-go/project_statistics.go | 66 + .../gitlab-org/api/client-go/projects.go | 50 +- .../api/client-go/protected_branches.go | 2 +- .../api/client-go/protected_packages.go | 165 + .../gitlab-org/api/client-go/repositories.go | 4 +- .../api/client-go/request_handler.go | 130 + .../gitlab-org/api/client-go/services.go | 2 +- .../gitlab-org/api/client-go/strings.go | 2 +- .../api/client-go/terraform_states.go | 4 + .../gitlab-org/api/client-go/todos.go | 2 +- .../gitlab-org/api/client-go/types.go | 11 +- .../gitlab-org/api/client-go/users.go | 4 +- .../gitlab-org/api/client-go/wikis.go | 2 +- .../bson/bsoncodec/default_value_decoders.go | 16 +- .../mongo-driver/bson/bsoncodec/uint_codec.go | 8 +- .../bson/bsonrw/extjson_parser.go | 2 +- .../bson/bsonrw/extjson_wrappers.go | 4 +- .../bson/bsonrw/extjson_writer.go | 20 +- .../mongo-driver/bson/bsonrw/json_scanner.go | 37 +- .../mongo-driver/bson/bsonrw/value_reader.go | 12 +- .../mongo-driver/bson/bsonrw/value_writer.go | 2 +- .../go.mongodb.org/mongo-driver/bson/doc.go | 11 +- .../mongo-driver/bson/primitive/decimal.go | 6 +- .../mongo-driver/bson/raw_value.go | 8 +- .../mongo-driver/bson/registry.go | 18 +- .../mongo-driver/bson/unmarshal.go | 3 + .../mongo-driver/x/bsonx/bsoncore/bsoncore.go | 40 +- .../mongo-driver/x/bsonx/bsoncore/doc.go | 23 +- .../mongo-driver/x/bsonx/bsoncore/element.go | 8 +- .../mongo-driver/x/bsonx/bsoncore/value.go | 13 +- .../auto/sdk/internal/telemetry/id.go | 2 +- .../auto/sdk/internal/telemetry/number.go | 2 +- .../auto/sdk/internal/telemetry/span.go | 70 +- .../auto/sdk/internal/telemetry/status.go | 10 +- .../auto/sdk/internal/telemetry/traces.go | 4 +- .../auto/sdk/internal/telemetry/value.go | 14 +- vendor/go.opentelemetry.io/auto/sdk/span.go | 25 +- vendor/go.opentelemetry.io/auto/sdk/tracer.go | 29 +- .../instrumentation/net/http/otelhttp/LICENSE | 30 + .../net/http/otelhttp/client.go | 4 +- .../net/http/otelhttp/config.go | 3 +- .../net/http/otelhttp/handler.go | 6 +- .../net/http/otelhttp/internal/semconv/env.go | 115 +- .../net/http/otelhttp/internal/semconv/gen.go | 1 - .../otelhttp/internal/semconv/httpconv.go | 4 +- .../http/otelhttp/internal/semconv/util.go | 6 +- .../http/otelhttp/internal/semconv/v1.20.0.go | 273 - .../http/otelhttp/internal/semconvutil/gen.go | 10 - .../otelhttp/internal/semconvutil/httpconv.go | 594 - .../otelhttp/internal/semconvutil/netconv.go | 214 - .../net/http/otelhttp/transport.go | 12 +- .../net/http/otelhttp/version.go | 2 +- vendor/go.opentelemetry.io/otel/sdk/LICENSE | 30 + .../otel/sdk/internal/x/x.go | 4 +- .../otel/sdk/resource/builtin.go | 4 +- .../otel/sdk/resource/container.go | 4 +- .../otel/sdk/resource/env.go | 2 +- .../otel/sdk/resource/host_id.go | 4 +- .../otel/sdk/resource/os.go | 6 +- .../otel/sdk/resource/os_release_unix.go | 6 +- .../otel/sdk/resource/process.go | 18 +- .../otel/sdk/resource/resource.go | 4 +- .../otel/sdk/trace/batch_span_processor.go | 122 +- .../go.opentelemetry.io/otel/sdk/trace/doc.go | 3 + .../otel/sdk/trace/id_generator.go | 4 +- .../otel/sdk/trace/internal/x/README.md | 35 + .../otel/sdk/trace/internal/x/x.go | 63 + .../otel/sdk/trace/provider.go | 40 +- .../otel/sdk/trace/sampling.go | 8 +- .../otel/sdk/trace/simple_span_processor.go | 6 +- .../otel/sdk/trace/snapshot.go | 2 +- .../otel/sdk/trace/span.go | 19 +- .../otel/sdk/trace/tracer.go | 138 +- .../otel/sdk/trace/version.go | 9 - .../go.opentelemetry.io/otel/sdk/version.go | 2 +- .../otel/semconv/internal/v2/http.go | 398 - .../otel/semconv/internal/v2/net.go | 313 - .../otel/semconv/v1.17.0/README.md | 3 - .../otel/semconv/v1.17.0/doc.go | 9 - .../otel/semconv/v1.17.0/event.go | 188 - .../otel/semconv/v1.17.0/exception.go | 9 - .../otel/semconv/v1.17.0/http.go | 10 - .../otel/semconv/v1.17.0/httpconv/README.md | 3 - .../otel/semconv/v1.17.0/httpconv/http.go | 141 - .../otel/semconv/v1.17.0/resource.go | 1999 --- .../otel/semconv/v1.17.0/schema.go | 9 - .../otel/semconv/v1.17.0/trace.go | 3364 ---- .../otel/semconv/v1.20.0/README.md | 3 - .../otel/semconv/v1.20.0/attribute_group.go | 1198 -- .../otel/semconv/v1.20.0/doc.go | 9 - .../otel/semconv/v1.20.0/event.go | 188 - .../otel/semconv/v1.20.0/exception.go | 9 - .../otel/semconv/v1.20.0/http.go | 10 - .../otel/semconv/v1.20.0/resource.go | 2060 --- .../otel/semconv/v1.20.0/schema.go | 9 - .../otel/semconv/v1.20.0/trace.go | 2599 --- .../otel/semconv/v1.26.0/README.md | 3 - .../otel/semconv/v1.26.0/attribute_group.go | 8996 ---------- .../otel/semconv/v1.26.0/doc.go | 9 - .../otel/semconv/v1.26.0/exception.go | 9 - .../otel/semconv/v1.26.0/metric.go | 1307 -- .../otel/semconv/v1.26.0/schema.go | 9 - .../otel/semconv/v1.34.0/MIGRATION.md | 4 - .../otel/semconv/v1.34.0/README.md | 3 - .../otel/semconv/v1.34.0/attribute_group.go | 14061 ---------------- .../otel/semconv/v1.34.0/doc.go | 9 - .../otel/semconv/v1.34.0/error_type.go | 31 - .../otel/semconv/v1.34.0/exception.go | 9 - .../otel/semconv/v1.34.0/schema.go | 9 - .../{v1.34.0 => v1.37.0}/httpconv/metric.go | 309 +- .../otel/semconv/v1.37.0/otelconv/metric.go | 2126 +++ vendor/golang.org/x/crypto/ocsp/ocsp.go | 793 - vendor/golang.org/x/crypto/sha3/hashes.go | 95 - .../golang.org/x/crypto/sha3/legacy_hash.go | 263 - .../x/crypto/sha3/legacy_keccakf.go | 416 - vendor/golang.org/x/crypto/sha3/shake.go | 119 - .../x/exp/constraints/constraints.go | 54 + vendor/golang.org/x/oauth2/deviceauth.go | 31 +- vendor/golang.org/x/oauth2/google/google.go | 2 +- vendor/golang.org/x/oauth2/oauth2.go | 2 +- vendor/golang.org/x/oauth2/pkce.go | 2 +- vendor/golang.org/x/oauth2/token.go | 2 +- vendor/golang.org/x/oauth2/transport.go | 2 +- vendor/golang.org/x/time/rate/rate.go | 2 +- .../google.golang.org/api/internal/version.go | 2 +- .../grpc/balancer/pickfirst/pickfirst.go | 867 +- .../pickfirst/pickfirstleaf/pickfirstleaf.go | 913 - .../grpc/balancer/roundrobin/roundrobin.go | 6 +- .../grpc/balancer_wrapper.go | 9 +- .../grpc_binarylog_v1/binarylog.pb.go | 2 +- vendor/google.golang.org/grpc/clientconn.go | 9 +- .../grpc/credentials/credentials.go | 3 +- .../grpc/encoding/encoding.go | 20 + .../grpc/encoding/internal/internal.go} | 25 +- .../grpc/experimental/stats/metricregistry.go | 33 + .../grpc/experimental/stats/metrics.go | 3 + .../grpc/health/grpc_health_v1/health.pb.go | 2 +- .../grpc/internal/envconfig/envconfig.go | 14 +- .../grpc/internal/envconfig/xds.go | 5 + .../delegatingresolver/delegatingresolver.go | 58 +- .../internal/stats/metrics_recorder_list.go | 10 + .../grpc/internal/stats/stats.go | 70 + .../grpc/internal/transport/client_stream.go | 32 +- .../grpc/internal/transport/controlbuf.go | 80 +- .../grpc/internal/transport/flowcontrol.go | 23 +- .../grpc/internal/transport/handler_server.go | 48 +- .../grpc/internal/transport/http2_client.go | 199 +- .../grpc/internal/transport/http2_server.go | 76 +- .../grpc/internal/transport/http_util.go | 174 +- .../grpc/internal/transport/server_stream.go | 13 +- .../grpc/internal/transport/transport.go | 90 +- .../google.golang.org/grpc/mem/buffer_pool.go | 16 +- .../grpc/mem/buffer_slice.go | 101 +- vendor/google.golang.org/grpc/preloader.go | 3 - vendor/google.golang.org/grpc/rpc_util.go | 16 +- vendor/google.golang.org/grpc/server.go | 100 +- vendor/google.golang.org/grpc/stream.go | 105 +- vendor/google.golang.org/grpc/version.go | 2 +- vendor/modules.txt | 549 +- .../release-utils/version/command.go | 2 + 2243 files changed, 198049 insertions(+), 99610 deletions(-) create mode 100644 vendor/cloud.google.com/go/auth/internal/retry/retry.go create mode 100644 vendor/cloud.google.com/go/auth/internal/transport/headers/headers.go create mode 100644 vendor/cloud.google.com/go/auth/internal/trustboundary/external_accounts_config_providers.go create mode 100644 vendor/cloud.google.com/go/auth/internal/trustboundary/trust_boundary.go create mode 100644 vendor/cloud.google.com/go/auth/internal/version.go delete mode 100644 vendor/cuelang.org/go/cue/ast/astutil/walk.go create mode 100644 vendor/cuelang.org/go/cue/ast/importpath.go create mode 100644 vendor/cuelang.org/go/cue/interpreter/embed/embed.go create mode 100644 vendor/cuelang.org/go/cue/load/modfilecache.go create mode 100644 vendor/cuelang.org/go/encoding/json/pointer.go create mode 100644 vendor/cuelang.org/go/encoding/jsonschema/crd.cue create mode 100644 vendor/cuelang.org/go/encoding/jsonschema/crd.go create mode 100644 vendor/cuelang.org/go/encoding/jsonschema/cue_types_gen.go create mode 100644 vendor/cuelang.org/go/encoding/jsonschema/generate.go create mode 100644 vendor/cuelang.org/go/encoding/jsonschema/generate_items.go delete mode 100644 vendor/cuelang.org/go/encoding/jsonschema/pointer.go delete mode 100644 vendor/cuelang.org/go/encoding/jsonschema/resolveref_v1.22.go delete mode 100644 vendor/cuelang.org/go/encoding/jsonschema/resolveref_v1.23.go create mode 100644 vendor/cuelang.org/go/encoding/xml/koala/decode.go create mode 100644 vendor/cuelang.org/go/internal/anyunique/unique.go create mode 100644 vendor/cuelang.org/go/internal/core/adt/arctype_string.go create mode 100644 vendor/cuelang.org/go/internal/core/adt/call.go delete mode 100644 vendor/cuelang.org/go/internal/core/adt/closed2.go create mode 100644 vendor/cuelang.org/go/internal/core/adt/defidtype_string.go delete mode 100644 vendor/cuelang.org/go/internal/core/adt/dep.go delete mode 100644 vendor/cuelang.org/go/internal/core/adt/depkind_string.go delete mode 100644 vendor/cuelang.org/go/internal/core/adt/dev.go create mode 100644 vendor/cuelang.org/go/internal/core/adt/flags.go create mode 100644 vendor/cuelang.org/go/internal/core/adt/mem.go delete mode 100644 vendor/cuelang.org/go/internal/core/adt/optional.go create mode 100644 vendor/cuelang.org/go/internal/core/adt/typocheck.go create mode 100644 vendor/cuelang.org/go/internal/core/adt/validate.go create mode 100644 vendor/cuelang.org/go/internal/core/format/printer.go create mode 100644 vendor/cuelang.org/go/internal/core/layer/layer.go delete mode 100644 vendor/cuelang.org/go/internal/core/toposort/cycles.go delete mode 100644 vendor/cuelang.org/go/internal/core/validate/validate.go create mode 100644 vendor/cuelang.org/go/internal/cueexperiment/file.go create mode 100644 vendor/cuelang.org/go/internal/cueexperiment/parse.go create mode 100644 vendor/cuelang.org/go/internal/encoding/yaml/validate.go create mode 100644 vendor/cuelang.org/go/internal/filetypes/fileinfo.dat create mode 100644 vendor/cuelang.org/go/internal/filetypes/fromfile.dat create mode 100644 vendor/cuelang.org/go/internal/filetypes/internal/genstruct/gen.go create mode 100644 vendor/cuelang.org/go/internal/filetypes/internal/genstruct/struct.go create mode 100644 vendor/cuelang.org/go/internal/filetypes/internal/internal.go create mode 100644 vendor/cuelang.org/go/internal/filetypes/internal/opt/opt.go create mode 100644 vendor/cuelang.org/go/internal/filetypes/tagtype_string.go create mode 100644 vendor/cuelang.org/go/internal/filetypes/tofile.go create mode 100644 vendor/cuelang.org/go/internal/filetypes/tofile_bootstrap.go create mode 100644 vendor/cuelang.org/go/internal/filetypes/types_gen.go create mode 100644 vendor/cuelang.org/go/internal/filetypes/types_gen.go.tmpl delete mode 100644 vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_flaky.go delete mode 100644 vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_other.go create mode 100644 vendor/cuelang.org/go/internal/iterutil/iter.go create mode 100644 vendor/cuelang.org/go/internal/mod/modfiledata/modfile.go create mode 100644 vendor/cuelang.org/go/internal/robustio/doc.go rename vendor/cuelang.org/go/internal/{golangorgx/tools => }/robustio/gopls_windows.go (100%) rename vendor/cuelang.org/go/internal/{golangorgx/tools => }/robustio/robustio.go (100%) rename vendor/cuelang.org/go/internal/{golangorgx/tools => }/robustio/robustio_darwin.go (100%) rename vendor/{github.com/rogpeppe/go-internal => cuelang.org/go/internal}/robustio/robustio_flaky.go (100%) create mode 100644 vendor/cuelang.org/go/internal/robustio/robustio_js.go rename vendor/{github.com/rogpeppe/go-internal => cuelang.org/go/internal}/robustio/robustio_other.go (100%) rename vendor/cuelang.org/go/internal/{golangorgx/tools => }/robustio/robustio_plan9.go (93%) rename vendor/cuelang.org/go/internal/{golangorgx/tools/robustio/robustio_posix.go => robustio/robustio_unix.go} (81%) rename vendor/cuelang.org/go/internal/{golangorgx/tools => }/robustio/robustio_windows.go (100%) create mode 100644 vendor/cuelang.org/go/internal/tools.mod create mode 100644 vendor/cuelang.org/go/internal/tools.sum create mode 100644 vendor/cuelang.org/go/tools/flow/cycle.go create mode 100644 vendor/cuelang.org/go/tools/flow/flow.go create mode 100644 vendor/cuelang.org/go/tools/flow/run.go create mode 100644 vendor/cuelang.org/go/tools/flow/state_string.go create mode 100644 vendor/cuelang.org/go/tools/flow/tasks.go rename vendor/github.com/{mitchellh/mapstructure => Azure/go-ansiterm}/LICENSE (96%) create mode 100644 vendor/github.com/Azure/go-ansiterm/README.md create mode 100644 vendor/github.com/Azure/go-ansiterm/SECURITY.md create mode 100644 vendor/github.com/Azure/go-ansiterm/constants.go create mode 100644 vendor/github.com/Azure/go-ansiterm/context.go create mode 100644 vendor/github.com/Azure/go-ansiterm/csi_entry_state.go create mode 100644 vendor/github.com/Azure/go-ansiterm/csi_param_state.go create mode 100644 vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go create mode 100644 vendor/github.com/Azure/go-ansiterm/escape_state.go create mode 100644 vendor/github.com/Azure/go-ansiterm/event_handler.go create mode 100644 vendor/github.com/Azure/go-ansiterm/ground_state.go create mode 100644 vendor/github.com/Azure/go-ansiterm/osc_string_state.go create mode 100644 vendor/github.com/Azure/go-ansiterm/parser.go create mode 100644 vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go create mode 100644 vendor/github.com/Azure/go-ansiterm/parser_actions.go create mode 100644 vendor/github.com/Azure/go-ansiterm/states.go create mode 100644 vendor/github.com/Azure/go-ansiterm/utilities.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/ansi.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/api.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/utilities.go create mode 100644 vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/auth_scheme_preference.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/dpop.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/file.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/token.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/CHANGELOG.md rename vendor/github.com/{go-jose/go-jose/v3/LICENSE => aws/aws-sdk-go-v2/service/signin/LICENSE.txt} (100%) create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_client.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_CreateOAuth2Token.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/auth.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/deserializers.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/endpoints.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/generated.json create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/go_module_metadata.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/internal/endpoints/endpoints.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/options.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/serializers.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/enums.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/types.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/signin/validators.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/enums.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go create mode 100644 vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/doc.go create mode 100644 vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/strings.go create mode 100644 vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go create mode 100644 vendor/github.com/aws/smithy-go/transport/http/interceptor.go create mode 100644 vendor/github.com/aws/smithy-go/transport/http/interceptor_middleware.go rename vendor/github.com/{josharian/intern/license.md => aymanbagabas/go-osc52/v2/LICENSE} (96%) create mode 100644 vendor/github.com/aymanbagabas/go-osc52/v2/README.md create mode 100644 vendor/github.com/aymanbagabas/go-osc52/v2/osc52.go create mode 100644 vendor/github.com/buildkite/agent/v3/api/token.go create mode 100644 vendor/github.com/buildkite/go-pipeline/secret.go create mode 100644 vendor/github.com/buildkite/go-pipeline/secrets.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_embedded.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_precompute.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go create mode 100644 vendor/github.com/docker/cli/cli/config/memorystore/store.go create mode 100644 vendor/github.com/emicklei/proto/edition.go create mode 100644 vendor/github.com/emicklei/proto/literals.go delete mode 100644 vendor/github.com/go-chi/chi/.travis.yml delete mode 100644 vendor/github.com/go-chi/chi/middleware/content_type.go delete mode 100644 vendor/github.com/go-chi/chi/middleware/profiler.go rename vendor/github.com/go-chi/chi/{ => v5}/.gitignore (100%) rename vendor/github.com/go-chi/chi/{ => v5}/CHANGELOG.md (51%) rename vendor/github.com/go-chi/chi/{ => v5}/CONTRIBUTING.md (58%) rename vendor/github.com/go-chi/chi/{ => v5}/LICENSE (100%) create mode 100644 vendor/github.com/go-chi/chi/v5/Makefile rename vendor/github.com/go-chi/chi/{ => v5}/README.md (61%) create mode 100644 vendor/github.com/go-chi/chi/v5/SECURITY.md rename vendor/github.com/go-chi/chi/{ => v5}/chain.go (94%) rename vendor/github.com/go-chi/chi/{ => v5}/chi.go (80%) rename vendor/github.com/go-chi/chi/{ => v5}/context.go (73%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/basic_auth.go (87%) create mode 100644 vendor/github.com/go-chi/chi/v5/middleware/clean_path.go rename vendor/github.com/go-chi/chi/{ => v5}/middleware/compress.go (87%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/content_charset.go (88%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/content_encoding.go (100%) create mode 100644 vendor/github.com/go-chi/chi/v5/middleware/content_type.go rename vendor/github.com/go-chi/chi/{ => v5}/middleware/get_head.go (97%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/heartbeat.go (87%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/logger.go (89%) create mode 100644 vendor/github.com/go-chi/chi/v5/middleware/maybe.go rename vendor/github.com/go-chi/chi/{ => v5}/middleware/middleware.go (100%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/nocache.go (83%) create mode 100644 vendor/github.com/go-chi/chi/v5/middleware/page_route.go create mode 100644 vendor/github.com/go-chi/chi/v5/middleware/path_rewrite.go create mode 100644 vendor/github.com/go-chi/chi/v5/middleware/profiler.go rename vendor/github.com/go-chi/chi/{ => v5}/middleware/realip.go (74%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/recoverer.go (78%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/request_id.go (100%) create mode 100644 vendor/github.com/go-chi/chi/v5/middleware/request_size.go rename vendor/github.com/go-chi/chi/{ => v5}/middleware/route_headers.go (67%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/strip.go (64%) create mode 100644 vendor/github.com/go-chi/chi/v5/middleware/sunset.go create mode 100644 vendor/github.com/go-chi/chi/v5/middleware/supress_notfound.go rename vendor/github.com/go-chi/chi/{ => v5}/middleware/terminal.go (100%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/throttle.go (80%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/timeout.go (72%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/url_format.go (55%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/value.go (80%) rename vendor/github.com/go-chi/chi/{ => v5}/middleware/wrap_writer.go (71%) rename vendor/github.com/go-chi/chi/{ => v5}/mux.go (83%) create mode 100644 vendor/github.com/go-chi/chi/v5/path_value.go create mode 100644 vendor/github.com/go-chi/chi/v5/path_value_fallback.go create mode 100644 vendor/github.com/go-chi/chi/v5/pattern.go create mode 100644 vendor/github.com/go-chi/chi/v5/pattern_fallback.go rename vendor/github.com/go-chi/chi/{ => v5}/tree.go (95%) delete mode 100644 vendor/github.com/go-jose/go-jose/v3/.gitignore delete mode 100644 vendor/github.com/go-jose/go-jose/v3/.golangci.yml delete mode 100644 vendor/github.com/go-jose/go-jose/v3/.travis.yml delete mode 100644 vendor/github.com/go-jose/go-jose/v3/CHANGELOG.md delete mode 100644 vendor/github.com/go-jose/go-jose/v3/CONTRIBUTING.md delete mode 100644 vendor/github.com/go-jose/go-jose/v3/README.md delete mode 100644 vendor/github.com/go-jose/go-jose/v3/SECURITY.md delete mode 100644 vendor/github.com/go-jose/go-jose/v3/asymmetric.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/cipher/cbc_hmac.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/cipher/concat_kdf.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/cipher/ecdh_es.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/cipher/key_wrap.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/crypter.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/encoding.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/json/LICENSE delete mode 100644 vendor/github.com/go-jose/go-jose/v3/json/README.md delete mode 100644 vendor/github.com/go-jose/go-jose/v3/json/decode.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/json/encode.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/json/indent.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/json/scanner.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/json/stream.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/json/tags.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/jwe.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/jwk.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/jws.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/jwt/builder.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/jwt/claims.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/jwt/doc.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/jwt/errors.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/jwt/jwt.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/jwt/validation.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/opaque.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/shared.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/signing.go delete mode 100644 vendor/github.com/go-jose/go-jose/v3/symmetric.go create mode 100644 vendor/github.com/go-openapi/analysis/errors.go create mode 100644 vendor/github.com/go-openapi/analysis/internal/flatten/replace/errors.go create mode 100644 vendor/github.com/go-openapi/jsonreference/NOTICE create mode 100644 vendor/github.com/go-openapi/loads/errors.go delete mode 100644 vendor/github.com/go-openapi/runtime/client/opentracing.go create mode 100644 vendor/github.com/go-openapi/runtime/go.work create mode 100644 vendor/github.com/go-openapi/runtime/go.work.sum create mode 100644 vendor/github.com/go-openapi/strfmt/errors.go create mode 100644 vendor/github.com/go-openapi/strfmt/ifaces.go create mode 100644 vendor/github.com/go-openapi/strfmt/mongo.go create mode 100644 vendor/github.com/go-openapi/swag/.codecov.yml create mode 100644 vendor/github.com/go-openapi/swag/.mockery.yml create mode 100644 vendor/github.com/go-openapi/swag/SECURITY.md create mode 100644 vendor/github.com/go-openapi/swag/go.work create mode 100644 vendor/github.com/go-openapi/swag/go.work.sum create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/README.md create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/doc.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/doc.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/ifaces.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/ifaces/registry_iface.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/registry.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/adapter.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/doc.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/lexer.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/ordered_map.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/pool.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/register.go create mode 100644 vendor/github.com/go-openapi/swag/jsonutils/adapters/stdlib/json/writer.go create mode 100644 vendor/github.com/go-piv/piv-go/v2/piv/certs/yubico-ca-1.pem create mode 100644 vendor/github.com/go-piv/piv-go/v2/piv/certs/yubico-intermediate.pem create mode 100644 vendor/github.com/goccy/go-json/.codecov.yml create mode 100644 vendor/github.com/goccy/go-json/.gitignore create mode 100644 vendor/github.com/goccy/go-json/.golangci.yml create mode 100644 vendor/github.com/goccy/go-json/CHANGELOG.md create mode 100644 vendor/github.com/goccy/go-json/LICENSE create mode 100644 vendor/github.com/goccy/go-json/Makefile create mode 100644 vendor/github.com/goccy/go-json/README.md create mode 100644 vendor/github.com/goccy/go-json/color.go create mode 100644 vendor/github.com/goccy/go-json/decode.go create mode 100644 vendor/github.com/goccy/go-json/docker-compose.yml create mode 100644 vendor/github.com/goccy/go-json/encode.go create mode 100644 vendor/github.com/goccy/go-json/error.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/array.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/assign.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/bool.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/bytes.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/compile.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/compile_race.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/context.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/float.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/func.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/int.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/interface.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/invalid.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/map.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/number.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/option.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/path.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/ptr.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/slice.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/stream.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/string.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/struct.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/type.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/uint.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/code.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compact.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compiler.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/context.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/decode_rune.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/encoder.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/indent.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/int.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/map112.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/map113.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/opcode.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/option.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/optype.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/query.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/string.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/string_table.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/errors/error.go create mode 100644 vendor/github.com/goccy/go-json/internal/runtime/rtype.go create mode 100644 vendor/github.com/goccy/go-json/internal/runtime/struct_field.go create mode 100644 vendor/github.com/goccy/go-json/internal/runtime/type.go create mode 100644 vendor/github.com/goccy/go-json/json.go create mode 100644 vendor/github.com/goccy/go-json/option.go create mode 100644 vendor/github.com/goccy/go-json/path.go create mode 100644 vendor/github.com/goccy/go-json/query.go delete mode 100644 vendor/github.com/google/go-github/v72/github/dependency_graph.go rename vendor/github.com/google/go-github/{v72 => v73}/AUTHORS (100%) rename vendor/github.com/google/go-github/{v72 => v73}/LICENSE (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions_artifacts.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions_cache.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions_hosted_runners.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions_oidc.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions_permissions_enterprise.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions_permissions_orgs.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions_runner_groups.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions_runners.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions_secrets.go (99%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions_variables.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions_workflow_jobs.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions_workflow_runs.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/actions_workflows.go (99%) rename vendor/github.com/google/go-github/{v72 => v73}/github/activity.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/activity_events.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/activity_notifications.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/activity_star.go (94%) rename vendor/github.com/google/go-github/{v72 => v73}/github/activity_watching.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/admin.go (97%) rename vendor/github.com/google/go-github/{v72 => v73}/github/admin_orgs.go (93%) rename vendor/github.com/google/go-github/{v72 => v73}/github/admin_stats.go (98%) rename vendor/github.com/google/go-github/{v72 => v73}/github/admin_users.go (94%) rename vendor/github.com/google/go-github/{v72 => v73}/github/apps.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/apps_hooks.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/apps_hooks_deliveries.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/apps_installation.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/apps_manifest.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/apps_marketplace.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/attestations.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/authorizations.go (98%) rename vendor/github.com/google/go-github/{v72 => v73}/github/billing.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/checks.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/code_scanning.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/codesofconduct.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/codespaces.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/codespaces_secrets.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/copilot.go (97%) rename vendor/github.com/google/go-github/{v72 => v73}/github/dependabot.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/dependabot_alerts.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/dependabot_secrets.go (100%) create mode 100644 vendor/github.com/google/go-github/v73/github/dependency_graph.go rename vendor/github.com/google/go-github/{v72 => v73}/github/dependency_graph_snapshots.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/doc.go (88%) rename vendor/github.com/google/go-github/{v72 => v73}/github/emojis.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/enterprise.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/enterprise_actions_hosted_runners.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/enterprise_actions_runner_groups.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/enterprise_actions_runners.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/enterprise_audit_log.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/enterprise_code_security_and_analysis.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/enterprise_manage_ghes.go (95%) rename vendor/github.com/google/go-github/{v72 => v73}/github/enterprise_manage_ghes_config.go (97%) rename vendor/github.com/google/go-github/{v72 => v73}/github/enterprise_manage_ghes_maintenance.go (96%) rename vendor/github.com/google/go-github/{v72 => v73}/github/enterprise_manage_ghes_ssh.go (93%) rename vendor/github.com/google/go-github/{v72 => v73}/github/enterprise_network_configurations.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/enterprise_properties.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/enterprise_rules.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/event.go (93%) rename vendor/github.com/google/go-github/{v72 => v73}/github/event_types.go (97%) rename vendor/github.com/google/go-github/{v72 => v73}/github/gists.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/gists_comments.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/git.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/git_blobs.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/git_commits.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/git_refs.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/git_tags.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/git_trees.go (96%) rename vendor/github.com/google/go-github/{v72 => v73}/github/github-accessors.go (99%) rename vendor/github.com/google/go-github/{v72 => v73}/github/github.go (98%) rename vendor/github.com/google/go-github/{v72 => v73}/github/gitignore.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/interactions.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/interactions_orgs.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/interactions_repos.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/issue_import.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/issues.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/issues_assignees.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/issues_comments.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/issues_events.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/issues_labels.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/issues_milestones.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/issues_timeline.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/licenses.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/markdown.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/messages.go (92%) rename vendor/github.com/google/go-github/{v72 => v73}/github/meta.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/migrations.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/migrations_source_import.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/migrations_user.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_actions_allowed.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_actions_permissions.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_attestations.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_audit_log.go (96%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_codesecurity_configurations.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_credential_authorizations.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_custom_repository_roles.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_hooks.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_hooks_configuration.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_hooks_deliveries.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_issue_types.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_members.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_network_configurations.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_organization_roles.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_outside_collaborators.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_packages.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_personal_access_tokens.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_properties.go (94%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_rules.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_security_managers.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/orgs_users_blocking.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/packages.go (98%) rename vendor/github.com/google/go-github/{v72 => v73}/github/pulls.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/pulls_comments.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/pulls_reviewers.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/pulls_reviews.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/pulls_threads.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/rate_limit.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/reactions.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos.go (95%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_actions_access.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_actions_allowed.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_actions_permissions.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_attestations.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_autolinks.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_codeowners.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_collaborators.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_comments.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_commits.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_community_health.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_contents.go (95%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_deployment_branch_policies.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_deployment_protection_rules.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_deployments.go (93%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_environments.go (98%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_forks.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_hooks.go (93%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_hooks_configuration.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_hooks_deliveries.go (98%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_invitations.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_keys.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_lfs.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_merging.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_pages.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_prereceive_hooks.go (93%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_properties.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_releases.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_rules.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_stats.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_statuses.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_tags.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/repos_traffic.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/rules.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/scim.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/search.go (98%) rename vendor/github.com/google/go-github/{v72 => v73}/github/secret_scanning.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/security_advisories.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/strings.go (97%) create mode 100644 vendor/github.com/google/go-github/v73/github/sub_issue.go rename vendor/github.com/google/go-github/{v72 => v73}/github/teams.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/teams_discussion_comments.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/teams_discussions.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/teams_members.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/timestamp.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/users.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/users_administration.go (91%) rename vendor/github.com/google/go-github/{v72 => v73}/github/users_attestations.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/users_blocking.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/users_emails.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/users_followers.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/users_gpg_keys.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/users_keys.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/users_packages.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/users_ssh_signing_keys.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/with_appengine.go (100%) rename vendor/github.com/google/go-github/{v72 => v73}/github/without_appengine.go (100%) delete mode 100644 vendor/github.com/gorilla/mux/.editorconfig delete mode 100644 vendor/github.com/gorilla/mux/.gitignore delete mode 100644 vendor/github.com/gorilla/mux/LICENSE delete mode 100644 vendor/github.com/gorilla/mux/Makefile delete mode 100644 vendor/github.com/gorilla/mux/README.md delete mode 100644 vendor/github.com/gorilla/mux/doc.go delete mode 100644 vendor/github.com/gorilla/mux/middleware.go delete mode 100644 vendor/github.com/gorilla/mux/mux.go delete mode 100644 vendor/github.com/gorilla/mux/regexp.go delete mode 100644 vendor/github.com/gorilla/mux/route.go delete mode 100644 vendor/github.com/gorilla/mux/test_helpers.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/BUILD.bazel create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/annotations.pb.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/annotations.proto create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/annotations_protoopaque.pb.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/buf.gen.yaml create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2.pb.go create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2.proto create mode 100644 vendor/github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options/openapiv2_protoopaque.pb.go delete mode 100644 vendor/github.com/josharian/intern/README.md delete mode 100644 vendor/github.com/josharian/intern/intern.go create mode 100644 vendor/github.com/klauspost/compress/zstd/simple_go124.go create mode 100644 vendor/github.com/lestrrat-go/blackmagic/.gitignore create mode 100644 vendor/github.com/lestrrat-go/blackmagic/LICENSE create mode 100644 vendor/github.com/lestrrat-go/blackmagic/README.md create mode 100644 vendor/github.com/lestrrat-go/blackmagic/blackmagic.go create mode 100644 vendor/github.com/lestrrat-go/dsig-secp256k1/.gitignore create mode 100644 vendor/github.com/lestrrat-go/dsig-secp256k1/Changes create mode 100644 vendor/github.com/lestrrat-go/dsig-secp256k1/LICENSE create mode 100644 vendor/github.com/lestrrat-go/dsig-secp256k1/secp256k1.go create mode 100644 vendor/github.com/lestrrat-go/dsig/.gitignore create mode 100644 vendor/github.com/lestrrat-go/dsig/Changes create mode 100644 vendor/github.com/lestrrat-go/dsig/LICENSE create mode 100644 vendor/github.com/lestrrat-go/dsig/README.md create mode 100644 vendor/github.com/lestrrat-go/dsig/algorithms.go create mode 100644 vendor/github.com/lestrrat-go/dsig/crypto_signer.go create mode 100644 vendor/github.com/lestrrat-go/dsig/dsig.go create mode 100644 vendor/github.com/lestrrat-go/dsig/ecdsa.go create mode 100644 vendor/github.com/lestrrat-go/dsig/eddsa.go create mode 100644 vendor/github.com/lestrrat-go/dsig/hmac.go create mode 100644 vendor/github.com/lestrrat-go/dsig/internal/ecutil/ecutil.go create mode 100644 vendor/github.com/lestrrat-go/dsig/rsa.go create mode 100644 vendor/github.com/lestrrat-go/dsig/sign.go create mode 100644 vendor/github.com/lestrrat-go/dsig/validation.go create mode 100644 vendor/github.com/lestrrat-go/dsig/verify.go create mode 100644 vendor/github.com/lestrrat-go/httpcc/.gitignore create mode 100644 vendor/github.com/lestrrat-go/httpcc/LICENSE create mode 100644 vendor/github.com/lestrrat-go/httpcc/README.md create mode 100644 vendor/github.com/lestrrat-go/httpcc/directives.go create mode 100644 vendor/github.com/lestrrat-go/httpcc/httpcc.go create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/.gitignore create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/.golangci.yml create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/Changes rename vendor/github.com/{segmentio/ksuid/LICENSE.md => lestrrat-go/httprc/v3/LICENSE} (97%) create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/README.md create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/backend.go create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/client.go create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/controller.go create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/errors.go create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/errsink/errsink.go create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/httprc.go create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/options.go create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/proxysink/proxysink.go create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/resource.go create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/tracesink/tracesink.go create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/transformer.go create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/whitelist.go create mode 100644 vendor/github.com/lestrrat-go/httprc/v3/worker.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/.bazelignore create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/.bazelrc create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/.bazelversion rename vendor/github.com/{segmentio/ksuid => lestrrat-go/jwx/v3}/.gitignore (67%) create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/.golangci.yml create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/BUILD create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/Changes create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/Changes-v2.md create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/Changes-v3.md rename vendor/github.com/{open-policy-agent/opa/internal/jwx => lestrrat-go/jwx/v3}/LICENSE (99%) create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/MODULE.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/MODULE.bazel.lock create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/Makefile create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/SECURITY.md create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/WORKSPACE create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/cert/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/cert/cert.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/cert/chain.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/codecov.yml create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/format.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/formatkind_string_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/base64/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/base64/asmbase64.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/base64/base64.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/ecutil/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/ecutil/ecutil.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/json/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/json/goccy.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/json/json.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/json/registry.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/json/stdlib.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/jwxio/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/jwxio/jwxio.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/keyconv/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/keyconv/keyconv.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/pool/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/pool/big_int.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/pool/byte_slice.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/pool/bytes_buffer.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/pool/error_slice.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/pool/key_to_error_map.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/pool/pool.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/tokens/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/tokens/jwe_tokens.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/internal/tokens/tokens.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwa/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwa/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwa/compression_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwa/content_encryption_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwa/elliptic_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwa/jwa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwa/key_encryption_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwa/key_type_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwa/options.yaml create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwa/options_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwa/secp2561k.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwa/signature_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/compress.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/decrypt.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/encrypt.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/errors.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/filter.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/headers.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/headers_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/aescbc/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/aescbc/aescbc.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/cipher/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/cipher/cipher.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/cipher/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/concatkdf/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/concatkdf/concatkdf.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/content_crypt/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/content_crypt/content_crypt.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/content_crypt/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/keygen/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/keygen/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/internal/keygen/keygen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/io.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/jwe.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/jwebb/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/jwebb/content_cipher.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/jwebb/jwebb.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/jwebb/key_decrypt_asymmetric.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/jwebb/key_decrypt_symmetric.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/jwebb/key_encrypt_asymmetric.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/jwebb/key_encrypt_symmetric.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/jwebb/key_encryption.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/jwebb/keywrap.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/key_provider.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/message.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/options.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/options.yaml create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwe/options_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/cache.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/convert.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/doc.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/ecdsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/ecdsa/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/ecdsa/ecdsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/ecdsa_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/errors.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/es256k.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/fetch.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/filter.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/interface_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/io.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/jwk.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/jwkbb/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/jwkbb/x509.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/key_ops.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/okp.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/okp_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/options.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/options.yaml create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/options_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/parser.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/rsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/rsa_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/set.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/symmetric.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/symmetric_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/usage.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/whitelist.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwk/x509.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/errors.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/es256k.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/filter.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/headers.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/headers_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/internal/keytype/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/internal/keytype/keytype.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/io.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/jws.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/crypto_signer.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/ecdsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/eddsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/es256k.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/format.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/header.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/hmac.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/jwsbb.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/rsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/sign.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/jwsbb/verify.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/key_provider.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/legacy.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/legacy/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/legacy/ecdsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/legacy/eddsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/legacy/hmac.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/legacy/legacy.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/legacy/rsa.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/message.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/options.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/options.yaml create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/options_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/sign_context.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/signature_builder.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/signer.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/verifier.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jws/verify_context.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/README.md create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/builder_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/errors.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/fastpath.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/filter.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/http.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/interface.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/internal/errors/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/internal/errors/errors.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/internal/types/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/internal/types/date.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/internal/types/string.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/io.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/jwt.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/options.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/options.yaml create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/options_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/serialize.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/token_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/token_options.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/token_options_gen.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwt/validate.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/jwx.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/options.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/transform/BUILD.bazel create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/transform/filter.go create mode 100644 vendor/github.com/lestrrat-go/jwx/v3/transform/map.go create mode 100644 vendor/github.com/lestrrat-go/option/.gitignore create mode 100644 vendor/github.com/lestrrat-go/option/LICENSE create mode 100644 vendor/github.com/lestrrat-go/option/README.md create mode 100644 vendor/github.com/lestrrat-go/option/option.go create mode 100644 vendor/github.com/lestrrat-go/option/v2/.gitignore create mode 100644 vendor/github.com/lestrrat-go/option/v2/LICENSE create mode 100644 vendor/github.com/lestrrat-go/option/v2/README.md create mode 100644 vendor/github.com/lestrrat-go/option/v2/option.go create mode 100644 vendor/github.com/lestrrat-go/option/v2/set.go delete mode 100644 vendor/github.com/letsencrypt/boulder/LICENSE.txt delete mode 100644 vendor/github.com/letsencrypt/boulder/core/challenges.go delete mode 100644 vendor/github.com/letsencrypt/boulder/core/interfaces.go delete mode 100644 vendor/github.com/letsencrypt/boulder/core/objects.go delete mode 100644 vendor/github.com/letsencrypt/boulder/core/util.go delete mode 100644 vendor/github.com/letsencrypt/boulder/goodkey/blocked.go delete mode 100644 vendor/github.com/letsencrypt/boulder/goodkey/good_key.go delete mode 100644 vendor/github.com/letsencrypt/boulder/goodkey/weak.go delete mode 100644 vendor/github.com/letsencrypt/boulder/identifier/identifier.go delete mode 100644 vendor/github.com/letsencrypt/boulder/probs/probs.go delete mode 100644 vendor/github.com/letsencrypt/boulder/revocation/reasons.go delete mode 100644 vendor/github.com/letsencrypt/boulder/strictyaml/yaml.go create mode 100644 vendor/github.com/lucasb-eyer/go-colorful/rand.go create mode 100644 vendor/github.com/lucasb-eyer/go-colorful/sort.go delete mode 100644 vendor/github.com/mailru/easyjson/.gitignore delete mode 100644 vendor/github.com/mailru/easyjson/LICENSE delete mode 100644 vendor/github.com/mailru/easyjson/Makefile delete mode 100644 vendor/github.com/mailru/easyjson/README.md delete mode 100644 vendor/github.com/mailru/easyjson/buffer/pool.go delete mode 100644 vendor/github.com/mailru/easyjson/helpers.go delete mode 100644 vendor/github.com/mailru/easyjson/jlexer/bytestostr.go delete mode 100644 vendor/github.com/mailru/easyjson/jlexer/bytestostr_nounsafe.go delete mode 100644 vendor/github.com/mailru/easyjson/jlexer/error.go delete mode 100644 vendor/github.com/mailru/easyjson/jlexer/lexer.go delete mode 100644 vendor/github.com/mailru/easyjson/jwriter/writer.go delete mode 100644 vendor/github.com/mailru/easyjson/raw.go delete mode 100644 vendor/github.com/mailru/easyjson/unknown_fields.go delete mode 100644 vendor/github.com/mattn/go-runewidth/README.md delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth.go delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_appengine.go delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_js.go delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_posix.go delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_table.go delete mode 100644 vendor/github.com/mattn/go-runewidth/runewidth_windows.go delete mode 100644 vendor/github.com/mitchellh/mapstructure/CHANGELOG.md delete mode 100644 vendor/github.com/mitchellh/mapstructure/README.md delete mode 100644 vendor/github.com/mitchellh/mapstructure/decode_hooks.go delete mode 100644 vendor/github.com/mitchellh/mapstructure/error.go delete mode 100644 vendor/github.com/mitchellh/mapstructure/mapstructure.go create mode 100644 vendor/github.com/moby/term/.gitignore create mode 100644 vendor/github.com/moby/term/LICENSE create mode 100644 vendor/github.com/moby/term/README.md create mode 100644 vendor/github.com/moby/term/ascii.go create mode 100644 vendor/github.com/moby/term/doc.go create mode 100644 vendor/github.com/moby/term/proxy.go create mode 100644 vendor/github.com/moby/term/term.go create mode 100644 vendor/github.com/moby/term/term_unix.go create mode 100644 vendor/github.com/moby/term/term_windows.go create mode 100644 vendor/github.com/moby/term/termios_bsd.go create mode 100644 vendor/github.com/moby/term/termios_nonbsd.go create mode 100644 vendor/github.com/moby/term/termios_unix.go create mode 100644 vendor/github.com/moby/term/termios_windows.go create mode 100644 vendor/github.com/moby/term/windows/ansi_reader.go create mode 100644 vendor/github.com/moby/term/windows/ansi_writer.go create mode 100644 vendor/github.com/moby/term/windows/console.go create mode 100644 vendor/github.com/moby/term/windows/doc.go create mode 100644 vendor/github.com/muesli/termenv/constants_zos.go create mode 100644 vendor/github.com/muesli/termenv/copy.go create mode 100644 vendor/github.com/muesli/termenv/hyperlink.go create mode 100644 vendor/github.com/muesli/termenv/notification.go create mode 100644 vendor/github.com/muesli/termenv/output.go create mode 100644 vendor/github.com/muesli/termenv/profile.go create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.10.0.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.10.1.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.6.0.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.7.0.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.8.0.json create mode 100644 vendor/github.com/open-policy-agent/opa/capabilities/v1.9.0.json delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/buffer/buffer.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jwa/elliptic.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jwa/key_type.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jwa/parameters.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jwa/signature.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/ecdsa.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/headers.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/interface.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/jwk.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/key_ops.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/rsa.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jwk/symmetric.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/headers.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/interface.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/jws.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/message.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/ecdsa.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/hmac.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/interface.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/rsa.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/sign.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/ecdsa.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/hmac.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/interface.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/rsa.go delete mode 100644 vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/verify.go create mode 100644 vendor/github.com/open-policy-agent/opa/v1/ast/default_module_loader.go create mode 100644 vendor/github.com/open-policy-agent/opa/v1/ast/performance.go create mode 100644 vendor/github.com/open-policy-agent/opa/v1/ast/rego_compiler.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/.gitignore delete mode 100644 vendor/github.com/opentracing/opentracing-go/.travis.yml delete mode 100644 vendor/github.com/opentracing/opentracing-go/CHANGELOG.md delete mode 100644 vendor/github.com/opentracing/opentracing-go/Makefile delete mode 100644 vendor/github.com/opentracing/opentracing-go/README.md delete mode 100644 vendor/github.com/opentracing/opentracing-go/ext.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/ext/field.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/ext/tags.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/globaltracer.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/gocontext.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/log/field.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/log/util.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/noop.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/propagation.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/span.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/tracer.go create mode 100644 vendor/github.com/pkg/browser/LICENSE create mode 100644 vendor/github.com/pkg/browser/README.md create mode 100644 vendor/github.com/pkg/browser/browser.go create mode 100644 vendor/github.com/pkg/browser/browser_darwin.go create mode 100644 vendor/github.com/pkg/browser/browser_freebsd.go create mode 100644 vendor/github.com/pkg/browser/browser_linux.go create mode 100644 vendor/github.com/pkg/browser/browser_netbsd.go create mode 100644 vendor/github.com/pkg/browser/browser_openbsd.go create mode 100644 vendor/github.com/pkg/browser/browser_unsupported.go create mode 100644 vendor/github.com/pkg/browser/browser_windows.go create mode 100644 vendor/github.com/protocolbuffers/txtpbfmt/config/config.go create mode 100644 vendor/github.com/protocolbuffers/txtpbfmt/descriptor/descriptor.go create mode 100644 vendor/github.com/protocolbuffers/txtpbfmt/impl/impl.go create mode 100644 vendor/github.com/protocolbuffers/txtpbfmt/logger/logger.go create mode 100644 vendor/github.com/protocolbuffers/txtpbfmt/printer/printer.go create mode 100644 vendor/github.com/protocolbuffers/txtpbfmt/quote/quote.go create mode 100644 vendor/github.com/protocolbuffers/txtpbfmt/sort/sort.go create mode 100644 vendor/github.com/protocolbuffers/txtpbfmt/wrap/wrap.go delete mode 100644 vendor/github.com/rogpeppe/go-internal/robustio/robustio.go delete mode 100644 vendor/github.com/rogpeppe/go-internal/robustio/robustio_darwin.go delete mode 100644 vendor/github.com/rogpeppe/go-internal/robustio/robustio_windows.go create mode 100644 vendor/github.com/segmentio/asm/LICENSE create mode 100644 vendor/github.com/segmentio/asm/base64/base64.go create mode 100644 vendor/github.com/segmentio/asm/base64/base64_amd64.go create mode 100644 vendor/github.com/segmentio/asm/base64/base64_arm64.go create mode 100644 vendor/github.com/segmentio/asm/base64/base64_asm.go create mode 100644 vendor/github.com/segmentio/asm/base64/base64_default.go create mode 100644 vendor/github.com/segmentio/asm/base64/decode_amd64.go create mode 100644 vendor/github.com/segmentio/asm/base64/decode_amd64.s create mode 100644 vendor/github.com/segmentio/asm/base64/decode_arm64.go create mode 100644 vendor/github.com/segmentio/asm/base64/decode_arm64.s create mode 100644 vendor/github.com/segmentio/asm/base64/encode_amd64.go create mode 100644 vendor/github.com/segmentio/asm/base64/encode_amd64.s create mode 100644 vendor/github.com/segmentio/asm/base64/encode_arm64.go create mode 100644 vendor/github.com/segmentio/asm/base64/encode_arm64.s create mode 100644 vendor/github.com/segmentio/asm/cpu/arm/arm.go create mode 100644 vendor/github.com/segmentio/asm/cpu/arm64/arm64.go create mode 100644 vendor/github.com/segmentio/asm/cpu/cpu.go create mode 100644 vendor/github.com/segmentio/asm/cpu/cpuid/cpuid.go create mode 100644 vendor/github.com/segmentio/asm/cpu/x86/x86.go create mode 100644 vendor/github.com/segmentio/asm/internal/unsafebytes/unsafebytes.go delete mode 100644 vendor/github.com/segmentio/ksuid/README.md delete mode 100644 vendor/github.com/segmentio/ksuid/base62.go delete mode 100644 vendor/github.com/segmentio/ksuid/ksuid.go delete mode 100644 vendor/github.com/segmentio/ksuid/rand.go delete mode 100644 vendor/github.com/segmentio/ksuid/sequence.go delete mode 100644 vendor/github.com/segmentio/ksuid/set.go delete mode 100644 vendor/github.com/segmentio/ksuid/uint128.go create mode 100644 vendor/github.com/sigstore/cosign/v2/cmd/cosign/cli/options/signingconfig.go create mode 100644 vendor/github.com/sigstore/cosign/v2/internal/auth/auth.go create mode 100644 vendor/github.com/sigstore/cosign/v2/internal/key/svkeypair.go create mode 100644 vendor/github.com/sigstore/cosign/v2/internal/ui/spinner.go create mode 100644 vendor/github.com/sigstore/cosign/v2/pkg/cosign/bundle/sign.go create mode 100644 vendor/github.com/sigstore/cosign/v2/pkg/types/predicate.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/COPYRIGHT.txt rename vendor/github.com/{opentracing/opentracing-go => sigstore/rekor-tiles/v2}/LICENSE (99%) create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/internal/safeint/safeint.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/pkg/client/option.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/pkg/client/transport.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/pkg/client/write/write.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/pkg/generated/protobuf/dsse.pb.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/pkg/generated/protobuf/entry.pb.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/pkg/generated/protobuf/hashedrekord.pb.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/pkg/generated/protobuf/rekor_service.pb.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/pkg/generated/protobuf/rekor_service.pb.gw.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/pkg/generated/protobuf/rekor_service_grpc.pb.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/pkg/generated/protobuf/verifier.pb.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/pkg/note/note.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/pkg/types/verifier/verifier.go create mode 100644 vendor/github.com/sigstore/rekor-tiles/v2/pkg/verify/verify.go create mode 100644 vendor/github.com/sigstore/rekor/pkg/internal/log/logger.go create mode 100644 vendor/github.com/sigstore/rekor/pkg/pki/pkitypes/types.go delete mode 100644 vendor/github.com/sigstore/rekor/pkg/pki/x509/e2e.go delete mode 100644 vendor/github.com/sigstore/rekor/pkg/util/util.go create mode 100644 vendor/github.com/sigstore/sigstore-go/pkg/sign/certificate.go create mode 100644 vendor/github.com/sigstore/sigstore-go/pkg/sign/content.go create mode 100644 vendor/github.com/sigstore/sigstore-go/pkg/sign/keys.go create mode 100644 vendor/github.com/sigstore/sigstore-go/pkg/sign/signer.go create mode 100644 vendor/github.com/sigstore/sigstore-go/pkg/sign/timestamping.go create mode 100644 vendor/github.com/sigstore/sigstore-go/pkg/sign/transparency.go create mode 100644 vendor/github.com/sigstore/sigstore/pkg/cryptoutils/safestring.go create mode 100644 vendor/github.com/sigstore/timestamp-authority/v2/CONTRIBUTORS.md create mode 100644 vendor/github.com/sigstore/timestamp-authority/v2/COPYRIGHT.txt create mode 100644 vendor/github.com/sigstore/timestamp-authority/v2/LICENSE create mode 100644 vendor/github.com/sigstore/timestamp-authority/v2/pkg/verification/verify.go create mode 100644 vendor/github.com/sigstore/timestamp-authority/v2/pkg/verification/verify_request.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_wasi.go create mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go delete mode 100644 vendor/github.com/skratchdot/open-golang/LICENSE delete mode 100644 vendor/github.com/skratchdot/open-golang/open/exec.go delete mode 100644 vendor/github.com/skratchdot/open-golang/open/exec_darwin.go delete mode 100644 vendor/github.com/skratchdot/open-golang/open/exec_windows.go delete mode 100644 vendor/github.com/skratchdot/open-golang/open/open.go delete mode 100644 vendor/github.com/titanous/rocacheck/LICENSE delete mode 100644 vendor/github.com/titanous/rocacheck/README.md delete mode 100644 vendor/github.com/titanous/rocacheck/rocacheck.go create mode 100644 vendor/github.com/transparency-dev/formats/LICENSE create mode 100644 vendor/github.com/transparency-dev/formats/log/README.md create mode 100644 vendor/github.com/transparency-dev/formats/log/checkpoint.go create mode 100644 vendor/github.com/transparency-dev/formats/log/identifier.go create mode 100644 vendor/github.com/transparency-dev/formats/log/note.go create mode 100644 vendor/github.com/valyala/fastjson/.gitignore create mode 100644 vendor/github.com/valyala/fastjson/.travis.yml rename vendor/github.com/{mattn/go-runewidth => valyala/fastjson}/LICENSE (96%) create mode 100644 vendor/github.com/valyala/fastjson/README.md create mode 100644 vendor/github.com/valyala/fastjson/arena.go create mode 100644 vendor/github.com/valyala/fastjson/doc.go create mode 100644 vendor/github.com/valyala/fastjson/fastfloat/parse.go create mode 100644 vendor/github.com/valyala/fastjson/fuzz.go create mode 100644 vendor/github.com/valyala/fastjson/handy.go create mode 100644 vendor/github.com/valyala/fastjson/parser.go create mode 100644 vendor/github.com/valyala/fastjson/pool.go create mode 100644 vendor/github.com/valyala/fastjson/scanner.go create mode 100644 vendor/github.com/valyala/fastjson/update.go create mode 100644 vendor/github.com/valyala/fastjson/util.go create mode 100644 vendor/github.com/valyala/fastjson/validate.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/core/core.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/core/helpers.go rename vendor/github.com/vektah/gqlparser/v2/validator/{ => core}/walk.go (99%) delete mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/error.go delete mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/messaging.go create mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/rules/rules.go delete mode 100644 vendor/github.com/vektah/gqlparser/v2/validator/suggestionList.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/AGENTS.md create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/group_relations_export.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/merge_request_context_commits.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/model_registry.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_aliases.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/project_statistics.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/protected_packages.go create mode 100644 vendor/gitlab.com/gitlab-org/api/client-go/request_handler.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/v1.20.0.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/gen.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/httpconv.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go create mode 100644 vendor/go.opentelemetry.io/otel/sdk/trace/internal/x/README.md create mode 100644 vendor/go.opentelemetry.io/otel/sdk/trace/internal/x/x.go delete mode 100644 vendor/go.opentelemetry.io/otel/sdk/trace/version.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/internal/v2/http.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/internal/v2/net.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/README.md delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/doc.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/event.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/exception.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/http.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv/README.md delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/httpconv/http.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/resource.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/schema.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.17.0/trace.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.20.0/README.md delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.20.0/attribute_group.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.20.0/doc.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.20.0/event.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.20.0/exception.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.20.0/http.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.20.0/resource.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.20.0/schema.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.20.0/trace.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.26.0/README.md delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.26.0/attribute_group.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.26.0/doc.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.26.0/exception.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.26.0/metric.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.26.0/schema.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.34.0/MIGRATION.md delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.34.0/README.md delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.34.0/attribute_group.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.34.0/doc.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.34.0/error_type.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.34.0/exception.go delete mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.34.0/schema.go rename vendor/go.opentelemetry.io/otel/semconv/{v1.34.0 => v1.37.0}/httpconv/metric.go (85%) create mode 100644 vendor/go.opentelemetry.io/otel/semconv/v1.37.0/otelconv/metric.go delete mode 100644 vendor/golang.org/x/crypto/ocsp/ocsp.go delete mode 100644 vendor/golang.org/x/crypto/sha3/hashes.go delete mode 100644 vendor/golang.org/x/crypto/sha3/legacy_hash.go delete mode 100644 vendor/golang.org/x/crypto/sha3/legacy_keccakf.go delete mode 100644 vendor/golang.org/x/crypto/sha3/shake.go create mode 100644 vendor/golang.org/x/exp/constraints/constraints.go delete mode 100644 vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go rename vendor/{github.com/go-jose/go-jose/v3/doc.go => google.golang.org/grpc/encoding/internal/internal.go} (51%) create mode 100644 vendor/google.golang.org/grpc/internal/stats/stats.go diff --git a/go.mod b/go.mod index a5b3d9b8e2..e1f3cb4124 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ module github.com/tektoncd/operator -go 1.24.0 - -toolchain go1.24.1 +go 1.25.0 require ( github.com/Masterminds/semver v1.5.0 @@ -16,7 +14,7 @@ require ( github.com/openshift/api v0.0.0-20240521185306-0314f31e7774 github.com/openshift/apiserver-library-go v0.0.0-20230816171015-6bfafa975bfb github.com/openshift/client-go v0.0.0-20240523113335-452272e0496d - github.com/sigstore/cosign/v2 v2.5.2 + github.com/sigstore/cosign/v2 v2.6.1 github.com/spf13/cobra v1.10.2 github.com/spf13/viper v1.21.0 github.com/stretchr/testify v1.11.1 @@ -32,9 +30,9 @@ require ( gomodules.xyz/jsonpatch/v2 v2.5.0 gopkg.in/yaml.v3 v3.0.1 gotest.tools/v3 v3.5.2 - k8s.io/api v0.34.1 + k8s.io/api v0.34.2 k8s.io/apiextensions-apiserver v0.34.1 - k8s.io/apimachinery v0.34.1 + k8s.io/apimachinery v0.34.2 k8s.io/client-go v1.5.2 k8s.io/code-generator v0.34.1 k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d @@ -56,17 +54,18 @@ replace ( ) require ( - cel.dev/expr v0.24.0 // indirect - cloud.google.com/go/auth v0.16.5 // indirect + cel.dev/expr v0.25.1 // indirect + cloud.google.com/go/auth v0.17.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect - cloud.google.com/go/compute/metadata v0.8.0 // indirect + cloud.google.com/go/compute/metadata v0.9.0 // indirect contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20230502190836-7399e0f8ee5e // indirect contrib.go.opencensus.io/exporter/prometheus v0.4.2 // indirect - cuelabs.dev/go/oci/ociregistry v0.0.0-20241125120445-2c00c104c6e1 // indirect - cuelang.org/go v0.12.1 // indirect + cuelabs.dev/go/oci/ociregistry v0.0.0-20250722084951-074d06050084 // indirect + cuelang.org/go v0.15.1 // indirect github.com/AlecAivazis/survey/v2 v2.3.7 // indirect github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/provider v0.14.0 // indirect github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect + github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.29 // indirect github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect @@ -91,31 +90,33 @@ require ( github.com/aliyun/credentials-go v1.3.2 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go-v2 v1.36.4 // indirect - github.com/aws/aws-sdk-go-v2/config v1.29.16 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.69 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.31 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.35 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.35 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect - github.com/aws/aws-sdk-go-v2/service/ecr v1.40.3 // indirect - github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.31.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.16 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.25.4 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.2 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.21 // indirect - github.com/aws/smithy-go v1.22.3 // indirect - github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.9.1 // indirect + github.com/aws/aws-sdk-go-v2 v1.40.0 // indirect + github.com/aws/aws-sdk-go-v2/config v1.32.2 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.19.2 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.14 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect + github.com/aws/aws-sdk-go-v2/service/ecr v1.51.2 // indirect + github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.38.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.14 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.10 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.41.2 // indirect + github.com/aws/smithy-go v1.24.0 // indirect + github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.11.0 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/blendle/zapdriver v1.3.1 // indirect - github.com/buildkite/agent/v3 v3.98.2 // indirect - github.com/buildkite/go-pipeline v0.13.3 // indirect + github.com/buildkite/agent/v3 v3.114.1 // indirect + github.com/buildkite/go-pipeline v0.16.0 // indirect github.com/buildkite/interpolate v0.1.5 // indirect - github.com/buildkite/roko v1.3.1 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect + github.com/buildkite/roko v1.4.0 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect @@ -124,55 +125,56 @@ require ( github.com/cli/shurcooL-graphql v0.0.2 // indirect github.com/cockroachdb/apd/v3 v3.2.1 // indirect github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect - github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect - github.com/coreos/go-oidc/v3 v3.15.0 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.18.1 // indirect + github.com/coreos/go-oidc/v3 v3.17.0 // indirect github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect github.com/dimchansky/utfbom v1.1.1 // indirect - github.com/docker/cli v28.2.2+incompatible // indirect + github.com/docker/cli v29.0.3+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker-credential-helpers v0.9.3 // indirect + github.com/docker/docker-credential-helpers v0.9.4 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/emicklei/go-restful/v3 v3.13.0 // indirect - github.com/emicklei/proto v1.13.4 // indirect + github.com/emicklei/proto v1.14.2 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect - github.com/go-chi/chi v4.1.2+incompatible // indirect + github.com/go-chi/chi/v5 v5.2.3 // indirect github.com/go-ini/ini v1.67.0 // indirect - github.com/go-jose/go-jose/v3 v3.0.4 // indirect - github.com/go-jose/go-jose/v4 v4.1.2 // indirect + github.com/go-jose/go-jose/v4 v4.1.3 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/analysis v0.23.0 // indirect - github.com/go-openapi/errors v0.22.1 // indirect - github.com/go-openapi/jsonpointer v0.22.0 // indirect - github.com/go-openapi/jsonreference v0.21.1 // indirect - github.com/go-openapi/loads v0.22.0 // indirect - github.com/go-openapi/runtime v0.28.0 // indirect - github.com/go-openapi/spec v0.21.0 // indirect - github.com/go-openapi/strfmt v0.23.0 // indirect - github.com/go-openapi/swag v0.24.1 // indirect - github.com/go-openapi/swag/cmdutils v0.24.0 // indirect - github.com/go-openapi/swag/conv v0.24.0 // indirect - github.com/go-openapi/swag/fileutils v0.24.0 // indirect - github.com/go-openapi/swag/jsonname v0.24.0 // indirect - github.com/go-openapi/swag/jsonutils v0.24.0 // indirect - github.com/go-openapi/swag/loading v0.24.0 // indirect - github.com/go-openapi/swag/mangling v0.24.0 // indirect - github.com/go-openapi/swag/netutils v0.24.0 // indirect - github.com/go-openapi/swag/stringutils v0.24.0 // indirect - github.com/go-openapi/swag/typeutils v0.24.0 // indirect - github.com/go-openapi/swag/yamlutils v0.24.0 // indirect - github.com/go-openapi/validate v0.24.0 // indirect - github.com/go-piv/piv-go/v2 v2.3.0 // indirect + github.com/go-openapi/analysis v0.24.1 // indirect + github.com/go-openapi/errors v0.22.4 // indirect + github.com/go-openapi/jsonpointer v0.22.1 // indirect + github.com/go-openapi/jsonreference v0.21.3 // indirect + github.com/go-openapi/loads v0.23.2 // indirect + github.com/go-openapi/runtime v0.29.2 // indirect + github.com/go-openapi/spec v0.22.1 // indirect + github.com/go-openapi/strfmt v0.25.0 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect + github.com/go-openapi/validate v0.25.1 // indirect + github.com/go-piv/piv-go/v2 v2.4.0 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/gobuffalo/envy v1.10.1 // indirect github.com/gobuffalo/flect v1.0.3 // indirect github.com/gobwas/glob v0.2.3 // indirect + github.com/goccy/go-json v0.10.5 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect @@ -181,80 +183,87 @@ require ( github.com/google/cel-go v0.26.1 // indirect github.com/google/certificate-transparency-go v1.3.2 // indirect github.com/google/gnostic-models v0.7.0 // indirect - github.com/google/go-containerregistry v0.20.6 // indirect - github.com/google/go-github/v72 v72.0.0 // indirect + github.com/google/go-containerregistry v0.20.7 // indirect + github.com/google/go-github/v73 v73.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.7 // indirect github.com/googleapis/gax-go/v2 v2.15.0 // indirect - github.com/gorilla/mux v1.8.1 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.8 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/henvic/httpretty v0.0.6 // indirect - github.com/in-toto/attestation v1.1.1 // indirect + github.com/in-toto/attestation v1.1.2 // indirect github.com/in-toto/in-toto-golang v0.9.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect github.com/joho/godotenv v1.4.0 // indirect - github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.18.0 // indirect - github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/mailru/easyjson v0.9.1 // indirect + github.com/klauspost/compress v1.18.1 // indirect + github.com/lestrrat-go/blackmagic v1.0.4 // indirect + github.com/lestrrat-go/dsig v1.0.0 // indirect + github.com/lestrrat-go/dsig-secp256k1 v1.0.0 // indirect + github.com/lestrrat-go/httpcc v1.0.1 // indirect + github.com/lestrrat-go/httprc/v3 v3.0.1 // indirect + github.com/lestrrat-go/jwx/v3 v3.0.11 // indirect + github.com/lestrrat-go/option v1.0.1 // indirect + github.com/lestrrat-go/option/v2 v2.0.0 // indirect + github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.17 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/miekg/dns v1.1.61 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect - github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect + github.com/moby/term v0.5.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mozillazg/docker-credential-acr-helper v0.4.0 // indirect - github.com/muesli/termenv v0.12.0 // indirect + github.com/muesli/termenv v0.16.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 // indirect + github.com/nxadm/tail v1.4.11 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/oleiade/reflections v1.1.0 // indirect - github.com/open-policy-agent/opa v1.5.1 // indirect + github.com/open-policy-agent/opa v1.10.1 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect - github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/pborman/uuid v1.2.1 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/common v0.67.4 // indirect github.com/prometheus/procfs v0.17.0 // indirect github.com/prometheus/statsd_exporter v0.28.0 // indirect - github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d // indirect - github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/protocolbuffers/txtpbfmt v0.0.0-20251016062345-16587c79cd91 // indirect + github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/sagikazarmark/locafero v0.11.0 // indirect github.com/sassoftware/relic v7.2.1+incompatible // indirect - github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect - github.com/segmentio/ksuid v1.0.4 // indirect + github.com/secure-systems-lab/go-securesystemslib v0.9.1 // indirect + github.com/segmentio/asm v1.2.0 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect - github.com/sigstore/fulcio v1.7.1 // indirect - github.com/sigstore/protobuf-specs v0.4.3 // indirect - github.com/sigstore/rekor v1.3.10 // indirect - github.com/sigstore/sigstore v1.9.5 // indirect - github.com/sigstore/sigstore-go v1.0.0 // indirect - github.com/sigstore/timestamp-authority v1.2.8 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect + github.com/sigstore/fulcio v1.8.3 // indirect + github.com/sigstore/protobuf-specs v0.5.0 // indirect + github.com/sigstore/rekor v1.4.3 // indirect + github.com/sigstore/rekor-tiles/v2 v2.0.1 // indirect + github.com/sigstore/sigstore v1.10.3 // indirect + github.com/sigstore/sigstore-go v1.1.4-0.20251201121426-2cdedea80894 // indirect + github.com/sigstore/timestamp-authority v1.2.9 // indirect + github.com/sigstore/timestamp-authority/v2 v2.0.3 // indirect + github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af // indirect github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect github.com/spf13/afero v1.15.0 // indirect github.com/spf13/cast v1.10.0 // indirect @@ -263,27 +272,28 @@ require ( github.com/stoewer/go-strcase v1.3.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect - github.com/tchap/go-patricia/v2 v2.3.2 // indirect + github.com/tchap/go-patricia/v2 v2.3.3 // indirect github.com/thales-e-security/pool v0.0.2 // indirect github.com/theupdateframework/go-tuf v0.7.0 // indirect - github.com/theupdateframework/go-tuf/v2 v2.1.1 // indirect + github.com/theupdateframework/go-tuf/v2 v2.3.0 // indirect github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e // indirect - github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect + github.com/transparency-dev/formats v0.0.0-20251017110053-404c0d5b696c // indirect github.com/transparency-dev/merkle v0.0.2 // indirect - github.com/vbatts/tar-split v0.12.1 // indirect - github.com/vektah/gqlparser/v2 v2.5.26 // indirect + github.com/valyala/fastjson v1.6.4 // indirect + github.com/vbatts/tar-split v0.12.2 // indirect + github.com/vektah/gqlparser/v2 v2.5.30 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yashtewari/glob-intersection v0.2.0 // indirect - gitlab.com/gitlab-org/api/client-go v0.145.0 // indirect - go.mongodb.org/mongo-driver v1.14.0 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect + gitlab.com/gitlab-org/api/client-go v0.160.0 // indirect + go.mongodb.org/mongo-driver v1.17.6 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect go.opentelemetry.io/otel v1.38.0 // indirect go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.37.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect go.opentelemetry.io/otel/trace v1.38.0 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect @@ -291,16 +301,16 @@ require ( go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.46.0 // indirect golang.org/x/net v0.48.0 // indirect - golang.org/x/oauth2 v0.32.0 // indirect + golang.org/x/oauth2 v0.33.0 // indirect golang.org/x/sys v0.39.0 // indirect golang.org/x/term v0.38.0 // indirect golang.org/x/text v0.32.0 // indirect - golang.org/x/time v0.13.0 // indirect + golang.org/x/time v0.14.0 // indirect golang.org/x/tools v0.40.0 // indirect - google.golang.org/api v0.249.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 // indirect - google.golang.org/grpc v1.76.0 // indirect + google.golang.org/api v0.256.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101 // indirect + google.golang.org/grpc v1.77.0 // indirect google.golang.org/protobuf v1.36.10 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect @@ -313,6 +323,6 @@ require ( sigs.k8s.io/controller-runtime v0.15.3 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/release-utils v0.11.1 // indirect + sigs.k8s.io/release-utils v0.12.2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect ) diff --git a/go.sum b/go.sum index 8a1a90f036..3a6516f844 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ al.essio.dev/pkg/shellescape v1.6.0 h1:NxFcEqzFSEVCGN2yq7Huv/9hyCEGVa/TncnOOBBeX al.essio.dev/pkg/shellescape v1.6.0/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890= cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg= cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -52,8 +52,8 @@ cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJN cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU= cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= -cloud.google.com/go v0.121.1 h1:S3kTQSydxmu1JfLRLpKtxRPA7rSrYPRPEUmL/PavVUw= -cloud.google.com/go v0.121.1/go.mod h1:nRFlrHq39MNVWu+zESP2PosMWA0ryJw8KUBZ2iZpxbw= +cloud.google.com/go v0.121.6 h1:waZiuajrI28iAf40cWgycWNgaXPO06dupuS+sgibK6c= +cloud.google.com/go v0.121.6/go.mod h1:coChdst4Ea5vUpiALcYKXEpR1S9ZgXbhEzzMcMR66vI= cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= @@ -190,8 +190,8 @@ cloud.google.com/go/assuredworkloads v1.11.2/go.mod h1:O1dfr+oZJMlE6mw0Bp0P1KZSl cloud.google.com/go/assuredworkloads v1.11.3/go.mod h1:vEjfTKYyRUaIeA0bsGJceFV2JKpVRgyG2op3jfa59Zs= cloud.google.com/go/assuredworkloads v1.11.4/go.mod h1:4pwwGNwy1RP0m+y12ef3Q/8PaiWrIDQ6nD2E8kvWI9U= cloud.google.com/go/assuredworkloads v1.11.5/go.mod h1:FKJ3g3ZvkL2D7qtqIGnDufFkHxwIpNM9vtmhvt+6wqk= -cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI= -cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ= +cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4= +cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= @@ -363,8 +363,8 @@ cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1h cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/compute/metadata v0.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA= -cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= @@ -701,8 +701,8 @@ cloud.google.com/go/iam v1.1.3/go.mod h1:3khUlaBXfPKKe7huYgEpDn6FtgRyMEqbkvBxrQy cloud.google.com/go/iam v1.1.4/go.mod h1:l/rg8l1AaA+VFMho/HYx2Vv6xinPSLMF8qfhRPIZ0L8= cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= -cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= -cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= +cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc= +cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU= cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= @@ -747,8 +747,8 @@ cloud.google.com/go/kms v1.15.4/go.mod h1:L3Sdj6QTHK8dfwK5D1JLsAyELsNMnd3tAIwGS4 cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI= cloud.google.com/go/kms v1.15.6/go.mod h1:yF75jttnIdHfGBoE51AKsD/Yqf+/jICzB9v1s1acsms= cloud.google.com/go/kms v1.15.7/go.mod h1:ub54lbsa6tDkUwnu4W7Yt1aAIFLnspgh0kPGToDukeI= -cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk= -cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8= +cloud.google.com/go/kms v1.23.2 h1:4IYDQL5hG4L+HzJBhzejUySoUOheh3Lk5YT4PCyyW6k= +cloud.google.com/go/kms v1.23.2/go.mod h1:rZ5kK0I7Kn9W4erhYVoIRPtpizjunlrfU4fUkumUp8g= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= @@ -1338,10 +1338,10 @@ contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20230502190836-7399e0f8ee5e h contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20230502190836-7399e0f8ee5e/go.mod h1:IshRmMJBhDfFj5Y67nVhMYTTIze91RUeT73ipWKs/GY= contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg= contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9fpw1KeYcjrnC1J8B+JKjsZyRQ= -cuelabs.dev/go/oci/ociregistry v0.0.0-20241125120445-2c00c104c6e1 h1:mRwydyTyhtRX2wXS3mqYWzR2qlv6KsmoKXmlz5vInjg= -cuelabs.dev/go/oci/ociregistry v0.0.0-20241125120445-2c00c104c6e1/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg= -cuelang.org/go v0.12.1 h1:5I+zxmXim9MmiN2tqRapIqowQxABv2NKTgbOspud1Eo= -cuelang.org/go v0.12.1/go.mod h1:B4+kjvGGQnbkz+GuAv1dq/R308gTkp0sO28FdMrJ2Kw= +cuelabs.dev/go/oci/ociregistry v0.0.0-20250722084951-074d06050084 h1:4k1yAtPvZJZQTu8DRY8muBo0LHv6TqtrE0AO5n6IPYs= +cuelabs.dev/go/oci/ociregistry v0.0.0-20250722084951-074d06050084/go.mod h1:4WWeZNxUO1vRoZWAHIG0KZOd6dA25ypyWuwD3ti0Tdc= +cuelang.org/go v0.15.1 h1:MRnjc/KJE+K42rnJ3a+425f1jqXeOOgq9SK4tYRTtWw= +cuelang.org/go v0.15.1/go.mod h1:NYw6n4akZcTjA7QQwJ1/gqWrrhsN4aZwhcAL0jv9rZE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= @@ -1355,18 +1355,20 @@ github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/provider v0.14.0 github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/provider v0.14.0/go.mod h1:tlqp9mUGbsP+0z3Q+c0Q5MgSdq/OMwQhm5bffR3Q3ss= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 h1:B+blDbyVIG3WaikNxPnhPiJ1MThR03b3vKGtER95TP4= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1 h1:Wgf5rZba3YZqeTNJPtvqZoBu1sBN/L4sry+u2U3Y75w= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.3.1/go.mod h1:xxCBG/f/4Vbmh2XQJBsOmNdxWUY5j/s27jujKPbQf14= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1 h1:bFWuoEKg+gImo7pvkiQEFAc8ocibADgXeiLAxWhWmkI= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.1.1/go.mod h1:Vih/3yc6yac2JzU4hzpaDupBJP0Flaia9rXXrU8xyww= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 h1:JXg2dwJUmPB9JmtVmdEB16APJ7jurfbY5jnfXpJoRMc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 h1:E4MgwLBGeVB5f2MdcIVD3ELVAWpr+WD6MUe1i+tM/PA= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0/go.mod h1:Y2b/1clN4zsAoUd/pgNAQHjLDnTis/6ROkUfyob6psM= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 h1:nCYfgcSyHZXJI8J0IWE5MsCGlb2xp9fJiXyxWgmOFg4= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0/go.mod h1:ucUjca2JtSZboY8IoUqyQyuuXvwbMBVwFOm0vdQPNhA= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= @@ -1390,8 +1392,8 @@ github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+Z github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= -github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgvJqCH0sFfrBUTnUJSBrBf7++ypk+twtRs= +github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= @@ -1491,42 +1493,46 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= -github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.36.4 h1:GySzjhVvx0ERP6eyfAbAuAXLtAda5TEy19E5q5W8I9E= -github.com/aws/aws-sdk-go-v2 v1.36.4/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= -github.com/aws/aws-sdk-go-v2/config v1.29.16 h1:XkruGnXX1nEZ+Nyo9v84TzsX+nj86icbFAeust6uo8A= -github.com/aws/aws-sdk-go-v2/config v1.29.16/go.mod h1:uCW7PNjGwZ5cOGZ5jr8vCWrYkGIhPoTNV23Q/tpHKzg= -github.com/aws/aws-sdk-go-v2/credentials v1.17.69 h1:8B8ZQboRc3uaIKjshve/XlvJ570R7BKNy3gftSbS178= -github.com/aws/aws-sdk-go-v2/credentials v1.17.69/go.mod h1:gPME6I8grR1jCqBFEGthULiolzf/Sexq/Wy42ibKK9c= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.31 h1:oQWSGexYasNpYp4epLGZxxjsDo8BMBh6iNWkTXQvkwk= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.31/go.mod h1:nc332eGUU+djP3vrMI6blS0woaCfHTe3KiSQUVTMRq0= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.35 h1:o1v1VFfPcDVlK3ll1L5xHsaQAFdNtZ5GXnNR7SwueC4= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.35/go.mod h1:rZUQNYMNG+8uZxz9FOerQJ+FceCiodXvixpeRtdESrU= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.35 h1:R5b82ubO2NntENm3SAm0ADME+H630HomNJdgv+yZ3xw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.35/go.mod h1:FuA+nmgMRfkzVKYDNEqQadvEMxtxl9+RLT9ribCwEMs= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= -github.com/aws/aws-sdk-go-v2/service/ecr v1.40.3 h1:a+210FCU/pR5hhKRaskRfX/ogcyyzFBrehcTk5DTAyU= -github.com/aws/aws-sdk-go-v2/service/ecr v1.40.3/go.mod h1:dtD3a4sjUjVL86e0NUvaqdGvds5ED6itUiZPDaT+Gh8= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.31.2 h1:E6/Myrj9HgLF22medmDrKmbpm4ULsa+cIBNx3phirBk= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.31.2/go.mod h1:OQ8NALFcchBJ/qruak6zKUQodovnTKKaReTuCkc5/9Y= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.16 h1:/ldKrPPXTC421bTNWrUIpq3CxwHwRI/kpc+jPUTJocM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.16/go.mod h1:5vkf/Ws0/wgIMJDQbjI4p2op86hNW6Hie5QtebrDgT8= -github.com/aws/aws-sdk-go-v2/service/kms v1.41.0 h1:2jKyib9msVrAVn+lngwlSplG13RpUZmzVte2yDao5nc= -github.com/aws/aws-sdk-go-v2/service/kms v1.41.0/go.mod h1:RyhzxkWGcfixlkieewzpO3D4P4fTMxhIDqDZWsh0u/4= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.4 h1:EU58LP8ozQDVroOEyAfcq0cGc5R/FTZjVoYJ6tvby3w= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.4/go.mod h1:CrtOgCcysxMvrCoHnvNAD7PHWclmoFG78Q2xLK0KKcs= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.2 h1:XB4z0hbQtpmBnb1FQYvKaCM7UsS6Y/u8jVBwIUGeCTk= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.2/go.mod h1:hwRpqkRxnQ58J9blRDrB4IanlXCpcKmsC83EhG77upg= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.21 h1:nyLjs8sYJShFYj6aiyjCBI3EcLn1udWrQTjEF+SOXB0= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.21/go.mod h1:EhdxtZ+g84MSGrSrHzZiUm9PYiZkrADNja15wtRJSJo= -github.com/aws/smithy-go v1.22.3 h1:Z//5NuZCSW6R4PhQ93hShNbyBbn8BWCmCVCt+Q8Io5k= -github.com/aws/smithy-go v1.22.3/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= -github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.9.1 h1:50sS0RWhGpW/yZx2KcDNEb1u1MANv5BMEkJgcieEDTA= -github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.9.1/go.mod h1:ErZOtbzuHabipRTDTor0inoRlYwbsV1ovwSxjGs/uJo= +github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ= +github.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk= +github.com/aws/aws-sdk-go-v2 v1.40.0 h1:/WMUA0kjhZExjOQN2z3oLALDREea1A7TobfuiBrKlwc= +github.com/aws/aws-sdk-go-v2 v1.40.0/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE= +github.com/aws/aws-sdk-go-v2/config v1.32.2 h1:4liUsdEpUUPZs5WVapsJLx5NPmQhQdez7nYFcovrytk= +github.com/aws/aws-sdk-go-v2/config v1.32.2/go.mod h1:l0hs06IFz1eCT+jTacU/qZtC33nvcnLADAPL/XyrkZI= +github.com/aws/aws-sdk-go-v2/credentials v1.19.2 h1:qZry8VUyTK4VIo5aEdUcBjPZHL2v4FyQ3QEOaWcFLu4= +github.com/aws/aws-sdk-go-v2/credentials v1.19.2/go.mod h1:YUqm5a1/kBnoK+/NY5WEiMocZihKSo15/tJdmdXnM5g= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.14 h1:WZVR5DbDgxzA0BJeudId89Kmgy6DIU4ORpxwsVHz0qA= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.14/go.mod h1:Dadl9QO0kHgbrH1GRqGiZdYtW5w+IXXaBNCHTIaheM4= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 h1:PZHqQACxYb8mYgms4RZbhZG0a7dPW06xOjmaH0EJC/I= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14/go.mod h1:VymhrMJUWs69D8u0/lZ7jSB6WgaG/NqHi3gX0aYf6U0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 h1:bOS19y6zlJwagBfHxs0ESzr1XCOU2KXJCWcq3E2vfjY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14/go.mod h1:1ipeGBMAxZ0xcTm6y6paC2C/J6f6OO7LBODV9afuAyM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= +github.com/aws/aws-sdk-go-v2/service/ecr v1.51.2 h1:aq2N/9UkbEyljIQ7OFcudEgUsJzO8MYucmfsM/k/dmc= +github.com/aws/aws-sdk-go-v2/service/ecr v1.51.2/go.mod h1:1NVD1KuMjH2GqnPwMotPndQaT/MreKkWpjkF12d6oKU= +github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.38.2 h1:9fe6w8bydUwNAhFVmjo+SRqAJjbBMOyILL/6hTTVkyA= +github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.38.2/go.mod h1:x7gU4CAyAz4BsM9hlRkhHiYw2GIr1QCmN45uwQw9l/E= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 h1:x2Ibm/Af8Fi+BH+Hsn9TXGdT+hKbDd5XOTZxTMxDk7o= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3/go.mod h1:IW1jwyrQgMdhisceG8fQLmQIydcT/jWY21rFhzgaKwo= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.14 h1:FIouAnCE46kyYqyhs0XEBDFFSREtdnr8HQuLPQPLCrY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.14/go.mod h1:UTwDc5COa5+guonQU8qBikJo1ZJ4ln2r1MkF7Dqag1E= +github.com/aws/aws-sdk-go-v2/service/kms v1.49.1 h1:U0asSZ3ifpuIehDPkRI2rxHbmFUMplDA2VeR9Uogrmw= +github.com/aws/aws-sdk-go-v2/service/kms v1.49.1/go.mod h1:NZo9WJqQ0sxQ1Yqu1IwCHQFQunTms2MlVgejg16S1rY= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.2 h1:MxMBdKTYBjPQChlJhi4qlEueqB1p1KcbTEa7tD5aqPs= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.2/go.mod h1:iS6EPmNeqCsGo+xQmXv0jIMjyYtQfnwg36zl2FwEouk= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.5 h1:ksUT5KtgpZd3SAiFJNJ0AFEJVva3gjBmN7eXUZjzUwQ= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.5/go.mod h1:av+ArJpoYf3pgyrj6tcehSFW+y9/QvAY8kMooR9bZCw= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.10 h1:GtsxyiF3Nd3JahRBJbxLCCdYW9ltGQYrFWg8XdkGDd8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.10/go.mod h1:/j67Z5XBVDx8nZVp9EuFM9/BS5dvBznbqILGuu73hug= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.2 h1:a5UTtD4mHBU3t0o6aHQZFJTNKVfxFWfPX7J0Lr7G+uY= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.2/go.mod h1:6TxbXoDSgBQ225Qd8Q+MbxUxUh6TtNKwbRt/EPS9xso= +github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk= +github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= +github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.11.0 h1:GOPttfOAf5qAgx7r6b+zCWZrvCsfKffkL4H6mSYx1kA= +github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.11.0/go.mod h1:a2HN6+p7k0JLDO8514sMr0l4cnrR52z4sWoZ/Uc82ho= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -1542,22 +1548,23 @@ github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHf github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/buildkite/agent/v3 v3.98.2 h1:VOOxv8XD8HVCtEvtRPQhvB6k2Gorha2gN1wGh94gYAA= -github.com/buildkite/agent/v3 v3.98.2/go.mod h1:+zCvvo/OlOwfs+AH3QvSn37H3cBXP3Fe18eoSbqUvnY= -github.com/buildkite/go-pipeline v0.13.3 h1:llI7sAdZ7sqYE7r8ePlmDADRhJ1K0Kua2+gv74Z9+Es= -github.com/buildkite/go-pipeline v0.13.3/go.mod h1:1uC2XdHkTV1G5jYv9K8omERIwrsYbBruBrPx1Zu1uFw= +github.com/buildkite/agent/v3 v3.114.1 h1:UpSJmnOjoep5YQyMC7rHeCx4cSRKoBZvEtZGW2akQA0= +github.com/buildkite/agent/v3 v3.114.1/go.mod h1:KJOGdrc9M4VNAkSesOrSNHIXXdQ3esyqEOCptmuFTQs= +github.com/buildkite/go-pipeline v0.16.0 h1:wEgWUMRAgSg1ZnWOoA3AovtYYdTvN0dLY1zwUWmPP+4= +github.com/buildkite/go-pipeline v0.16.0/go.mod h1:VE37qY3X5pmAKKUMoDZvPsHOQuyakB9cmXj9Qn6QasA= github.com/buildkite/interpolate v0.1.5 h1:v2Ji3voik69UZlbfoqzx+qfcsOKLA61nHdU79VV+tPU= github.com/buildkite/interpolate v0.1.5/go.mod h1:dHnrwHew5O8VNOAgMDpwRlFnhL5VSN6M1bHVmRZ9Ccc= -github.com/buildkite/roko v1.3.1 h1:t7K30ceLLYn6k7hQP4oq1c7dVlhgD5nRcuSRDEEnY1s= -github.com/buildkite/roko v1.3.1/go.mod h1:23R9e6nHxgedznkwwfmqZ6+0VJZJZ2Sg/uVcp2cP46I= -github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA= -github.com/bytecodealliance/wasmtime-go/v3 v3.0.2/go.mod h1:RnUjnIXxEJcL6BgCvNyzCCRzZcxCgsZCi+RNlvYor5Q= +github.com/buildkite/roko v1.4.0 h1:DxixoCdpNqxu4/1lXrXbfsKbJSd7r1qoxtef/TT2J80= +github.com/buildkite/roko v1.4.0/go.mod h1:0vbODqUFEcVf4v2xVXRfZZRsqJVsCCHTG/TBRByGK4E= +github.com/bytecodealliance/wasmtime-go/v37 v37.0.0 h1:DPjdn2V3JhXHMoZ2ymRqGK+y1bDyr9wgpyYCvhjMky8= +github.com/bytecodealliance/wasmtime-go/v37 v37.0.0/go.mod h1:Pf1l2JCTUFMnOqDIwkjzx1qfVJ09xbaXETKgRVE4jZ0= +github.com/cenkalti/backoff v1.1.1-0.20171020064038-309aa717adbf h1:yxlp0s+Sge9UsKEK0Bsvjiopb9XRk+vxylmZ9eGBfm8= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= @@ -1620,13 +1627,13 @@ github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUo github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ= github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w= -github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8= -github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU= +github.com/containerd/stargz-snapshotter/estargz v0.18.1 h1:cy2/lpgBXDA3cDKSyEfNOFMA/c10O1axL69EU7iirO8= +github.com/containerd/stargz-snapshotter/estargz v0.18.1/go.mod h1:ALIEqa7B6oVDsrF37GkGN20SuvG/pIMm7FwP7ZmRb0Q= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-oidc/v3 v3.15.0 h1:R6Oz8Z4bqWR7VFQ+sPSvZPQv4x8M+sJkDO5ojgwlyAg= -github.com/coreos/go-oidc/v3 v3.15.0/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU= +github.com/coreos/go-oidc/v3 v3.17.0 h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNvehc= +github.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -1645,16 +1652,18 @@ github.com/creack/pty v1.1.19 h1:tUN6H7LWqNx4hQVxomd0CVsDwaDr9gaRQaI4GpSmrsA= github.com/creack/pty v1.1.19/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q= github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= -github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= -github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= +github.com/danieljoos/wincred v1.2.3 h1:v7dZC2x32Ut3nEfRH+vhoZGvN72+dQ/snVXo/vMFLdQ= +github.com/danieljoos/wincred v1.2.3/go.mod h1:6qqX0WNrS4RzPZ1tnroDzq9kY3fu1KwE7MRLQK4X0bs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/depcheck-test/depcheck-test v0.0.0-20220607135614-199033aaa936 h1:foGzavPWwtoyBvjWyKJYDYsyzy+23iBV7NKTwdk+LRY= github.com/depcheck-test/depcheck-test v0.0.0-20220607135614-199033aaa936/go.mod h1:ttKPnOepYt4LLzD+loXQ1rT6EmpyIYHro7TAJuIIlHo= -github.com/dgraph-io/badger/v4 v4.7.0 h1:Q+J8HApYAY7UMpL8d9owqiB+odzEc0zn/aqOD9jhc6Y= -github.com/dgraph-io/badger/v4 v4.7.0/go.mod h1:He7TzG3YBy3j4f5baj5B7Zl2XyfNe5bl4Udl0aPemVA= +github.com/dgraph-io/badger/v4 v4.8.0 h1:JYph1ChBijCw8SLeybvPINizbDKWZ5n/GYbz2yhN/bs= +github.com/dgraph-io/badger/v4 v4.8.0/go.mod h1:U6on6e8k/RTbUWxqKR0MvugJuVmkxSNc79ap4917h4w= github.com/dgraph-io/ristretto/v2 v2.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM= github.com/dgraph-io/ristretto/v2 v2.2.0/go.mod h1:RZrm63UmcBAaYWC1DotLYBmTvgkrs0+XhBd7Npn7/zI= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -1668,12 +1677,12 @@ github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 h1:lxmTCgmHE1G github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7/go.mod h1:GvWntX9qiTlOud0WkQ6ewFm0LPy5JUR1Xo0Ngbd1w6Y= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= -github.com/docker/cli v28.2.2+incompatible h1:qzx5BNUDFqlvyq4AHzdNB7gSyVTmU4cgsyN9SdInc1A= -github.com/docker/cli v28.2.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v29.0.3+incompatible h1:8J+PZIcF2xLd6h5sHPsp5pvvJA+Sr2wGQxHkRl53a1E= +github.com/docker/cli v29.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= -github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= +github.com/docker/docker-credential-helpers v0.9.4 h1:76ItO69/AP/V4yT9V4uuuItG0B1N8hvt0T0c0NN/DzI= +github.com/docker/docker-credential-helpers v0.9.4/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= @@ -1682,8 +1691,8 @@ github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emicklei/proto v1.13.4 h1:myn1fyf8t7tAqIzV91Tj9qXpvyXXGXk8OS2H6IBSc9g= -github.com/emicklei/proto v1.13.4/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= +github.com/emicklei/proto v1.14.2 h1:wJPxPy2Xifja9cEMrcA/g08art5+7CGJNFNk35iXC1I= +github.com/emicklei/proto v1.14.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -1742,8 +1751,8 @@ github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXE github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= -github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE= +github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= @@ -1754,8 +1763,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= -github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY= -github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -1786,58 +1793,64 @@ github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU= -github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= -github.com/go-openapi/errors v0.22.1 h1:kslMRRnK7NCb/CvR1q1VWuEQCEIsBGn5GgKD9e+HYhU= -github.com/go-openapi/errors v0.22.1/go.mod h1:+n/5UdIqdVnLIJ6Q9Se8HNGUXYaY6CN8ImWzfi/Gzp0= +github.com/go-openapi/analysis v0.24.1 h1:Xp+7Yn/KOnVWYG8d+hPksOYnCYImE3TieBa7rBOesYM= +github.com/go-openapi/analysis v0.24.1/go.mod h1:dU+qxX7QGU1rl7IYhBC8bIfmWQdX4Buoea4TGtxXY84= +github.com/go-openapi/errors v0.22.4 h1:oi2K9mHTOb5DPW2Zjdzs/NIvwi2N3fARKaTJLdNabaM= +github.com/go-openapi/errors v0.22.4/go.mod h1:z9S8ASTUqx7+CP1Q8dD8ewGH/1JWFFLX/2PmAYNQLgk= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonpointer v0.22.0 h1:TmMhghgNef9YXxTu1tOopo+0BGEytxA+okbry0HjZsM= -github.com/go-openapi/jsonpointer v0.22.0/go.mod h1:xt3jV88UtExdIkkL7NloURjRQjbeUgcxFblMjq2iaiU= +github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= +github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/jsonreference v0.21.1 h1:bSKrcl8819zKiOgxkbVNRUBIr6Wwj9KYrDbMjRs0cDA= -github.com/go-openapi/jsonreference v0.21.1/go.mod h1:PWs8rO4xxTUqKGu+lEvvCxD5k2X7QYkKAepJyCmSTT8= -github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco= -github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs= -github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ= -github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc= -github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY= -github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= -github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c= -github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= +github.com/go-openapi/jsonreference v0.21.3 h1:96Dn+MRPa0nYAR8DR1E03SblB5FJvh7W6krPI0Z7qMc= +github.com/go-openapi/jsonreference v0.21.3/go.mod h1:RqkUP0MrLf37HqxZxrIAtTWW4ZJIK1VzduhXYBEeGc4= +github.com/go-openapi/loads v0.23.2 h1:rJXAcP7g1+lWyBHC7iTY+WAF0rprtM+pm8Jxv1uQJp4= +github.com/go-openapi/loads v0.23.2/go.mod h1:IEVw1GfRt/P2Pplkelxzj9BYFajiWOtY2nHZNj4UnWY= +github.com/go-openapi/runtime v0.29.2 h1:UmwSGWNmWQqKm1c2MGgXVpC2FTGwPDQeUsBMufc5Yj0= +github.com/go-openapi/runtime v0.29.2/go.mod h1:biq5kJXRJKBJxTDJXAa00DOTa/anflQPhT0/wmjuy+0= +github.com/go-openapi/spec v0.22.1 h1:beZMa5AVQzRspNjvhe5aG1/XyBSMeX1eEOs7dMoXh/k= +github.com/go-openapi/spec v0.22.1/go.mod h1:c7aeIQT175dVowfp7FeCvXXnjN/MrpaONStibD2WtDA= +github.com/go-openapi/strfmt v0.25.0 h1:7R0RX7mbKLa9EYCTHRcCuIPcaqlyQiWNPTXwClK0saQ= +github.com/go-openapi/strfmt v0.25.0/go.mod h1:nNXct7OzbwrMY9+5tLX4I21pzcmE6ccMGXl3jFdPfn8= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-openapi/swag v0.24.1 h1:DPdYTZKo6AQCRqzwr/kGkxJzHhpKxZ9i/oX0zag+MF8= -github.com/go-openapi/swag v0.24.1/go.mod h1:sm8I3lCPlspsBBwUm1t5oZeWZS0s7m/A+Psg0ooRU0A= -github.com/go-openapi/swag/cmdutils v0.24.0 h1:KlRCffHwXFI6E5MV9n8o8zBRElpY4uK4yWyAMWETo9I= -github.com/go-openapi/swag/cmdutils v0.24.0/go.mod h1:uxib2FAeQMByyHomTlsP8h1TtPd54Msu2ZDU/H5Vuf8= -github.com/go-openapi/swag/conv v0.24.0 h1:ejB9+7yogkWly6pnruRX45D1/6J+ZxRu92YFivx54ik= -github.com/go-openapi/swag/conv v0.24.0/go.mod h1:jbn140mZd7EW2g8a8Y5bwm8/Wy1slLySQQ0ND6DPc2c= -github.com/go-openapi/swag/fileutils v0.24.0 h1:U9pCpqp4RUytnD689Ek/N1d2N/a//XCeqoH508H5oak= -github.com/go-openapi/swag/fileutils v0.24.0/go.mod h1:3SCrCSBHyP1/N+3oErQ1gP+OX1GV2QYFSnrTbzwli90= -github.com/go-openapi/swag/jsonname v0.24.0 h1:2wKS9bgRV/xB8c62Qg16w4AUiIrqqiniJFtZGi3dg5k= -github.com/go-openapi/swag/jsonname v0.24.0/go.mod h1:GXqrPzGJe611P7LG4QB9JKPtUZ7flE4DOVechNaDd7Q= -github.com/go-openapi/swag/jsonutils v0.24.0 h1:F1vE1q4pg1xtO3HTyJYRmEuJ4jmIp2iZ30bzW5XgZts= -github.com/go-openapi/swag/jsonutils v0.24.0/go.mod h1:vBowZtF5Z4DDApIoxcIVfR8v0l9oq5PpYRUuteVu6f0= -github.com/go-openapi/swag/loading v0.24.0 h1:ln/fWTwJp2Zkj5DdaX4JPiddFC5CHQpvaBKycOlceYc= -github.com/go-openapi/swag/loading v0.24.0/go.mod h1:gShCN4woKZYIxPxbfbyHgjXAhO61m88tmjy0lp/LkJk= -github.com/go-openapi/swag/mangling v0.24.0 h1:PGOQpViCOUroIeak/Uj/sjGAq9LADS3mOyjznmHy2pk= -github.com/go-openapi/swag/mangling v0.24.0/go.mod h1:Jm5Go9LHkycsz0wfoaBDkdc4CkpuSnIEf62brzyCbhc= -github.com/go-openapi/swag/netutils v0.24.0 h1:Bz02HRjYv8046Ycg/w80q3g9QCWeIqTvlyOjQPDjD8w= -github.com/go-openapi/swag/netutils v0.24.0/go.mod h1:WRgiHcYTnx+IqfMCtu0hy9oOaPR0HnPbmArSRN1SkZM= -github.com/go-openapi/swag/stringutils v0.24.0 h1:i4Z/Jawf9EvXOLUbT97O0HbPUja18VdBxeadyAqS1FM= -github.com/go-openapi/swag/stringutils v0.24.0/go.mod h1:5nUXB4xA0kw2df5PRipZDslPJgJut+NjL7D25zPZ/4w= -github.com/go-openapi/swag/typeutils v0.24.0 h1:d3szEGzGDf4L2y1gYOSSLeK6h46F+zibnEas2Jm/wIw= -github.com/go-openapi/swag/typeutils v0.24.0/go.mod h1:q8C3Kmk/vh2VhpCLaoR2MVWOGP8y7Jc8l82qCTd1DYI= -github.com/go-openapi/swag/yamlutils v0.24.0 h1:bhw4894A7Iw6ne+639hsBNRHg9iZg/ISrOVr+sJGp4c= -github.com/go-openapi/swag/yamlutils v0.24.0/go.mod h1:DpKv5aYuaGm/sULePoeiG8uwMpZSfReo1HR3Ik0yaG8= -github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= -github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= +github.com/go-openapi/validate v0.25.1 h1:sSACUI6Jcnbo5IWqbYHgjibrhhmt3vR6lCzKZnmAgBw= +github.com/go-openapi/validate v0.25.1/go.mod h1:RMVyVFYte0gbSTaZ0N4KmTn6u/kClvAFp+mAVfS/DQc= github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= -github.com/go-piv/piv-go/v2 v2.3.0 h1:kKkrYlgLQTMPA6BiSL25A7/x4CEh2YCG7rtb/aTkx+g= -github.com/go-piv/piv-go/v2 v2.3.0/go.mod h1:ShZi74nnrWNQEdWzRUd/3cSig3uNOcEZp+EWl0oewnI= +github.com/go-piv/piv-go/v2 v2.4.0 h1:xamQ/fR4MJiw/Ndbk6yi7MVwhjrwlnDAPuaH9zcGb+I= +github.com/go-piv/piv-go/v2 v2.4.0/go.mod h1:ShZi74nnrWNQEdWzRUd/3cSig3uNOcEZp+EWl0oewnI= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= @@ -1846,16 +1859,14 @@ github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7 github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= github.com/go-rod/rod v0.116.2 h1:A5t2Ky2A+5eD/ZJQr1EfsQSe5rms5Xof/qj296e+ZqA= github.com/go-rod/rod v0.116.2/go.mod h1:H+CMO9SCNc2TJ2WfrG+pKhITz57uGNYU43qYHh438Mg= -github.com/go-sql-driver/mysql v1.9.2 h1:4cNKDYQ1I84SXslGddlsrMhc8k4LeDVj6Ad6WRjiHuU= -github.com/go-sql-driver/mysql v1.9.2/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= +github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= -github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= @@ -1870,6 +1881,8 @@ github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-yaml v1.9.8/go.mod h1:JubOolP3gh0HpiBc4BLRD4YmjEjHAmIIB2aaXKkTfoE= github.com/goccy/go-yaml v1.11.0/go.mod h1:H+mJrWtjPTJAHvRbV09MCK9xYwODM+wRTVFFTWckfng= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -1885,8 +1898,8 @@ github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= @@ -1967,10 +1980,10 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU= -github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y= -github.com/google/go-github/v72 v72.0.0 h1:FcIO37BLoVPBO9igQQ6tStsv2asG4IPcYFi655PPvBM= -github.com/google/go-github/v72 v72.0.0/go.mod h1:WWtw8GMRiL62mvIquf1kO3onRHeWWKmK01qdCY8c5fg= +github.com/google/go-containerregistry v0.20.7 h1:24VGNpS0IwrOZ2ms2P1QE3Xa5X9p4phx0aUgzYzHW6I= +github.com/google/go-containerregistry v0.20.7/go.mod h1:Lx5LCZQjLH1QBaMPeGwsME9biPeo1lPx6lbGj/UmzgM= +github.com/google/go-github/v73 v73.0.0 h1:aR+Utnh+Y4mMkS+2qLQwcQ/cF9mOTpdwnzlaw//rG24= +github.com/google/go-github/v73 v73.0.0/go.mod h1:fa6w8+/V+edSU0muqdhCVY7Beh1M8F1IlQPZIANKIYw= github.com/google/go-pkcs11 v0.2.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= @@ -2005,8 +2018,8 @@ github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwg github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= -github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= +github.com/google/pprof v0.0.0-20250602020802-c6617b811d0e h1:FJta/0WsADCe1r9vQjdHbd3KuiLPu7Y9WlyLGwMUNyE= +github.com/google/pprof v0.0.0-20250602020802-c6617b811d0e/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= @@ -2032,8 +2045,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5 github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= -github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= +github.com/googleapis/enterprise-certificate-proxy v0.3.7 h1:zrn2Ee/nWmHulBx5sAVrGgAa0f2/R35S4DJwfFaUPFQ= +github.com/googleapis/enterprise-certificate-proxy v0.3.7/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -2057,13 +2070,13 @@ github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+ github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= @@ -2073,8 +2086,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= @@ -2115,14 +2128,14 @@ github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= -github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= +github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I= +github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/vault/api v1.16.0 h1:nbEYGJiAPGzT9U4oWgaaB0g+Rj8E59QuHKyA5LhwQN4= -github.com/hashicorp/vault/api v1.16.0/go.mod h1:KhuUhzOD8lDSk29AtzNjgAu2kxRA9jL9NAbkFlqvkBA= +github.com/hashicorp/vault/api v1.22.0 h1:+HYFquE35/B74fHoIeXlZIP2YADVboaPjaSicHEZiH0= +github.com/hashicorp/vault/api v1.22.0/go.mod h1:IUZA2cDvr4Ok3+NtK2Oq/r+lJeXkeCrHRmqdyWfpmGM= github.com/henvic/httpretty v0.0.6 h1:JdzGzKZBajBfnvlMALXXMVQWxWMF/ofTy8C3/OSUTxs= github.com/henvic/httpretty v0.0.6/go.mod h1:X38wLjWXHkXT7r2+uK8LjCMne9rsuNaBLJ+5cU2/Pmo= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= @@ -2138,8 +2151,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/in-toto/attestation v1.1.1 h1:QD3d+oATQ0dFsWoNh5oT0udQ3tUrOsZZ0Fc3tSgWbzI= -github.com/in-toto/attestation v1.1.1/go.mod h1:Dcq1zVwA2V7Qin8I7rgOi+i837wEf/mOZwRm047Sjys= +github.com/in-toto/attestation v1.1.2 h1:MBFn6lsMq6dptQZJBhalXTcWMb/aJy3V+GX3VYj/V1E= +github.com/in-toto/attestation v1.1.2/go.mod h1:gYFddHMZj3DiQ0b62ltNi1Vj5rC879bTmBbrv9CRHpM= github.com/in-toto/in-toto-golang v0.9.0 h1:tHny7ac4KgtsfrG6ybU8gVOZux2H8jN05AXJ9EBM1XU= github.com/in-toto/in-toto-golang v0.9.0/go.mod h1:xsBVrVsHNsB61++S6Dy2vWosKhuA3lUTQd+eF9HdeMo= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -2156,20 +2169,17 @@ github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 h1:TMtDYDHKYY15rFihtRfck/bfFqNfvcabqvXAFQfAUpY= github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= -github.com/jellydator/ttlcache/v3 v3.3.0 h1:BdoC9cE81qXfrxeb9eoJi9dWrdhSuwXMAnHTbnBm4Wc= -github.com/jellydator/ttlcache/v3 v3.3.0/go.mod h1:bj2/e0l4jRnQdrnSTaGTsh4GSXvMjQcy41i7th0GVGw= +github.com/jellydator/ttlcache/v3 v3.4.0 h1:YS4P125qQS0tNhtL6aeYkheEaB/m8HCqdMMP4mnWdTY= +github.com/jellydator/ttlcache/v3 v3.4.0/go.mod h1:Hw9EgjymziQD3yGsQdf1FqFdpp7YjFMd4Srg5EJlgD4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 h1:liMMTbpW34dhU4az1GN0pTPADwNmvoRSeoZ6PItiqnY= github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmhodges/clock v1.2.0 h1:eq4kys+NI0PLngzaHEe7AmPT90XMGIEySD1JfV1PDIs= -github.com/jmhodges/clock v1.2.0/go.mod h1:qKjhA7x7u/lQpPB1XAqX1b1lCI/w3/fNuYpI/ZjLynI= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -2194,8 +2204,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= +github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -2217,20 +2227,34 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec h1:2tTW6cDth2TSgRbAhD7yjZzTQmcN25sDRPEeinR51yQ= -github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec/go.mod h1:TmwEoGCwIti7BCeJ9hescZgRtatxRE+A72pCoPfmcfk= +github.com/lestrrat-go/blackmagic v1.0.4 h1:IwQibdnf8l2KoO+qC3uT4OaTWsW7tuRQXy9TRN9QanA= +github.com/lestrrat-go/blackmagic v1.0.4/go.mod h1:6AWFyKNNj0zEXQYfTMPfZrAXUWUfTIZ5ECEUEJaijtw= +github.com/lestrrat-go/dsig v1.0.0 h1:OE09s2r9Z81kxzJYRn07TFM9XA4akrUdoMwr0L8xj38= +github.com/lestrrat-go/dsig v1.0.0/go.mod h1:dEgoOYYEJvW6XGbLasr8TFcAxoWrKlbQvmJgCR0qkDo= +github.com/lestrrat-go/dsig-secp256k1 v1.0.0 h1:JpDe4Aybfl0soBvoVwjqDbp+9S1Y2OM7gcrVVMFPOzY= +github.com/lestrrat-go/dsig-secp256k1 v1.0.0/go.mod h1:CxUgAhssb8FToqbL8NjSPoGQlnO4w3LG1P0qPWQm/NU= +github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= +github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= +github.com/lestrrat-go/httprc/v3 v3.0.1 h1:3n7Es68YYGZb2Jf+k//llA4FTZMl3yCwIjFIk4ubevI= +github.com/lestrrat-go/httprc/v3 v3.0.1/go.mod h1:2uAvmbXE4Xq8kAUjVrZOq1tZVYYYs5iP62Cmtru00xk= +github.com/lestrrat-go/jwx/v3 v3.0.11 h1:yEeUGNUuNjcez/Voxvr7XPTYNraSQTENJgtVTfwvG/w= +github.com/lestrrat-go/jwx/v3 v3.0.11/go.mod h1:XSOAh2SiXm0QgRe3DulLZLyt+wUuEdFo81zuKTLcvgQ= +github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= +github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/option/v2 v2.0.0 h1:XxrcaJESE1fokHy3FpaQ/cXW8ZsIdWcdFzzLOcID3Ss= +github.com/lestrrat-go/option/v2 v2.0.0/go.mod h1:oSySsmzMoR0iRzCDCaUfsCzxQHUEuhOViQObyy7S6Vg= +github.com/letsencrypt/boulder v0.20251110.0 h1:J8MnKICeilO91dyQ2n5eBbab24neHzUpYMUIOdOtbjc= +github.com/letsencrypt/boulder v0.20251110.0/go.mod h1:ogKCJQwll82m7OVHWyTuf8eeFCjuzdRQlgnZcCl0V+8= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= +github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= -github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/manifestival/client-go-client v0.6.0 h1:7vV7th1Y48LlJ3UWcR57JYD/h7Oo0Dm0ffmwj8xoEVE= github.com/manifestival/client-go-client v0.6.0/go.mod h1:2x6VHJ9/2It3TknttgiDgrdhtgwNnCK1JsOh/+3Jld0= github.com/manifestival/manifestival v0.7.1/go.mod h1:nl3T6HlfHCeidooWVTMI9vYNTBkQ1GdhLNb+smozbdk= @@ -2254,9 +2278,8 @@ github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.17 h1:78v8ZlW0bP43XfmAfPsdXcoNCelfMHsDmd/pkENfrjQ= +github.com/mattn/go-runewidth v0.0.17/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= @@ -2268,8 +2291,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= +github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= @@ -2291,6 +2314,8 @@ github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1 github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= +github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -2303,13 +2328,15 @@ github.com/mozillazg/docker-credential-acr-helper v0.4.0 h1:Uoh3Z9CcpEDnLiozDx+D github.com/mozillazg/docker-credential-acr-helper v0.4.0/go.mod h1:2kiicb3OlPytmlNC9XGkLvVC+f0qTiJw3f/mhmeeQBg= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= -github.com/muesli/termenv v0.12.0 h1:KuQRUE3PgxRFWhq4gHvZtPSLCGDqM5q/cYr1pZ39ytc= -github.com/muesli/termenv v0.12.0/go.mod h1:WCCv32tusQ/EEZ5S8oUIIrC/nIuBcxCVqlN4Xfkv+7A= +github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= +github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A= +github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 h1:Up6+btDp321ZG5/zdSLo48H9Iaq0UQGthrhWC6pCxzE= github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481/go.mod h1:yKZQO8QE2bHlgozqWDiRVqTFlLQSj30K/6SAK8EeYFw= @@ -2371,8 +2398,8 @@ github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeD github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= -github.com/open-policy-agent/opa v1.5.1 h1:LTxxBJusMVjfs67W4FoRcnMfXADIGFMzpqnfk6D08Cg= -github.com/open-policy-agent/opa v1.5.1/go.mod h1:bYbS7u+uhTI+cxHQIpzvr5hxX0hV7urWtY+38ZtjMgk= +github.com/open-policy-agent/opa v1.10.1 h1:haIvxZSPky8HLjRrvQwWAjCPLg8JDFSZMbbG4yyUHgY= +github.com/open-policy-agent/opa v1.10.1/go.mod h1:7uPI3iRpOalJ0BhK6s1JALWPU9HvaV1XeBSSMZnr/PM= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -2386,8 +2413,6 @@ github.com/openshift/apiserver-library-go v0.0.0-20230816171015-6bfafa975bfb/go. github.com/openshift/client-go v0.0.0-20240523113335-452272e0496d h1:Dq21KMlDTVy2fCIyp0gsW+6ir6FwD3RjnCuza2/bIyM= github.com/openshift/client-go v0.0.0-20240523113335-452272e0496d/go.mod h1:jt2Q+6Iheyh6omSPkRMOC6Doad5My/FfBfJpATPD4g0= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= @@ -2459,8 +2484,8 @@ github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= -github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= -github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -2478,10 +2503,10 @@ github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9 github.com/prometheus/statsd_exporter v0.28.0 h1:S3ZLyLm/hOKHYZFOF0h4zYmd0EeKyPF9R1pFBYXUgYY= github.com/prometheus/statsd_exporter v0.28.0/go.mod h1:Lq41vNkMLfiPANmI+uHb5/rpFFUTxPXiiNpmsAYLvDI= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d h1:HWfigq7lB31IeJL8iy7jkUmU/PG1Sr8jVGhS749dbUA= -github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/protocolbuffers/txtpbfmt v0.0.0-20251016062345-16587c79cd91 h1:s1LvMaU6mVwoFtbxv/rCZKE7/fwDmDY684FfUe4c1Io= +github.com/protocolbuffers/txtpbfmt v0.0.0-20251016062345-16587c79cd91/go.mod h1:JSbkp0BviKovYYt9XunS95M3mLPibE9bGg+Y95DsEEY= +github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 h1:bsUq1dX0N8AOIL7EB/X911+m4EHsnWEHeJ0c+3TTBrg= +github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -2511,45 +2536,48 @@ github.com/sassoftware/relic v7.2.1+incompatible/go.mod h1:CWfAxv73/iLZ17rbyhIEq github.com/sassoftware/relic/v7 v7.6.2 h1:rS44Lbv9G9eXsukknS4mSjIAuuX+lMq/FnStgmZlUv4= github.com/sassoftware/relic/v7 v7.6.2/go.mod h1:kjmP0IBVkJZ6gXeAu35/KCEfca//+PKM6vTAsyDPY+k= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/secure-systems-lab/go-securesystemslib v0.9.0 h1:rf1HIbL64nUpEIZnjLZ3mcNEL9NBPB0iuVjyxvq3LZc= -github.com/secure-systems-lab/go-securesystemslib v0.9.0/go.mod h1:DVHKMcZ+V4/woA/peqr+L0joiRXbPpQ042GgJckkFgw= -github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= -github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= -github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= -github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/secure-systems-lab/go-securesystemslib v0.9.1 h1:nZZaNz4DiERIQguNy0cL5qTdn9lR8XKHf4RUyG1Sx3g= +github.com/secure-systems-lab/go-securesystemslib v0.9.1/go.mod h1:np53YzT0zXGMv6x4iEWc9Z59uR+x+ndLwCLqPYpLXVU= +github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= +github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= +github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= +github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI= github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sigstore/cosign/v2 v2.5.2 h1:i5Dw7M7W9OcWgyiknJB8vNx/07KweninBDxRoHPxqHE= -github.com/sigstore/cosign/v2 v2.5.2/go.mod h1:CYlcgkPQJZ5pvWlbl7mOfO/Q1S1N7r4tpdYCtFwhXco= -github.com/sigstore/fulcio v1.7.1 h1:RcoW20Nz49IGeZyu3y9QYhyyV3ZKQ85T+FXPKkvE+aQ= -github.com/sigstore/fulcio v1.7.1/go.mod h1:7lYY+hsd8Dt+IvKQRC+KEhWpCZ/GlmNvwIa5JhypMS8= -github.com/sigstore/protobuf-specs v0.4.3 h1:kRgJ+ciznipH9xhrkAbAEHuuxD3GhYnGC873gZpjJT4= -github.com/sigstore/protobuf-specs v0.4.3/go.mod h1:+gXR+38nIa2oEupqDdzg4qSBT0Os+sP7oYv6alWewWc= -github.com/sigstore/rekor v1.3.10 h1:/mSvRo4MZ/59ECIlARhyykAlQlkmeAQpvBPlmJtZOCU= -github.com/sigstore/rekor v1.3.10/go.mod h1:JvryKJ40O0XA48MdzYUPu0y4fyvqt0C4iSY7ri9iu3A= -github.com/sigstore/sigstore v1.9.5 h1:Wm1LT9yF4LhQdEMy5A2JeGRHTrAWGjT3ubE5JUSrGVU= -github.com/sigstore/sigstore v1.9.5/go.mod h1:VtxgvGqCmEZN9X2zhFSOkfXxvKUjpy8RpUW39oCtoII= -github.com/sigstore/sigstore-go v1.0.0 h1:4N07S2zLxf09nTRwaPKyAxbKzpM8WJYUS8lWWaYxneU= -github.com/sigstore/sigstore-go v1.0.0/go.mod h1:UYsZ/XHE4eltv1o1Lu+n6poW1Z5to3f0+emvfXNxIN8= -github.com/sigstore/sigstore/pkg/signature/kms/aws v1.9.5 h1:qp2VFyKuFQvTGmZwk5Q7m5nE4NwnF9tHwkyz0gtWAck= -github.com/sigstore/sigstore/pkg/signature/kms/aws v1.9.5/go.mod h1:DKlQjjr+GsWljEYPycI0Sf8URLCk4EbGA9qYjF47j4g= -github.com/sigstore/sigstore/pkg/signature/kms/azure v1.9.5 h1:CRZcdYn5AOptStsLRAAACudAVmb1qUbhMlzrvm7ju3o= -github.com/sigstore/sigstore/pkg/signature/kms/azure v1.9.5/go.mod h1:b9rFfITq2fp1M3oJmq6lFFhSrAz5vOEJH1qzbMsZWN4= -github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.9.5 h1:7U0GsO0UGG1PdtgS6wBkRC0sMgq7BRVaFlPRwN4m1Qg= -github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.9.5/go.mod h1:/2qrI0nnCy/DTIPOMFaZlFnNPWEn5UeS70P37XEM88o= -github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.9.5 h1:S2ukEfN1orLKw2wEQIUHDDlzk0YcylhcheeZ5TGk8LI= -github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.9.5/go.mod h1:m7sQxVJmDa+rsmS1m6biQxaLX83pzNS7ThUEyjOqkCU= -github.com/sigstore/timestamp-authority v1.2.8 h1:BEV3fkphwU4zBp3allFAhCqQb99HkiyCXB853RIwuEE= -github.com/sigstore/timestamp-authority v1.2.8/go.mod h1:G2/0hAZmLPnevEwT1S9IvtNHUm9Ktzvso6xuRhl94ZY= +github.com/sigstore/cosign/v2 v2.6.1 h1:7Wf67ENNCjg+1fLqHRPgKUNaCCnCavnEfCe1LApOoIo= +github.com/sigstore/cosign/v2 v2.6.1/go.mod h1:L37doL+7s6IeCXFODV2J7kds5Po/srlVzA//++YqAJ8= +github.com/sigstore/fulcio v1.8.3 h1:zkuAkRHbD53hhYGlBHHeAW4NRDrrTiDHumAbcfSyyFw= +github.com/sigstore/fulcio v1.8.3/go.mod h1:YxP7TTdn9H5Gg+dXOsu61X36LLYxT2ZuvODhWelMNwA= +github.com/sigstore/protobuf-specs v0.5.0 h1:F8YTI65xOHw70NrvPwJ5PhAzsvTnuJMGLkA4FIkofAY= +github.com/sigstore/protobuf-specs v0.5.0/go.mod h1:+gXR+38nIa2oEupqDdzg4qSBT0Os+sP7oYv6alWewWc= +github.com/sigstore/rekor v1.4.3 h1:2+aw4Gbgumv8vYM/QVg6b+hvr4x4Cukur8stJrVPKU0= +github.com/sigstore/rekor v1.4.3/go.mod h1:o0zgY087Q21YwohVvGwV9vK1/tliat5mfnPiVI3i75o= +github.com/sigstore/rekor-tiles/v2 v2.0.1 h1:1Wfz15oSRNGF5Dzb0lWn5W8+lfO50ork4PGIfEKjZeo= +github.com/sigstore/rekor-tiles/v2 v2.0.1/go.mod h1:Pjsbhzj5hc3MKY8FfVTYHBUHQEnP0ozC4huatu4x7OU= +github.com/sigstore/sigstore v1.10.3 h1:s7fBYYOzW/2Vd0nND2ZdpWySb5vRF2u9eix/NZMHJm0= +github.com/sigstore/sigstore v1.10.3/go.mod h1:T26vXIkpnGEg391v3TaZ8EERcXbnjtZb/1erh5jbIQk= +github.com/sigstore/sigstore-go v1.1.4-0.20251201121426-2cdedea80894 h1:K8hnZhun6XacjxAdCdxkowSi7+FpmfYnAcMhTXZQyPg= +github.com/sigstore/sigstore-go v1.1.4-0.20251201121426-2cdedea80894/go.mod h1:uuR+Edo6P+iwi0HKscycUm8mxXL748nAureqSg6jFLA= +github.com/sigstore/sigstore/pkg/signature/kms/aws v1.10.0 h1:UOHpiyezCj5RuixgIvCV3QyuxIGQT+N6nGZEXA7OTTY= +github.com/sigstore/sigstore/pkg/signature/kms/aws v1.10.0/go.mod h1:U0CZmA2psabDa8DdiV7yXab0AHODzfKqvD2isH7Hrvw= +github.com/sigstore/sigstore/pkg/signature/kms/azure v1.10.0 h1:fq4+8Y4YadxeF8mzhoMRPZ1mVvDYXmI3BfS0vlkPT7M= +github.com/sigstore/sigstore/pkg/signature/kms/azure v1.10.0/go.mod h1:u05nqPWY05lmcdHhv2lPaWTH3FGUhJzO7iW2hbboK3Q= +github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.10.0 h1:iUEf5MZYOuXGnXxdF/WrarJrk0DTVHqeIOjYdtpVXtc= +github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.10.0/go.mod h1:i6vg5JfEQix46R1rhQlrKmUtJoeH91drltyYOJEk1T4= +github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.10.0 h1:dUvPv/MP23ZPIXZUW45kvCIgC0ZRfYxEof57AB6bAtU= +github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.10.0/go.mod h1:fR/gDdPvJWGWL70/NgBBIL1O0/3Wma6JHs3tSSYg3s4= +github.com/sigstore/timestamp-authority v1.2.9 h1:L9Fj070/EbMC8qUk8BchkrYCS1BT5i93Bl6McwydkFs= +github.com/sigstore/timestamp-authority v1.2.9/go.mod h1:QyRnZchz4o+xdHyK5rvCWacCHxWmpX+mgvJwB1OXcLY= +github.com/sigstore/timestamp-authority/v2 v2.0.3 h1:sRyYNtdED/ttLCMdaYnwpf0zre1A9chvjTnCmWWxN8Y= +github.com/sigstore/timestamp-authority/v2 v2.0.3/go.mod h1:mDaHxkt3HmZYoIlwYj4QWo0RUr7VjYU52aVO5f5Qb3I= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= +github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af h1:Sp5TG9f7K39yfB+If0vjp97vuT74F72r8hfRpP8jLU0= +github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -2617,8 +2645,8 @@ github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSW github.com/substrait-io/substrait-go v0.4.2/go.mod h1:qhpnLmrcvAnlZsUyPXZRqldiHapPTXC3t7xFgDi3aQg= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= -github.com/tchap/go-patricia/v2 v2.3.2 h1:xTHFutuitO2zqKAQ5rCROYgUb7Or/+IC3fts9/Yc7nM= -github.com/tchap/go-patricia/v2 v2.3.2/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= +github.com/tchap/go-patricia/v2 v2.3.3 h1:xfNEsODumaEcCcY3gI0hYPZ/PcpVv5ju6RMAhgwZDDc= +github.com/tchap/go-patricia/v2 v2.3.3/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= github.com/tektoncd/pipeline v1.7.0 h1:+Rd/YGpxV8sgEmW9unSiS8RgBE4DqbPdz6zPh2pYDnk= github.com/tektoncd/pipeline v1.7.0/go.mod h1:+HsDce5knjq77Xv9FWg1W2wTuJRznR9lLEbkVjo62lU= github.com/tektoncd/plumbing v0.0.0-20250805154627-25448098dea2 h1:v4UPEbe6MEto5i4ELtiXWBxUAUIAWL5U1DznfPhi4WE= @@ -2631,8 +2659,8 @@ github.com/thales-e-security/pool v0.0.2 h1:RAPs4q2EbWsTit6tpzuvTFlgFRJ3S8Evf5gt github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU= github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI= github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug= -github.com/theupdateframework/go-tuf/v2 v2.1.1 h1:OWcoHItwsGO+7m0wLa7FDWPR4oB1cj0zOr1kosE4G+I= -github.com/theupdateframework/go-tuf/v2 v2.1.1/go.mod h1:V675cQGhZONR0OGQ8r1feO0uwtsTBYPDWHzAAPn5rjE= +github.com/theupdateframework/go-tuf/v2 v2.3.0 h1:gt3X8xT8qu/HT4w+n1jgv+p7koi5ad8XEkLXXZqG9AA= +github.com/theupdateframework/go-tuf/v2 v2.3.0/go.mod h1:xW8yNvgXRncmovMLvBxKwrKpsOwJZu/8x+aB0KtFcdw= github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e h1:BuzhfgfWQbX0dWzYzT1zsORLnHRv3bcRcsaUk0VmXA8= github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI= github.com/tidwall/gjson v1.14.2 h1:6BBkirS0rAHjumnjHF6qgy5d2YAJ1TLIaFE2lzfOLqo= @@ -2649,8 +2677,8 @@ github.com/tink-crypto/tink-go-gcpkms/v2 v2.2.0 h1:3B9i6XBXNTRspfkTC0asN5W0K6GhO github.com/tink-crypto/tink-go-gcpkms/v2 v2.2.0/go.mod h1:jY5YN2BqD/KSCHM9SqZPIpJNG/u3zwfLXHgws4x2IRw= github.com/tink-crypto/tink-go-hcvault/v2 v2.3.0 h1:6nAX1aRGnkg2SEUMwO5toB2tQkP0Jd6cbmZ/K5Le1V0= github.com/tink-crypto/tink-go-hcvault/v2 v2.3.0/go.mod h1:HOC5NWW1wBI2Vke1FGcRBvDATkEYE7AUDiYbXqi2sBw= -github.com/tink-crypto/tink-go/v2 v2.4.0 h1:8VPZeZI4EeZ8P/vB6SIkhlStrJfivTJn+cQ4dtyHNh0= -github.com/tink-crypto/tink-go/v2 v2.4.0/go.mod h1:l//evrF2Y3MjdbpNDNGnKgCpo5zSmvUvnQ4MU+yE2sw= +github.com/tink-crypto/tink-go/v2 v2.5.0 h1:B8KLF6AofxdBIE4UJIaFbmoj5/1ehEtt7/MmzfI4Zpw= +github.com/tink-crypto/tink-go/v2 v2.5.0/go.mod h1:2WbBA6pfNsAfBwDCggboaHeB2X29wkU8XHtGwh2YIk8= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= @@ -2659,14 +2687,18 @@ github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVc github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= +github.com/transparency-dev/formats v0.0.0-20251017110053-404c0d5b696c h1:5a2XDQ2LiAUV+/RjckMyq9sXudfrPSuCY4FuPC1NyAw= +github.com/transparency-dev/formats v0.0.0-20251017110053-404c0d5b696c/go.mod h1:g85IafeFJZLxlzZCDRu4JLpfS7HKzR+Hw9qRh3bVzDI= github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4= github.com/transparency-dev/merkle v0.0.2/go.mod h1:pqSy+OXefQ1EDUVmAJ8MUhHB9TXGuzVAT58PqBoHz1A= -github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo= -github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= +github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= +github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= +github.com/vbatts/tar-split v0.12.2 h1:w/Y6tjxpeiFMR47yzZPlPj/FcPLpXbTUi/9H7d3CPa4= +github.com/vbatts/tar-split v0.12.2/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= github.com/vdemeester/cr-20160607 v1.0.1 h1:nHyI7BZNR04QFtgItJFVAr8SLeoVIFd8co+DODxnPKE= github.com/vdemeester/cr-20160607 v1.0.1/go.mod h1:QHeKZtZ3F3FOE+/uIXCBAp8POwnUYekpLwr1dtQa5r0= -github.com/vektah/gqlparser/v2 v2.5.26 h1:REqqFkO8+SOEgZHR/eHScjjVjGS8Nk3RMO/juiTobN4= -github.com/vektah/gqlparser/v2 v2.5.26/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo= +github.com/vektah/gqlparser/v2 v2.5.30 h1:EqLwGAFLIzt1wpx1IPpY67DwUujF1OfzgEyDsLrN6kE= +github.com/vektah/gqlparser/v2 v2.5.30/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= @@ -2701,8 +2733,8 @@ github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8u github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= -gitlab.com/gitlab-org/api/client-go v0.145.0 h1:gvi4bwoF6fyQq6kJix4WicApy/jBRpGlqzI0PDRD9kU= -gitlab.com/gitlab-org/api/client-go v0.145.0/go.mod h1:eABRp++g3IbUP10ZeBIys+9g59dgJnlQLEk8XgKNB54= +gitlab.com/gitlab-org/api/client-go v0.160.0 h1:aMQzbcE8zFe0lR/J+a3zneEgH+/EBFs8rD8Chrr4Snw= +gitlab.com/gitlab-org/api/client-go v0.160.0/go.mod h1:ooCNtKB7OyP7GBa279+HrUS3eeJF6Yi6XABZZy7RTSk= go.einride.tech/aip v0.66.0/go.mod h1:qAhMsfT7plxBX+Oy7Huol6YUvZ0ZzdUz26yZsQwfl1M= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= @@ -2714,8 +2746,8 @@ go.etcd.io/etcd/pkg/v3 v3.5.16/go.mod h1:+lutCZHG5MBBFI/U4eYT5yL7sJfnexsoM20Y0t2 go.etcd.io/etcd/raft/v3 v3.5.16/go.mod h1:P4UP14AxofMJ/54boWilabqqWoW9eLodl6I5GdGzazI= go.etcd.io/etcd/server/v3 v3.5.16/go.mod h1:ynhyZZpdDp1Gq49jkUg5mfkDWZwXnn3eIqCqtJnrD/s= go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M= -go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= -go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= +go.mongodb.org/mongo-driver v1.17.6 h1:87JUG1wZfWsr6rIz3ZmpH90rL5tea7O3IHuSwHUpsss= +go.mongodb.org/mongo-driver v1.17.6/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -2725,24 +2757,24 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0/go.mod h1:Ct6zzQEuGK3WpJs2n4dn+wfJYzd/+hNnxMRTWjGn30M= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0/go.mod h1:tIKj3DbO8N9Y2xo52og3irLsPI4GW02DSMtrVgNMgxg= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.1/go.mod h1:9NiG9I2aHTKkcxqCILhjtyNA1QEiCjdBACv4IvrFQ+c= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0/go.mod h1:rdENBZMT2OE6Ne/KLwpiXudnAsbdrdBaqBvTN8M8BgA= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM= go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= @@ -2760,15 +2792,15 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.10.0/go.mod h1:Krqnjl22jUJ0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.20.0/go.mod h1:GijYcYmNpX1KazD5JmWGsi4P7dDTTTnfv1UbGn84MnU= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.10.0/go.mod h1:OfUCyyIiDvNXHWpcWgbF+MWvqPZiNa3YDEnivcnYsV0= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.20.0/go.mod h1:vNUq47TGFioo+ffTSnKNdob241vePmtNZnAODKapKd0= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= go.opentelemetry.io/otel/metric v0.31.0/go.mod h1:ohmwj9KTSIeBnDBm/ZwH2PSZxZzoOaG2xZeekTRzL5A= go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= go.opentelemetry.io/otel/metric v1.20.0/go.mod h1:90DRw3nfK4D7Sm/75yQ00gTJxtkBxX+wu6YaNymbpVM= @@ -2787,10 +2819,10 @@ go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6 go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4= go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= @@ -2809,10 +2841,10 @@ go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= -go.step.sm/crypto v0.66.0 h1:9TW6BEguOtcS9NIjja9bDQ+j8OjhenU/F6lJfHjbXNU= -go.step.sm/crypto v0.66.0/go.mod h1:anqGyvO/Px05D1mznHq4/a9wwP1I1DmMZvk+TWX5Dzo= +go.opentelemetry.io/proto/otlp v1.8.0 h1:fRAZQDcAFHySxpJ1TwlA1cJ4tvcrw7nXl9xWWC8N5CE= +go.opentelemetry.io/proto/otlp v1.8.0/go.mod h1:tIeYOeNBU4cvmPqpaji1P+KbB4Oloai8wN4rWzRrFF0= +go.step.sm/crypto v0.74.0 h1:/APBEv45yYR4qQFg47HA8w1nesIGcxh44pGyQNw6JRA= +go.step.sm/crypto v0.74.0/go.mod h1:UoXqCAJjjRgzPte0Llaqen7O9P7XjPmgjgTHQGkKCDk= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= @@ -3097,8 +3129,8 @@ golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= -golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= +golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -3318,8 +3350,8 @@ golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= -golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -3510,8 +3542,8 @@ google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYl google.golang.org/api v0.164.0/go.mod h1:2OatzO7ZDQsoS7IFf3rvsE17/TldiU3F/zxFHeqUB5o= google.golang.org/api v0.166.0/go.mod h1:4FcBc686KFi7QI/U51/2GKKevfZMpM17sCdibqe/bSA= google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= -google.golang.org/api v0.249.0 h1:0VrsWAKzIZi058aeq+I86uIXbNhm9GxSHpbmZ92a38w= -google.golang.org/api v0.249.0/go.mod h1:dGk9qyI0UYPwO/cjt2q06LG/EhUpwZGdAbYF14wHHrQ= +google.golang.org/api v0.256.0 h1:u6Khm8+F9sxbCTYNoBHg6/Hwv0N/i+V94MvkOSor6oI= +google.golang.org/api v0.256.0/go.mod h1:KIgPhksXADEKJlnEoRa9qAII4rXcy40vfI8HRqcU964= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -3684,8 +3716,8 @@ google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:cc8bqMqt google.golang.org/genproto v0.0.0-20240205150955-31a09d347014/go.mod h1:xEgQu1e4stdSSsxPDK8Azkrk/ECl5HvdPf6nbZrTS5M= google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= -google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= +google.golang.org/genproto v0.0.0-20250922171735-9219d122eba9 h1:LvZVVaPE0JSqL+ZWb6ErZfnEOKIqqFWUJE2D0fObSmc= +google.golang.org/genproto v0.0.0-20250922171735-9219d122eba9/go.mod h1:QFOrLhdAe2PsTp3vQY4quuLKTi9j3XG3r6JPPaw7MSc= google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= @@ -3721,8 +3753,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8/go. google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= -google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090 h1:d8Nakh1G+ur7+P3GcMjpRDEkoLUcLW2iU92XVqR+XMQ= -google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090/go.mod h1:U8EXRNSd8sUYyDfs/It7KVWodQr+Hf9xtxyxWudSwEw= +google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= +google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c= google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405/go.mod h1:GRUCuLdzVqZte8+Dl/D4N25yLzcGqqWaYkeVOwulFqw= @@ -3774,8 +3806,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240823204242-4ba0660f739c/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 h1:/OQuEa4YWtDt7uQWHd3q3sUMb+QOLQUg1xa8CEsRv5w= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101 h1:tRPGkdGHuewF4UisLzzHHr1spKw92qLM98nIzxbC0wY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -3835,8 +3867,8 @@ google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDom google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A= -google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c= +google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= +google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -4031,8 +4063,8 @@ sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/release-utils v0.11.1 h1:hzvXGpHgHJfLOJB6TRuu14bzWc3XEglHmXHJqwClSZE= -sigs.k8s.io/release-utils v0.11.1/go.mod h1:ybR2V/uQAOGxYfzYtBenSYeXWkBGNP2qnEiX77ACtpc= +sigs.k8s.io/release-utils v0.12.2 h1:H06v3FuLElAkf7Ikkd9ll8hnhdtQ+OgktJAni3iIAl8= +sigs.k8s.io/release-utils v0.12.2/go.mod h1:Ab9Lb/FpGUw4lUXj1QYbUcF2TRzll+GS7Md54W1G7sA= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= diff --git a/vendor/cel.dev/expr/BUILD.bazel b/vendor/cel.dev/expr/BUILD.bazel index 37d8adc950..f5bda3bb17 100644 --- a/vendor/cel.dev/expr/BUILD.bazel +++ b/vendor/cel.dev/expr/BUILD.bazel @@ -16,7 +16,6 @@ go_library( importpath = "cel.dev/expr", visibility = ["//visibility:public"], deps = [ - "@org_golang_google_genproto_googleapis_rpc//status:go_default_library", "@org_golang_google_protobuf//reflect/protoreflect", "@org_golang_google_protobuf//runtime/protoimpl", "@org_golang_google_protobuf//types/known/anypb", diff --git a/vendor/cel.dev/expr/MODULE.bazel b/vendor/cel.dev/expr/MODULE.bazel index 85ac9ff617..cb98ed5991 100644 --- a/vendor/cel.dev/expr/MODULE.bazel +++ b/vendor/cel.dev/expr/MODULE.bazel @@ -11,26 +11,9 @@ bazel_dep( version = "0.39.1", repo_name = "bazel_gazelle", ) -bazel_dep( - name = "googleapis", - version = "0.0.0-20241220-5e258e33.bcr.1", - repo_name = "com_google_googleapis", -) -bazel_dep( - name = "googleapis-cc", - version = "1.0.0", -) -bazel_dep( - name = "googleapis-java", - version = "1.0.0", -) -bazel_dep( - name = "googleapis-go", - version = "1.0.0", -) bazel_dep( name = "protobuf", - version = "27.0", + version = "27.1", repo_name = "com_google_protobuf", ) bazel_dep( @@ -63,12 +46,11 @@ python.toolchain( ) go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk") -go_sdk.download(version = "1.22.0") +go_sdk.download(version = "1.23.0") go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps") go_deps.from_file(go_mod = "//:go.mod") use_repo( go_deps, - "org_golang_google_genproto_googleapis_rpc", "org_golang_google_protobuf", ) diff --git a/vendor/cel.dev/expr/checked.pb.go b/vendor/cel.dev/expr/checked.pb.go index bb225c8ab3..b18085e9b6 100644 --- a/vendor/cel.dev/expr/checked.pb.go +++ b/vendor/cel.dev/expr/checked.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.5 +// protoc-gen-go v1.36.10 +// protoc v5.27.1 // source: cel/expr/checked.proto package expr @@ -13,6 +13,7 @@ import ( structpb "google.golang.org/protobuf/types/known/structpb" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -136,24 +137,21 @@ func (Type_WellKnownType) EnumDescriptor() ([]byte, []int) { } type CheckedExpr struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ReferenceMap map[int64]*Reference `protobuf:"bytes,2,rep,name=reference_map,json=referenceMap,proto3" json:"reference_map,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + TypeMap map[int64]*Type `protobuf:"bytes,3,rep,name=type_map,json=typeMap,proto3" json:"type_map,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + SourceInfo *SourceInfo `protobuf:"bytes,5,opt,name=source_info,json=sourceInfo,proto3" json:"source_info,omitempty"` + ExprVersion string `protobuf:"bytes,6,opt,name=expr_version,json=exprVersion,proto3" json:"expr_version,omitempty"` + Expr *Expr `protobuf:"bytes,4,opt,name=expr,proto3" json:"expr,omitempty"` unknownFields protoimpl.UnknownFields - - ReferenceMap map[int64]*Reference `protobuf:"bytes,2,rep,name=reference_map,json=referenceMap,proto3" json:"reference_map,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - TypeMap map[int64]*Type `protobuf:"bytes,3,rep,name=type_map,json=typeMap,proto3" json:"type_map,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - SourceInfo *SourceInfo `protobuf:"bytes,5,opt,name=source_info,json=sourceInfo,proto3" json:"source_info,omitempty"` - ExprVersion string `protobuf:"bytes,6,opt,name=expr_version,json=exprVersion,proto3" json:"expr_version,omitempty"` - Expr *Expr `protobuf:"bytes,4,opt,name=expr,proto3" json:"expr,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CheckedExpr) Reset() { *x = CheckedExpr{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CheckedExpr) String() string { @@ -164,7 +162,7 @@ func (*CheckedExpr) ProtoMessage() {} func (x *CheckedExpr) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -215,11 +213,8 @@ func (x *CheckedExpr) GetExpr() *Expr { } type Type struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to TypeKind: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to TypeKind: // // *Type_Dyn // *Type_Null @@ -234,16 +229,16 @@ type Type struct { // *Type_Type // *Type_Error // *Type_AbstractType_ - TypeKind isType_TypeKind `protobuf_oneof:"type_kind"` + TypeKind isType_TypeKind `protobuf_oneof:"type_kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Type) Reset() { *x = Type{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Type) String() string { @@ -254,7 +249,7 @@ func (*Type) ProtoMessage() {} func (x *Type) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -269,100 +264,126 @@ func (*Type) Descriptor() ([]byte, []int) { return file_cel_expr_checked_proto_rawDescGZIP(), []int{1} } -func (m *Type) GetTypeKind() isType_TypeKind { - if m != nil { - return m.TypeKind +func (x *Type) GetTypeKind() isType_TypeKind { + if x != nil { + return x.TypeKind } return nil } func (x *Type) GetDyn() *emptypb.Empty { - if x, ok := x.GetTypeKind().(*Type_Dyn); ok { - return x.Dyn + if x != nil { + if x, ok := x.TypeKind.(*Type_Dyn); ok { + return x.Dyn + } } return nil } func (x *Type) GetNull() structpb.NullValue { - if x, ok := x.GetTypeKind().(*Type_Null); ok { - return x.Null + if x != nil { + if x, ok := x.TypeKind.(*Type_Null); ok { + return x.Null + } } return structpb.NullValue(0) } func (x *Type) GetPrimitive() Type_PrimitiveType { - if x, ok := x.GetTypeKind().(*Type_Primitive); ok { - return x.Primitive + if x != nil { + if x, ok := x.TypeKind.(*Type_Primitive); ok { + return x.Primitive + } } return Type_PRIMITIVE_TYPE_UNSPECIFIED } func (x *Type) GetWrapper() Type_PrimitiveType { - if x, ok := x.GetTypeKind().(*Type_Wrapper); ok { - return x.Wrapper + if x != nil { + if x, ok := x.TypeKind.(*Type_Wrapper); ok { + return x.Wrapper + } } return Type_PRIMITIVE_TYPE_UNSPECIFIED } func (x *Type) GetWellKnown() Type_WellKnownType { - if x, ok := x.GetTypeKind().(*Type_WellKnown); ok { - return x.WellKnown + if x != nil { + if x, ok := x.TypeKind.(*Type_WellKnown); ok { + return x.WellKnown + } } return Type_WELL_KNOWN_TYPE_UNSPECIFIED } func (x *Type) GetListType() *Type_ListType { - if x, ok := x.GetTypeKind().(*Type_ListType_); ok { - return x.ListType + if x != nil { + if x, ok := x.TypeKind.(*Type_ListType_); ok { + return x.ListType + } } return nil } func (x *Type) GetMapType() *Type_MapType { - if x, ok := x.GetTypeKind().(*Type_MapType_); ok { - return x.MapType + if x != nil { + if x, ok := x.TypeKind.(*Type_MapType_); ok { + return x.MapType + } } return nil } func (x *Type) GetFunction() *Type_FunctionType { - if x, ok := x.GetTypeKind().(*Type_Function); ok { - return x.Function + if x != nil { + if x, ok := x.TypeKind.(*Type_Function); ok { + return x.Function + } } return nil } func (x *Type) GetMessageType() string { - if x, ok := x.GetTypeKind().(*Type_MessageType); ok { - return x.MessageType + if x != nil { + if x, ok := x.TypeKind.(*Type_MessageType); ok { + return x.MessageType + } } return "" } func (x *Type) GetTypeParam() string { - if x, ok := x.GetTypeKind().(*Type_TypeParam); ok { - return x.TypeParam + if x != nil { + if x, ok := x.TypeKind.(*Type_TypeParam); ok { + return x.TypeParam + } } return "" } func (x *Type) GetType() *Type { - if x, ok := x.GetTypeKind().(*Type_Type); ok { - return x.Type + if x != nil { + if x, ok := x.TypeKind.(*Type_Type); ok { + return x.Type + } } return nil } func (x *Type) GetError() *emptypb.Empty { - if x, ok := x.GetTypeKind().(*Type_Error); ok { - return x.Error + if x != nil { + if x, ok := x.TypeKind.(*Type_Error); ok { + return x.Error + } } return nil } func (x *Type) GetAbstractType() *Type_AbstractType { - if x, ok := x.GetTypeKind().(*Type_AbstractType_); ok { - return x.AbstractType + if x != nil { + if x, ok := x.TypeKind.(*Type_AbstractType_); ok { + return x.AbstractType + } } return nil } @@ -450,25 +471,22 @@ func (*Type_Error) isType_TypeKind() {} func (*Type_AbstractType_) isType_TypeKind() {} type Decl struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Types that are assignable to DeclKind: + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Types that are valid to be assigned to DeclKind: // // *Decl_Ident // *Decl_Function - DeclKind isDecl_DeclKind `protobuf_oneof:"decl_kind"` + DeclKind isDecl_DeclKind `protobuf_oneof:"decl_kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Decl) Reset() { *x = Decl{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Decl) String() string { @@ -479,7 +497,7 @@ func (*Decl) ProtoMessage() {} func (x *Decl) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -501,23 +519,27 @@ func (x *Decl) GetName() string { return "" } -func (m *Decl) GetDeclKind() isDecl_DeclKind { - if m != nil { - return m.DeclKind +func (x *Decl) GetDeclKind() isDecl_DeclKind { + if x != nil { + return x.DeclKind } return nil } func (x *Decl) GetIdent() *Decl_IdentDecl { - if x, ok := x.GetDeclKind().(*Decl_Ident); ok { - return x.Ident + if x != nil { + if x, ok := x.DeclKind.(*Decl_Ident); ok { + return x.Ident + } } return nil } func (x *Decl) GetFunction() *Decl_FunctionDecl { - if x, ok := x.GetDeclKind().(*Decl_Function); ok { - return x.Function + if x != nil { + if x, ok := x.DeclKind.(*Decl_Function); ok { + return x.Function + } } return nil } @@ -539,22 +561,19 @@ func (*Decl_Ident) isDecl_DeclKind() {} func (*Decl_Function) isDecl_DeclKind() {} type Reference struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + OverloadId []string `protobuf:"bytes,3,rep,name=overload_id,json=overloadId,proto3" json:"overload_id,omitempty"` + Value *Constant `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - OverloadId []string `protobuf:"bytes,3,rep,name=overload_id,json=overloadId,proto3" json:"overload_id,omitempty"` - Value *Constant `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Reference) Reset() { *x = Reference{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Reference) String() string { @@ -565,7 +584,7 @@ func (*Reference) ProtoMessage() {} func (x *Reference) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -602,20 +621,17 @@ func (x *Reference) GetValue() *Constant { } type Type_ListType struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ElemType *Type `protobuf:"bytes,1,opt,name=elem_type,json=elemType,proto3" json:"elem_type,omitempty"` unknownFields protoimpl.UnknownFields - - ElemType *Type `protobuf:"bytes,1,opt,name=elem_type,json=elemType,proto3" json:"elem_type,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Type_ListType) Reset() { *x = Type_ListType{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Type_ListType) String() string { @@ -626,7 +642,7 @@ func (*Type_ListType) ProtoMessage() {} func (x *Type_ListType) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -649,21 +665,18 @@ func (x *Type_ListType) GetElemType() *Type { } type Type_MapType struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + KeyType *Type `protobuf:"bytes,1,opt,name=key_type,json=keyType,proto3" json:"key_type,omitempty"` + ValueType *Type `protobuf:"bytes,2,opt,name=value_type,json=valueType,proto3" json:"value_type,omitempty"` unknownFields protoimpl.UnknownFields - - KeyType *Type `protobuf:"bytes,1,opt,name=key_type,json=keyType,proto3" json:"key_type,omitempty"` - ValueType *Type `protobuf:"bytes,2,opt,name=value_type,json=valueType,proto3" json:"value_type,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Type_MapType) Reset() { *x = Type_MapType{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Type_MapType) String() string { @@ -674,7 +687,7 @@ func (*Type_MapType) ProtoMessage() {} func (x *Type_MapType) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -704,21 +717,18 @@ func (x *Type_MapType) GetValueType() *Type { } type Type_FunctionType struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ResultType *Type `protobuf:"bytes,1,opt,name=result_type,json=resultType,proto3" json:"result_type,omitempty"` + ArgTypes []*Type `protobuf:"bytes,2,rep,name=arg_types,json=argTypes,proto3" json:"arg_types,omitempty"` unknownFields protoimpl.UnknownFields - - ResultType *Type `protobuf:"bytes,1,opt,name=result_type,json=resultType,proto3" json:"result_type,omitempty"` - ArgTypes []*Type `protobuf:"bytes,2,rep,name=arg_types,json=argTypes,proto3" json:"arg_types,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Type_FunctionType) Reset() { *x = Type_FunctionType{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Type_FunctionType) String() string { @@ -729,7 +739,7 @@ func (*Type_FunctionType) ProtoMessage() {} func (x *Type_FunctionType) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -759,21 +769,18 @@ func (x *Type_FunctionType) GetArgTypes() []*Type { } type Type_AbstractType struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - ParameterTypes []*Type `protobuf:"bytes,2,rep,name=parameter_types,json=parameterTypes,proto3" json:"parameter_types,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + ParameterTypes []*Type `protobuf:"bytes,2,rep,name=parameter_types,json=parameterTypes,proto3" json:"parameter_types,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Type_AbstractType) Reset() { *x = Type_AbstractType{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Type_AbstractType) String() string { @@ -784,7 +791,7 @@ func (*Type_AbstractType) ProtoMessage() {} func (x *Type_AbstractType) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -814,22 +821,19 @@ func (x *Type_AbstractType) GetParameterTypes() []*Type { } type Decl_IdentDecl struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Type *Type `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Value *Constant `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + Doc string `protobuf:"bytes,3,opt,name=doc,proto3" json:"doc,omitempty"` unknownFields protoimpl.UnknownFields - - Type *Type `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - Value *Constant `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` - Doc string `protobuf:"bytes,3,opt,name=doc,proto3" json:"doc,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Decl_IdentDecl) Reset() { *x = Decl_IdentDecl{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Decl_IdentDecl) String() string { @@ -840,7 +844,7 @@ func (*Decl_IdentDecl) ProtoMessage() {} func (x *Decl_IdentDecl) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -877,20 +881,18 @@ func (x *Decl_IdentDecl) GetDoc() string { } type Decl_FunctionDecl struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Overloads []*Decl_FunctionDecl_Overload `protobuf:"bytes,1,rep,name=overloads,proto3" json:"overloads,omitempty"` + Doc string `protobuf:"bytes,2,opt,name=doc,proto3" json:"doc,omitempty"` unknownFields protoimpl.UnknownFields - - Overloads []*Decl_FunctionDecl_Overload `protobuf:"bytes,1,rep,name=overloads,proto3" json:"overloads,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Decl_FunctionDecl) Reset() { *x = Decl_FunctionDecl{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Decl_FunctionDecl) String() string { @@ -901,7 +903,7 @@ func (*Decl_FunctionDecl) ProtoMessage() {} func (x *Decl_FunctionDecl) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -923,26 +925,30 @@ func (x *Decl_FunctionDecl) GetOverloads() []*Decl_FunctionDecl_Overload { return nil } -type Decl_FunctionDecl_Overload struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields +func (x *Decl_FunctionDecl) GetDoc() string { + if x != nil { + return x.Doc + } + return "" +} - OverloadId string `protobuf:"bytes,1,opt,name=overload_id,json=overloadId,proto3" json:"overload_id,omitempty"` - Params []*Type `protobuf:"bytes,2,rep,name=params,proto3" json:"params,omitempty"` - TypeParams []string `protobuf:"bytes,3,rep,name=type_params,json=typeParams,proto3" json:"type_params,omitempty"` - ResultType *Type `protobuf:"bytes,4,opt,name=result_type,json=resultType,proto3" json:"result_type,omitempty"` - IsInstanceFunction bool `protobuf:"varint,5,opt,name=is_instance_function,json=isInstanceFunction,proto3" json:"is_instance_function,omitempty"` - Doc string `protobuf:"bytes,6,opt,name=doc,proto3" json:"doc,omitempty"` +type Decl_FunctionDecl_Overload struct { + state protoimpl.MessageState `protogen:"open.v1"` + OverloadId string `protobuf:"bytes,1,opt,name=overload_id,json=overloadId,proto3" json:"overload_id,omitempty"` + Params []*Type `protobuf:"bytes,2,rep,name=params,proto3" json:"params,omitempty"` + TypeParams []string `protobuf:"bytes,3,rep,name=type_params,json=typeParams,proto3" json:"type_params,omitempty"` + ResultType *Type `protobuf:"bytes,4,opt,name=result_type,json=resultType,proto3" json:"result_type,omitempty"` + IsInstanceFunction bool `protobuf:"varint,5,opt,name=is_instance_function,json=isInstanceFunction,proto3" json:"is_instance_function,omitempty"` + Doc string `protobuf:"bytes,6,opt,name=doc,proto3" json:"doc,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Decl_FunctionDecl_Overload) Reset() { *x = Decl_FunctionDecl_Overload{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_checked_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_checked_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Decl_FunctionDecl_Overload) String() string { @@ -953,7 +959,7 @@ func (*Decl_FunctionDecl_Overload) ProtoMessage() {} func (x *Decl_FunctionDecl_Overload) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_checked_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1012,185 +1018,113 @@ func (x *Decl_FunctionDecl_Overload) GetDoc() string { var File_cel_expr_checked_proto protoreflect.FileDescriptor -var file_cel_expr_checked_proto_rawDesc = []byte{ - 0x0a, 0x16, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, - 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, - 0x70, 0x72, 0x1a, 0x15, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x73, 0x79, 0x6e, - 0x74, 0x61, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xba, 0x03, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, - 0x45, 0x78, 0x70, 0x72, 0x12, 0x4c, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x45, 0x78, - 0x70, 0x72, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x4d, - 0x61, 0x70, 0x12, 0x3d, 0x0a, 0x08, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, - 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x74, 0x79, 0x70, 0x65, 0x4d, 0x61, - 0x70, 0x12, 0x35, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, 0x70, 0x72, - 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x65, 0x78, 0x70, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x04, 0x65, - 0x78, 0x70, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x1a, - 0x54, 0x0a, 0x11, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x4d, 0x61, 0x70, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, - 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4a, 0x0a, 0x0c, 0x54, 0x79, 0x70, 0x65, 0x4d, 0x61, 0x70, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0xe6, 0x09, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x03, 0x64, 0x79, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, - 0x00, 0x52, 0x03, 0x64, 0x79, 0x6e, 0x12, 0x30, 0x0a, 0x04, 0x6e, 0x75, 0x6c, 0x6c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x48, 0x00, 0x52, 0x04, 0x6e, 0x75, 0x6c, 0x6c, 0x12, 0x3c, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6d, - 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x50, 0x72, 0x69, 0x6d, - 0x69, 0x74, 0x69, 0x76, 0x65, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x09, 0x70, 0x72, 0x69, - 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, - 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, - 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x07, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x12, 0x3d, 0x0a, 0x0a, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x54, 0x79, 0x70, 0x65, 0x2e, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x54, 0x79, - 0x70, 0x65, 0x48, 0x00, 0x52, 0x09, 0x77, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x12, - 0x36, 0x0a, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, - 0x70, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x08, 0x6c, - 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x61, 0x70, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, - 0x65, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x39, 0x0a, 0x08, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, - 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x46, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x08, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, - 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0a, - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, - 0x48, 0x00, 0x52, 0x09, 0x74, 0x79, 0x70, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x24, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x12, 0x42, 0x0a, 0x0d, 0x61, 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x41, 0x62, 0x73, 0x74, 0x72, - 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x62, 0x73, 0x74, 0x72, - 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x37, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x09, 0x65, 0x6c, 0x65, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, - 0x1a, 0x63, 0x0a, 0x07, 0x4d, 0x61, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x08, 0x6b, - 0x65, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x6b, - 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2d, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x6c, 0x0a, 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x61, 0x72, 0x67, 0x54, 0x79, - 0x70, 0x65, 0x73, 0x1a, 0x5b, 0x0a, 0x0c, 0x41, 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x0e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x73, - 0x22, 0x73, 0x0a, 0x0d, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x50, 0x52, 0x49, 0x4d, 0x49, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x49, - 0x4e, 0x54, 0x36, 0x34, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34, - 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x0a, - 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x05, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x59, - 0x54, 0x45, 0x53, 0x10, 0x06, 0x22, 0x56, 0x0a, 0x0d, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, - 0x77, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x1b, 0x57, 0x45, 0x4c, 0x4c, 0x5f, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x01, - 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x10, 0x02, 0x12, - 0x0c, 0x0a, 0x08, 0x44, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x42, 0x0b, 0x0a, - 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0xc2, 0x04, 0x0a, 0x04, 0x44, - 0x65, 0x63, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x2e, 0x44, 0x65, 0x63, 0x6c, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x63, 0x6c, - 0x48, 0x00, 0x52, 0x05, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x08, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x44, 0x65, 0x63, 0x6c, 0x2e, 0x46, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x63, 0x6c, 0x48, 0x00, 0x52, 0x08, 0x66, 0x75, 0x6e, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x6b, 0x0a, 0x09, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x63, - 0x6c, 0x12, 0x22, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x10, 0x0a, 0x03, 0x64, 0x6f, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x6f, - 0x63, 0x1a, 0xbe, 0x02, 0x0a, 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, - 0x63, 0x6c, 0x12, 0x42, 0x0a, 0x09, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, - 0x2e, 0x44, 0x65, 0x63, 0x6c, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, - 0x63, 0x6c, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x09, 0x6f, 0x76, 0x65, - 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x1a, 0xe9, 0x01, 0x0a, 0x08, 0x4f, 0x76, 0x65, 0x72, 0x6c, - 0x6f, 0x61, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, - 0x61, 0x64, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1f, 0x0a, 0x0b, - 0x74, 0x79, 0x70, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2f, 0x0a, - 0x0b, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x30, - 0x0a, 0x14, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x66, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x73, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x10, 0x0a, 0x03, 0x64, 0x6f, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, - 0x6f, 0x63, 0x42, 0x0b, 0x0a, 0x09, 0x64, 0x65, 0x63, 0x6c, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x22, - 0x6a, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x49, - 0x64, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2c, 0x0a, 0x0c, 0x64, - 0x65, 0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x09, 0x44, 0x65, 0x63, - 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64, 0x65, - 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} +const file_cel_expr_checked_proto_rawDesc = "" + + "\n" + + "\x16cel/expr/checked.proto\x12\bcel.expr\x1a\x15cel/expr/syntax.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\"\xba\x03\n" + + "\vCheckedExpr\x12L\n" + + "\rreference_map\x18\x02 \x03(\v2'.cel.expr.CheckedExpr.ReferenceMapEntryR\freferenceMap\x12=\n" + + "\btype_map\x18\x03 \x03(\v2\".cel.expr.CheckedExpr.TypeMapEntryR\atypeMap\x125\n" + + "\vsource_info\x18\x05 \x01(\v2\x14.cel.expr.SourceInfoR\n" + + "sourceInfo\x12!\n" + + "\fexpr_version\x18\x06 \x01(\tR\vexprVersion\x12\"\n" + + "\x04expr\x18\x04 \x01(\v2\x0e.cel.expr.ExprR\x04expr\x1aT\n" + + "\x11ReferenceMapEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\x03R\x03key\x12)\n" + + "\x05value\x18\x02 \x01(\v2\x13.cel.expr.ReferenceR\x05value:\x028\x01\x1aJ\n" + + "\fTypeMapEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\x03R\x03key\x12$\n" + + "\x05value\x18\x02 \x01(\v2\x0e.cel.expr.TypeR\x05value:\x028\x01\"\xe6\t\n" + + "\x04Type\x12*\n" + + "\x03dyn\x18\x01 \x01(\v2\x16.google.protobuf.EmptyH\x00R\x03dyn\x120\n" + + "\x04null\x18\x02 \x01(\x0e2\x1a.google.protobuf.NullValueH\x00R\x04null\x12<\n" + + "\tprimitive\x18\x03 \x01(\x0e2\x1c.cel.expr.Type.PrimitiveTypeH\x00R\tprimitive\x128\n" + + "\awrapper\x18\x04 \x01(\x0e2\x1c.cel.expr.Type.PrimitiveTypeH\x00R\awrapper\x12=\n" + + "\n" + + "well_known\x18\x05 \x01(\x0e2\x1c.cel.expr.Type.WellKnownTypeH\x00R\twellKnown\x126\n" + + "\tlist_type\x18\x06 \x01(\v2\x17.cel.expr.Type.ListTypeH\x00R\blistType\x123\n" + + "\bmap_type\x18\a \x01(\v2\x16.cel.expr.Type.MapTypeH\x00R\amapType\x129\n" + + "\bfunction\x18\b \x01(\v2\x1b.cel.expr.Type.FunctionTypeH\x00R\bfunction\x12#\n" + + "\fmessage_type\x18\t \x01(\tH\x00R\vmessageType\x12\x1f\n" + + "\n" + + "type_param\x18\n" + + " \x01(\tH\x00R\ttypeParam\x12$\n" + + "\x04type\x18\v \x01(\v2\x0e.cel.expr.TypeH\x00R\x04type\x12.\n" + + "\x05error\x18\f \x01(\v2\x16.google.protobuf.EmptyH\x00R\x05error\x12B\n" + + "\rabstract_type\x18\x0e \x01(\v2\x1b.cel.expr.Type.AbstractTypeH\x00R\fabstractType\x1a7\n" + + "\bListType\x12+\n" + + "\telem_type\x18\x01 \x01(\v2\x0e.cel.expr.TypeR\belemType\x1ac\n" + + "\aMapType\x12)\n" + + "\bkey_type\x18\x01 \x01(\v2\x0e.cel.expr.TypeR\akeyType\x12-\n" + + "\n" + + "value_type\x18\x02 \x01(\v2\x0e.cel.expr.TypeR\tvalueType\x1al\n" + + "\fFunctionType\x12/\n" + + "\vresult_type\x18\x01 \x01(\v2\x0e.cel.expr.TypeR\n" + + "resultType\x12+\n" + + "\targ_types\x18\x02 \x03(\v2\x0e.cel.expr.TypeR\bargTypes\x1a[\n" + + "\fAbstractType\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x127\n" + + "\x0fparameter_types\x18\x02 \x03(\v2\x0e.cel.expr.TypeR\x0eparameterTypes\"s\n" + + "\rPrimitiveType\x12\x1e\n" + + "\x1aPRIMITIVE_TYPE_UNSPECIFIED\x10\x00\x12\b\n" + + "\x04BOOL\x10\x01\x12\t\n" + + "\x05INT64\x10\x02\x12\n" + + "\n" + + "\x06UINT64\x10\x03\x12\n" + + "\n" + + "\x06DOUBLE\x10\x04\x12\n" + + "\n" + + "\x06STRING\x10\x05\x12\t\n" + + "\x05BYTES\x10\x06\"V\n" + + "\rWellKnownType\x12\x1f\n" + + "\x1bWELL_KNOWN_TYPE_UNSPECIFIED\x10\x00\x12\a\n" + + "\x03ANY\x10\x01\x12\r\n" + + "\tTIMESTAMP\x10\x02\x12\f\n" + + "\bDURATION\x10\x03B\v\n" + + "\ttype_kind\"\xd4\x04\n" + + "\x04Decl\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x120\n" + + "\x05ident\x18\x02 \x01(\v2\x18.cel.expr.Decl.IdentDeclH\x00R\x05ident\x129\n" + + "\bfunction\x18\x03 \x01(\v2\x1b.cel.expr.Decl.FunctionDeclH\x00R\bfunction\x1ak\n" + + "\tIdentDecl\x12\"\n" + + "\x04type\x18\x01 \x01(\v2\x0e.cel.expr.TypeR\x04type\x12(\n" + + "\x05value\x18\x02 \x01(\v2\x12.cel.expr.ConstantR\x05value\x12\x10\n" + + "\x03doc\x18\x03 \x01(\tR\x03doc\x1a\xd0\x02\n" + + "\fFunctionDecl\x12B\n" + + "\toverloads\x18\x01 \x03(\v2$.cel.expr.Decl.FunctionDecl.OverloadR\toverloads\x12\x10\n" + + "\x03doc\x18\x02 \x01(\tR\x03doc\x1a\xe9\x01\n" + + "\bOverload\x12\x1f\n" + + "\voverload_id\x18\x01 \x01(\tR\n" + + "overloadId\x12&\n" + + "\x06params\x18\x02 \x03(\v2\x0e.cel.expr.TypeR\x06params\x12\x1f\n" + + "\vtype_params\x18\x03 \x03(\tR\n" + + "typeParams\x12/\n" + + "\vresult_type\x18\x04 \x01(\v2\x0e.cel.expr.TypeR\n" + + "resultType\x120\n" + + "\x14is_instance_function\x18\x05 \x01(\bR\x12isInstanceFunction\x12\x10\n" + + "\x03doc\x18\x06 \x01(\tR\x03docB\v\n" + + "\tdecl_kind\"j\n" + + "\tReference\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x1f\n" + + "\voverload_id\x18\x03 \x03(\tR\n" + + "overloadId\x12(\n" + + "\x05value\x18\x04 \x01(\v2\x12.cel.expr.ConstantR\x05valueB,\n" + + "\fdev.cel.exprB\tDeclProtoP\x01Z\fcel.dev/expr\xf8\x01\x01b\x06proto3" var ( file_cel_expr_checked_proto_rawDescOnce sync.Once - file_cel_expr_checked_proto_rawDescData = file_cel_expr_checked_proto_rawDesc + file_cel_expr_checked_proto_rawDescData []byte ) func file_cel_expr_checked_proto_rawDescGZIP() []byte { file_cel_expr_checked_proto_rawDescOnce.Do(func() { - file_cel_expr_checked_proto_rawDescData = protoimpl.X.CompressGZIP(file_cel_expr_checked_proto_rawDescData) + file_cel_expr_checked_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cel_expr_checked_proto_rawDesc), len(file_cel_expr_checked_proto_rawDesc))) }) return file_cel_expr_checked_proto_rawDescData } var file_cel_expr_checked_proto_enumTypes = make([]protoimpl.EnumInfo, 2) var file_cel_expr_checked_proto_msgTypes = make([]protoimpl.MessageInfo, 13) -var file_cel_expr_checked_proto_goTypes = []interface{}{ +var file_cel_expr_checked_proto_goTypes = []any{ (Type_PrimitiveType)(0), // 0: cel.expr.Type.PrimitiveType (Type_WellKnownType)(0), // 1: cel.expr.Type.WellKnownType (*CheckedExpr)(nil), // 2: cel.expr.CheckedExpr @@ -1257,141 +1191,7 @@ func file_cel_expr_checked_proto_init() { return } file_cel_expr_syntax_proto_init() - if !protoimpl.UnsafeEnabled { - file_cel_expr_checked_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckedExpr); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Type); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Decl); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Reference); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Type_ListType); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Type_MapType); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Type_FunctionType); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Type_AbstractType); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Decl_IdentDecl); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Decl_FunctionDecl); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_checked_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Decl_FunctionDecl_Overload); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_cel_expr_checked_proto_msgTypes[1].OneofWrappers = []interface{}{ + file_cel_expr_checked_proto_msgTypes[1].OneofWrappers = []any{ (*Type_Dyn)(nil), (*Type_Null)(nil), (*Type_Primitive)(nil), @@ -1406,7 +1206,7 @@ func file_cel_expr_checked_proto_init() { (*Type_Error)(nil), (*Type_AbstractType_)(nil), } - file_cel_expr_checked_proto_msgTypes[2].OneofWrappers = []interface{}{ + file_cel_expr_checked_proto_msgTypes[2].OneofWrappers = []any{ (*Decl_Ident)(nil), (*Decl_Function)(nil), } @@ -1414,7 +1214,7 @@ func file_cel_expr_checked_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cel_expr_checked_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_cel_expr_checked_proto_rawDesc), len(file_cel_expr_checked_proto_rawDesc)), NumEnums: 2, NumMessages: 13, NumExtensions: 0, @@ -1426,7 +1226,6 @@ func file_cel_expr_checked_proto_init() { MessageInfos: file_cel_expr_checked_proto_msgTypes, }.Build() File_cel_expr_checked_proto = out.File - file_cel_expr_checked_proto_rawDesc = nil file_cel_expr_checked_proto_goTypes = nil file_cel_expr_checked_proto_depIdxs = nil } diff --git a/vendor/cel.dev/expr/eval.pb.go b/vendor/cel.dev/expr/eval.pb.go index a7aae0900c..83acb8935b 100644 --- a/vendor/cel.dev/expr/eval.pb.go +++ b/vendor/cel.dev/expr/eval.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.3 +// protoc-gen-go v1.36.10 // protoc v5.27.1 // source: cel/expr/eval.proto @@ -12,6 +12,7 @@ import ( anypb "google.golang.org/protobuf/types/known/anypb" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -373,58 +374,39 @@ func (x *EvalState_Result) GetValue() int64 { var File_cel_expr_eval_proto protoreflect.FileDescriptor -var file_cel_expr_eval_proto_rawDesc = []byte{ - 0x0a, 0x13, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x65, 0x76, 0x61, 0x6c, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x1a, - 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x63, 0x65, 0x6c, 0x2f, - 0x65, 0x78, 0x70, 0x72, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0xa2, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2b, - 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x72, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, - 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x1a, 0x32, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x65, - 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x48, - 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x30, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, - 0x6f, 0x77, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x48, - 0x00, 0x52, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, - 0x6e, 0x64, 0x22, 0x34, 0x0a, 0x08, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x12, 0x28, - 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x66, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x2e, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x22, 0x22, 0x0a, 0x0a, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x65, 0x78, 0x70, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x05, 0x65, - 0x78, 0x70, 0x72, 0x73, 0x42, 0x2c, 0x0a, 0x0c, 0x64, 0x65, 0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x42, 0x09, 0x45, 0x76, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, - 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} +const file_cel_expr_eval_proto_rawDesc = "" + + "\n" + + "\x13cel/expr/eval.proto\x12\bcel.expr\x1a\x19google/protobuf/any.proto\x1a\x14cel/expr/value.proto\"\xa2\x01\n" + + "\tEvalState\x12+\n" + + "\x06values\x18\x01 \x03(\v2\x13.cel.expr.ExprValueR\x06values\x124\n" + + "\aresults\x18\x03 \x03(\v2\x1a.cel.expr.EvalState.ResultR\aresults\x1a2\n" + + "\x06Result\x12\x12\n" + + "\x04expr\x18\x01 \x01(\x03R\x04expr\x12\x14\n" + + "\x05value\x18\x02 \x01(\x03R\x05value\"\x9a\x01\n" + + "\tExprValue\x12'\n" + + "\x05value\x18\x01 \x01(\v2\x0f.cel.expr.ValueH\x00R\x05value\x12*\n" + + "\x05error\x18\x02 \x01(\v2\x12.cel.expr.ErrorSetH\x00R\x05error\x120\n" + + "\aunknown\x18\x03 \x01(\v2\x14.cel.expr.UnknownSetH\x00R\aunknownB\x06\n" + + "\x04kind\"4\n" + + "\bErrorSet\x12(\n" + + "\x06errors\x18\x01 \x03(\v2\x10.cel.expr.StatusR\x06errors\"f\n" + + "\x06Status\x12\x12\n" + + "\x04code\x18\x01 \x01(\x05R\x04code\x12\x18\n" + + "\amessage\x18\x02 \x01(\tR\amessage\x12.\n" + + "\adetails\x18\x03 \x03(\v2\x14.google.protobuf.AnyR\adetails\"\"\n" + + "\n" + + "UnknownSet\x12\x14\n" + + "\x05exprs\x18\x01 \x03(\x03R\x05exprsB,\n" + + "\fdev.cel.exprB\tEvalProtoP\x01Z\fcel.dev/expr\xf8\x01\x01b\x06proto3" var ( file_cel_expr_eval_proto_rawDescOnce sync.Once - file_cel_expr_eval_proto_rawDescData = file_cel_expr_eval_proto_rawDesc + file_cel_expr_eval_proto_rawDescData []byte ) func file_cel_expr_eval_proto_rawDescGZIP() []byte { file_cel_expr_eval_proto_rawDescOnce.Do(func() { - file_cel_expr_eval_proto_rawDescData = protoimpl.X.CompressGZIP(file_cel_expr_eval_proto_rawDescData) + file_cel_expr_eval_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cel_expr_eval_proto_rawDesc), len(file_cel_expr_eval_proto_rawDesc))) }) return file_cel_expr_eval_proto_rawDescData } @@ -470,7 +452,7 @@ func file_cel_expr_eval_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cel_expr_eval_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_cel_expr_eval_proto_rawDesc), len(file_cel_expr_eval_proto_rawDesc)), NumEnums: 0, NumMessages: 6, NumExtensions: 0, @@ -481,7 +463,6 @@ func file_cel_expr_eval_proto_init() { MessageInfos: file_cel_expr_eval_proto_msgTypes, }.Build() File_cel_expr_eval_proto = out.File - file_cel_expr_eval_proto_rawDesc = nil file_cel_expr_eval_proto_goTypes = nil file_cel_expr_eval_proto_depIdxs = nil } diff --git a/vendor/cel.dev/expr/explain.pb.go b/vendor/cel.dev/expr/explain.pb.go index 79fd5443b9..4239933978 100644 --- a/vendor/cel.dev/expr/explain.pb.go +++ b/vendor/cel.dev/expr/explain.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.5 +// protoc-gen-go v1.36.10 +// protoc v5.27.1 // source: cel/expr/explain.proto package expr @@ -11,6 +11,7 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -20,23 +21,20 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in cel/expr/explain.proto. type Explain struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` + ExprSteps []*Explain_ExprStep `protobuf:"bytes,2,rep,name=expr_steps,json=exprSteps,proto3" json:"expr_steps,omitempty"` unknownFields protoimpl.UnknownFields - - Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` - ExprSteps []*Explain_ExprStep `protobuf:"bytes,2,rep,name=expr_steps,json=exprSteps,proto3" json:"expr_steps,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Explain) Reset() { *x = Explain{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_explain_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_explain_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Explain) String() string { @@ -47,7 +45,7 @@ func (*Explain) ProtoMessage() {} func (x *Explain) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_explain_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -77,21 +75,18 @@ func (x *Explain) GetExprSteps() []*Explain_ExprStep { } type Explain_ExprStep struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + ValueIndex int32 `protobuf:"varint,2,opt,name=value_index,json=valueIndex,proto3" json:"value_index,omitempty"` unknownFields protoimpl.UnknownFields - - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - ValueIndex int32 `protobuf:"varint,2,opt,name=value_index,json=valueIndex,proto3" json:"value_index,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Explain_ExprStep) Reset() { *x = Explain_ExprStep{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_explain_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_explain_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Explain_ExprStep) String() string { @@ -102,7 +97,7 @@ func (*Explain_ExprStep) ProtoMessage() {} func (x *Explain_ExprStep) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_explain_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -133,42 +128,33 @@ func (x *Explain_ExprStep) GetValueIndex() int32 { var File_cel_expr_explain_proto protoreflect.FileDescriptor -var file_cel_expr_explain_proto_rawDesc = []byte{ - 0x0a, 0x16, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x65, 0x78, 0x70, 0x6c, 0x61, - 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, - 0x70, 0x72, 0x1a, 0x14, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xae, 0x01, 0x0a, 0x07, 0x45, 0x78, 0x70, - 0x6c, 0x61, 0x69, 0x6e, 0x12, 0x27, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x39, 0x0a, - 0x0a, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, - 0x6c, 0x61, 0x69, 0x6e, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x53, 0x74, 0x65, 0x70, 0x52, 0x09, 0x65, - 0x78, 0x70, 0x72, 0x53, 0x74, 0x65, 0x70, 0x73, 0x1a, 0x3b, 0x0a, 0x08, 0x45, 0x78, 0x70, 0x72, - 0x53, 0x74, 0x65, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x69, 0x6e, - 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x02, 0x18, 0x01, 0x42, 0x2f, 0x0a, 0x0c, 0x64, 0x65, 0x76, - 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x0c, 0x45, 0x78, 0x70, 0x6c, 0x61, - 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64, - 0x65, 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} +const file_cel_expr_explain_proto_rawDesc = "" + + "\n" + + "\x16cel/expr/explain.proto\x12\bcel.expr\x1a\x14cel/expr/value.proto\"\xae\x01\n" + + "\aExplain\x12'\n" + + "\x06values\x18\x01 \x03(\v2\x0f.cel.expr.ValueR\x06values\x129\n" + + "\n" + + "expr_steps\x18\x02 \x03(\v2\x1a.cel.expr.Explain.ExprStepR\texprSteps\x1a;\n" + + "\bExprStep\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x1f\n" + + "\vvalue_index\x18\x02 \x01(\x05R\n" + + "valueIndex:\x02\x18\x01B/\n" + + "\fdev.cel.exprB\fExplainProtoP\x01Z\fcel.dev/expr\xf8\x01\x01b\x06proto3" var ( file_cel_expr_explain_proto_rawDescOnce sync.Once - file_cel_expr_explain_proto_rawDescData = file_cel_expr_explain_proto_rawDesc + file_cel_expr_explain_proto_rawDescData []byte ) func file_cel_expr_explain_proto_rawDescGZIP() []byte { file_cel_expr_explain_proto_rawDescOnce.Do(func() { - file_cel_expr_explain_proto_rawDescData = protoimpl.X.CompressGZIP(file_cel_expr_explain_proto_rawDescData) + file_cel_expr_explain_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cel_expr_explain_proto_rawDesc), len(file_cel_expr_explain_proto_rawDesc))) }) return file_cel_expr_explain_proto_rawDescData } var file_cel_expr_explain_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_cel_expr_explain_proto_goTypes = []interface{}{ +var file_cel_expr_explain_proto_goTypes = []any{ (*Explain)(nil), // 0: cel.expr.Explain (*Explain_ExprStep)(nil), // 1: cel.expr.Explain.ExprStep (*Value)(nil), // 2: cel.expr.Value @@ -189,37 +175,11 @@ func file_cel_expr_explain_proto_init() { return } file_cel_expr_value_proto_init() - if !protoimpl.UnsafeEnabled { - file_cel_expr_explain_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Explain); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_explain_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Explain_ExprStep); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cel_expr_explain_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_cel_expr_explain_proto_rawDesc), len(file_cel_expr_explain_proto_rawDesc)), NumEnums: 0, NumMessages: 2, NumExtensions: 0, @@ -230,7 +190,6 @@ func file_cel_expr_explain_proto_init() { MessageInfos: file_cel_expr_explain_proto_msgTypes, }.Build() File_cel_expr_explain_proto = out.File - file_cel_expr_explain_proto_rawDesc = nil file_cel_expr_explain_proto_goTypes = nil file_cel_expr_explain_proto_depIdxs = nil } diff --git a/vendor/cel.dev/expr/syntax.pb.go b/vendor/cel.dev/expr/syntax.pb.go index 48a952872e..72d19b20d4 100644 --- a/vendor/cel.dev/expr/syntax.pb.go +++ b/vendor/cel.dev/expr/syntax.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.5 +// protoc-gen-go v1.36.10 +// protoc v5.27.1 // source: cel/expr/syntax.proto package expr @@ -14,6 +14,7 @@ import ( timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -76,21 +77,18 @@ func (SourceInfo_Extension_Component) EnumDescriptor() ([]byte, []int) { } type ParsedExpr struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Expr *Expr `protobuf:"bytes,2,opt,name=expr,proto3" json:"expr,omitempty"` + SourceInfo *SourceInfo `protobuf:"bytes,3,opt,name=source_info,json=sourceInfo,proto3" json:"source_info,omitempty"` unknownFields protoimpl.UnknownFields - - Expr *Expr `protobuf:"bytes,2,opt,name=expr,proto3" json:"expr,omitempty"` - SourceInfo *SourceInfo `protobuf:"bytes,3,opt,name=source_info,json=sourceInfo,proto3" json:"source_info,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ParsedExpr) Reset() { *x = ParsedExpr{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ParsedExpr) String() string { @@ -101,7 +99,7 @@ func (*ParsedExpr) ProtoMessage() {} func (x *ParsedExpr) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -131,12 +129,9 @@ func (x *ParsedExpr) GetSourceInfo() *SourceInfo { } type Expr struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id int64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` - // Types that are assignable to ExprKind: + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` + // Types that are valid to be assigned to ExprKind: // // *Expr_ConstExpr // *Expr_IdentExpr @@ -145,16 +140,16 @@ type Expr struct { // *Expr_ListExpr // *Expr_StructExpr // *Expr_ComprehensionExpr - ExprKind isExpr_ExprKind `protobuf_oneof:"expr_kind"` + ExprKind isExpr_ExprKind `protobuf_oneof:"expr_kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Expr) Reset() { *x = Expr{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr) String() string { @@ -165,7 +160,7 @@ func (*Expr) ProtoMessage() {} func (x *Expr) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -187,58 +182,72 @@ func (x *Expr) GetId() int64 { return 0 } -func (m *Expr) GetExprKind() isExpr_ExprKind { - if m != nil { - return m.ExprKind +func (x *Expr) GetExprKind() isExpr_ExprKind { + if x != nil { + return x.ExprKind } return nil } func (x *Expr) GetConstExpr() *Constant { - if x, ok := x.GetExprKind().(*Expr_ConstExpr); ok { - return x.ConstExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_ConstExpr); ok { + return x.ConstExpr + } } return nil } func (x *Expr) GetIdentExpr() *Expr_Ident { - if x, ok := x.GetExprKind().(*Expr_IdentExpr); ok { - return x.IdentExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_IdentExpr); ok { + return x.IdentExpr + } } return nil } func (x *Expr) GetSelectExpr() *Expr_Select { - if x, ok := x.GetExprKind().(*Expr_SelectExpr); ok { - return x.SelectExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_SelectExpr); ok { + return x.SelectExpr + } } return nil } func (x *Expr) GetCallExpr() *Expr_Call { - if x, ok := x.GetExprKind().(*Expr_CallExpr); ok { - return x.CallExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_CallExpr); ok { + return x.CallExpr + } } return nil } func (x *Expr) GetListExpr() *Expr_CreateList { - if x, ok := x.GetExprKind().(*Expr_ListExpr); ok { - return x.ListExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_ListExpr); ok { + return x.ListExpr + } } return nil } func (x *Expr) GetStructExpr() *Expr_CreateStruct { - if x, ok := x.GetExprKind().(*Expr_StructExpr); ok { - return x.StructExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_StructExpr); ok { + return x.StructExpr + } } return nil } func (x *Expr) GetComprehensionExpr() *Expr_Comprehension { - if x, ok := x.GetExprKind().(*Expr_ComprehensionExpr); ok { - return x.ComprehensionExpr + if x != nil { + if x, ok := x.ExprKind.(*Expr_ComprehensionExpr); ok { + return x.ComprehensionExpr + } } return nil } @@ -290,11 +299,8 @@ func (*Expr_StructExpr) isExpr_ExprKind() {} func (*Expr_ComprehensionExpr) isExpr_ExprKind() {} type Constant struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to ConstantKind: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to ConstantKind: // // *Constant_NullValue // *Constant_BoolValue @@ -305,16 +311,16 @@ type Constant struct { // *Constant_BytesValue // *Constant_DurationValue // *Constant_TimestampValue - ConstantKind isConstant_ConstantKind `protobuf_oneof:"constant_kind"` + ConstantKind isConstant_ConstantKind `protobuf_oneof:"constant_kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Constant) Reset() { *x = Constant{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Constant) String() string { @@ -325,7 +331,7 @@ func (*Constant) ProtoMessage() {} func (x *Constant) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -340,74 +346,92 @@ func (*Constant) Descriptor() ([]byte, []int) { return file_cel_expr_syntax_proto_rawDescGZIP(), []int{2} } -func (m *Constant) GetConstantKind() isConstant_ConstantKind { - if m != nil { - return m.ConstantKind +func (x *Constant) GetConstantKind() isConstant_ConstantKind { + if x != nil { + return x.ConstantKind } return nil } func (x *Constant) GetNullValue() structpb.NullValue { - if x, ok := x.GetConstantKind().(*Constant_NullValue); ok { - return x.NullValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_NullValue); ok { + return x.NullValue + } } return structpb.NullValue(0) } func (x *Constant) GetBoolValue() bool { - if x, ok := x.GetConstantKind().(*Constant_BoolValue); ok { - return x.BoolValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_BoolValue); ok { + return x.BoolValue + } } return false } func (x *Constant) GetInt64Value() int64 { - if x, ok := x.GetConstantKind().(*Constant_Int64Value); ok { - return x.Int64Value + if x != nil { + if x, ok := x.ConstantKind.(*Constant_Int64Value); ok { + return x.Int64Value + } } return 0 } func (x *Constant) GetUint64Value() uint64 { - if x, ok := x.GetConstantKind().(*Constant_Uint64Value); ok { - return x.Uint64Value + if x != nil { + if x, ok := x.ConstantKind.(*Constant_Uint64Value); ok { + return x.Uint64Value + } } return 0 } func (x *Constant) GetDoubleValue() float64 { - if x, ok := x.GetConstantKind().(*Constant_DoubleValue); ok { - return x.DoubleValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_DoubleValue); ok { + return x.DoubleValue + } } return 0 } func (x *Constant) GetStringValue() string { - if x, ok := x.GetConstantKind().(*Constant_StringValue); ok { - return x.StringValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_StringValue); ok { + return x.StringValue + } } return "" } func (x *Constant) GetBytesValue() []byte { - if x, ok := x.GetConstantKind().(*Constant_BytesValue); ok { - return x.BytesValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_BytesValue); ok { + return x.BytesValue + } } return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in cel/expr/syntax.proto. func (x *Constant) GetDurationValue() *durationpb.Duration { - if x, ok := x.GetConstantKind().(*Constant_DurationValue); ok { - return x.DurationValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_DurationValue); ok { + return x.DurationValue + } } return nil } -// Deprecated: Do not use. +// Deprecated: Marked as deprecated in cel/expr/syntax.proto. func (x *Constant) GetTimestampValue() *timestamppb.Timestamp { - if x, ok := x.GetConstantKind().(*Constant_TimestampValue); ok { - return x.TimestampValue + if x != nil { + if x, ok := x.ConstantKind.(*Constant_TimestampValue); ok { + return x.TimestampValue + } } return nil } @@ -445,12 +469,12 @@ type Constant_BytesValue struct { } type Constant_DurationValue struct { - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in cel/expr/syntax.proto. DurationValue *durationpb.Duration `protobuf:"bytes,8,opt,name=duration_value,json=durationValue,proto3,oneof"` } type Constant_TimestampValue struct { - // Deprecated: Do not use. + // Deprecated: Marked as deprecated in cel/expr/syntax.proto. TimestampValue *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=timestamp_value,json=timestampValue,proto3,oneof"` } @@ -473,25 +497,22 @@ func (*Constant_DurationValue) isConstant_ConstantKind() {} func (*Constant_TimestampValue) isConstant_ConstantKind() {} type SourceInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` SyntaxVersion string `protobuf:"bytes,1,opt,name=syntax_version,json=syntaxVersion,proto3" json:"syntax_version,omitempty"` Location string `protobuf:"bytes,2,opt,name=location,proto3" json:"location,omitempty"` LineOffsets []int32 `protobuf:"varint,3,rep,packed,name=line_offsets,json=lineOffsets,proto3" json:"line_offsets,omitempty"` - Positions map[int64]int32 `protobuf:"bytes,4,rep,name=positions,proto3" json:"positions,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` - MacroCalls map[int64]*Expr `protobuf:"bytes,5,rep,name=macro_calls,json=macroCalls,proto3" json:"macro_calls,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Positions map[int64]int32 `protobuf:"bytes,4,rep,name=positions,proto3" json:"positions,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + MacroCalls map[int64]*Expr `protobuf:"bytes,5,rep,name=macro_calls,json=macroCalls,proto3" json:"macro_calls,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` Extensions []*SourceInfo_Extension `protobuf:"bytes,6,rep,name=extensions,proto3" json:"extensions,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SourceInfo) Reset() { *x = SourceInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SourceInfo) String() string { @@ -502,7 +523,7 @@ func (*SourceInfo) ProtoMessage() {} func (x *SourceInfo) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -560,20 +581,17 @@ func (x *SourceInfo) GetExtensions() []*SourceInfo_Extension { } type Expr_Ident struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Expr_Ident) Reset() { *x = Expr_Ident{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_Ident) String() string { @@ -584,7 +602,7 @@ func (*Expr_Ident) ProtoMessage() {} func (x *Expr_Ident) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -607,22 +625,19 @@ func (x *Expr_Ident) GetName() string { } type Expr_Select struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Operand *Expr `protobuf:"bytes,1,opt,name=operand,proto3" json:"operand,omitempty"` + Field string `protobuf:"bytes,2,opt,name=field,proto3" json:"field,omitempty"` + TestOnly bool `protobuf:"varint,3,opt,name=test_only,json=testOnly,proto3" json:"test_only,omitempty"` unknownFields protoimpl.UnknownFields - - Operand *Expr `protobuf:"bytes,1,opt,name=operand,proto3" json:"operand,omitempty"` - Field string `protobuf:"bytes,2,opt,name=field,proto3" json:"field,omitempty"` - TestOnly bool `protobuf:"varint,3,opt,name=test_only,json=testOnly,proto3" json:"test_only,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Expr_Select) Reset() { *x = Expr_Select{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_Select) String() string { @@ -633,7 +648,7 @@ func (*Expr_Select) ProtoMessage() {} func (x *Expr_Select) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -670,22 +685,19 @@ func (x *Expr_Select) GetTestOnly() bool { } type Expr_Call struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Target *Expr `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` + Function string `protobuf:"bytes,2,opt,name=function,proto3" json:"function,omitempty"` + Args []*Expr `protobuf:"bytes,3,rep,name=args,proto3" json:"args,omitempty"` unknownFields protoimpl.UnknownFields - - Target *Expr `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` - Function string `protobuf:"bytes,2,opt,name=function,proto3" json:"function,omitempty"` - Args []*Expr `protobuf:"bytes,3,rep,name=args,proto3" json:"args,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Expr_Call) Reset() { *x = Expr_Call{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_Call) String() string { @@ -696,7 +708,7 @@ func (*Expr_Call) ProtoMessage() {} func (x *Expr_Call) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -733,21 +745,18 @@ func (x *Expr_Call) GetArgs() []*Expr { } type Expr_CreateList struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Elements []*Expr `protobuf:"bytes,1,rep,name=elements,proto3" json:"elements,omitempty"` - OptionalIndices []int32 `protobuf:"varint,2,rep,packed,name=optional_indices,json=optionalIndices,proto3" json:"optional_indices,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Elements []*Expr `protobuf:"bytes,1,rep,name=elements,proto3" json:"elements,omitempty"` + OptionalIndices []int32 `protobuf:"varint,2,rep,packed,name=optional_indices,json=optionalIndices,proto3" json:"optional_indices,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Expr_CreateList) Reset() { *x = Expr_CreateList{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_CreateList) String() string { @@ -758,7 +767,7 @@ func (*Expr_CreateList) ProtoMessage() {} func (x *Expr_CreateList) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -788,21 +797,18 @@ func (x *Expr_CreateList) GetOptionalIndices() []int32 { } type Expr_CreateStruct struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + MessageName string `protobuf:"bytes,1,opt,name=message_name,json=messageName,proto3" json:"message_name,omitempty"` + Entries []*Expr_CreateStruct_Entry `protobuf:"bytes,2,rep,name=entries,proto3" json:"entries,omitempty"` unknownFields protoimpl.UnknownFields - - MessageName string `protobuf:"bytes,1,opt,name=message_name,json=messageName,proto3" json:"message_name,omitempty"` - Entries []*Expr_CreateStruct_Entry `protobuf:"bytes,2,rep,name=entries,proto3" json:"entries,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Expr_CreateStruct) Reset() { *x = Expr_CreateStruct{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_CreateStruct) String() string { @@ -813,7 +819,7 @@ func (*Expr_CreateStruct) ProtoMessage() {} func (x *Expr_CreateStruct) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -843,26 +849,24 @@ func (x *Expr_CreateStruct) GetEntries() []*Expr_CreateStruct_Entry { } type Expr_Comprehension struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + IterVar string `protobuf:"bytes,1,opt,name=iter_var,json=iterVar,proto3" json:"iter_var,omitempty"` + IterVar2 string `protobuf:"bytes,8,opt,name=iter_var2,json=iterVar2,proto3" json:"iter_var2,omitempty"` + IterRange *Expr `protobuf:"bytes,2,opt,name=iter_range,json=iterRange,proto3" json:"iter_range,omitempty"` + AccuVar string `protobuf:"bytes,3,opt,name=accu_var,json=accuVar,proto3" json:"accu_var,omitempty"` + AccuInit *Expr `protobuf:"bytes,4,opt,name=accu_init,json=accuInit,proto3" json:"accu_init,omitempty"` + LoopCondition *Expr `protobuf:"bytes,5,opt,name=loop_condition,json=loopCondition,proto3" json:"loop_condition,omitempty"` + LoopStep *Expr `protobuf:"bytes,6,opt,name=loop_step,json=loopStep,proto3" json:"loop_step,omitempty"` + Result *Expr `protobuf:"bytes,7,opt,name=result,proto3" json:"result,omitempty"` unknownFields protoimpl.UnknownFields - - IterVar string `protobuf:"bytes,1,opt,name=iter_var,json=iterVar,proto3" json:"iter_var,omitempty"` - IterRange *Expr `protobuf:"bytes,2,opt,name=iter_range,json=iterRange,proto3" json:"iter_range,omitempty"` - AccuVar string `protobuf:"bytes,3,opt,name=accu_var,json=accuVar,proto3" json:"accu_var,omitempty"` - AccuInit *Expr `protobuf:"bytes,4,opt,name=accu_init,json=accuInit,proto3" json:"accu_init,omitempty"` - LoopCondition *Expr `protobuf:"bytes,5,opt,name=loop_condition,json=loopCondition,proto3" json:"loop_condition,omitempty"` - LoopStep *Expr `protobuf:"bytes,6,opt,name=loop_step,json=loopStep,proto3" json:"loop_step,omitempty"` - Result *Expr `protobuf:"bytes,7,opt,name=result,proto3" json:"result,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Expr_Comprehension) Reset() { *x = Expr_Comprehension{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_Comprehension) String() string { @@ -873,7 +877,7 @@ func (*Expr_Comprehension) ProtoMessage() {} func (x *Expr_Comprehension) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -895,6 +899,13 @@ func (x *Expr_Comprehension) GetIterVar() string { return "" } +func (x *Expr_Comprehension) GetIterVar2() string { + if x != nil { + return x.IterVar2 + } + return "" +} + func (x *Expr_Comprehension) GetIterRange() *Expr { if x != nil { return x.IterRange @@ -938,27 +949,24 @@ func (x *Expr_Comprehension) GetResult() *Expr { } type Expr_CreateStruct_Entry struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - // Types that are assignable to KeyKind: + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are valid to be assigned to KeyKind: // // *Expr_CreateStruct_Entry_FieldKey // *Expr_CreateStruct_Entry_MapKey KeyKind isExpr_CreateStruct_Entry_KeyKind `protobuf_oneof:"key_kind"` Value *Expr `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` OptionalEntry bool `protobuf:"varint,5,opt,name=optional_entry,json=optionalEntry,proto3" json:"optional_entry,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Expr_CreateStruct_Entry) Reset() { *x = Expr_CreateStruct_Entry{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Expr_CreateStruct_Entry) String() string { @@ -969,7 +977,7 @@ func (*Expr_CreateStruct_Entry) ProtoMessage() {} func (x *Expr_CreateStruct_Entry) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -991,23 +999,27 @@ func (x *Expr_CreateStruct_Entry) GetId() int64 { return 0 } -func (m *Expr_CreateStruct_Entry) GetKeyKind() isExpr_CreateStruct_Entry_KeyKind { - if m != nil { - return m.KeyKind +func (x *Expr_CreateStruct_Entry) GetKeyKind() isExpr_CreateStruct_Entry_KeyKind { + if x != nil { + return x.KeyKind } return nil } func (x *Expr_CreateStruct_Entry) GetFieldKey() string { - if x, ok := x.GetKeyKind().(*Expr_CreateStruct_Entry_FieldKey); ok { - return x.FieldKey + if x != nil { + if x, ok := x.KeyKind.(*Expr_CreateStruct_Entry_FieldKey); ok { + return x.FieldKey + } } return "" } func (x *Expr_CreateStruct_Entry) GetMapKey() *Expr { - if x, ok := x.GetKeyKind().(*Expr_CreateStruct_Entry_MapKey); ok { - return x.MapKey + if x != nil { + if x, ok := x.KeyKind.(*Expr_CreateStruct_Entry_MapKey); ok { + return x.MapKey + } } return nil } @@ -1043,22 +1055,19 @@ func (*Expr_CreateStruct_Entry_FieldKey) isExpr_CreateStruct_Entry_KeyKind() {} func (*Expr_CreateStruct_Entry_MapKey) isExpr_CreateStruct_Entry_KeyKind() {} type SourceInfo_Extension struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` AffectedComponents []SourceInfo_Extension_Component `protobuf:"varint,2,rep,packed,name=affected_components,json=affectedComponents,proto3,enum=cel.expr.SourceInfo_Extension_Component" json:"affected_components,omitempty"` Version *SourceInfo_Extension_Version `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SourceInfo_Extension) Reset() { *x = SourceInfo_Extension{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SourceInfo_Extension) String() string { @@ -1069,7 +1078,7 @@ func (*SourceInfo_Extension) ProtoMessage() {} func (x *SourceInfo_Extension) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1106,21 +1115,18 @@ func (x *SourceInfo_Extension) GetVersion() *SourceInfo_Extension_Version { } type SourceInfo_Extension_Version struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Major int64 `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"` + Minor int64 `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"` unknownFields protoimpl.UnknownFields - - Major int64 `protobuf:"varint,1,opt,name=major,proto3" json:"major,omitempty"` - Minor int64 `protobuf:"varint,2,opt,name=minor,proto3" json:"minor,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SourceInfo_Extension_Version) Reset() { *x = SourceInfo_Extension_Version{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_syntax_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_syntax_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SourceInfo_Extension_Version) String() string { @@ -1131,7 +1137,7 @@ func (*SourceInfo_Extension_Version) ProtoMessage() {} func (x *SourceInfo_Extension_Version) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_syntax_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1162,210 +1168,124 @@ func (x *SourceInfo_Extension_Version) GetMinor() int64 { var File_cel_expr_syntax_proto protoreflect.FileDescriptor -var file_cel_expr_syntax_proto_rawDesc = []byte{ - 0x0a, 0x15, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x73, 0x79, 0x6e, 0x74, 0x61, - 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0x67, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x73, 0x65, 0x64, 0x45, 0x78, 0x70, 0x72, 0x12, 0x22, - 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, - 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x04, 0x65, 0x78, - 0x70, 0x72, 0x12, 0x35, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, - 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, - 0x70, 0x72, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xfd, 0x0a, 0x0a, 0x04, 0x45, 0x78, - 0x70, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x33, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x72, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x09, 0x63, 0x6f, - 0x6e, 0x73, 0x74, 0x45, 0x78, 0x70, 0x72, 0x12, 0x35, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x49, 0x64, 0x65, 0x6e, - 0x74, 0x48, 0x00, 0x52, 0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x45, 0x78, 0x70, 0x72, 0x12, 0x38, - 0x0a, 0x0b, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, - 0x78, 0x70, 0x72, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x73, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x45, 0x78, 0x70, 0x72, 0x12, 0x32, 0x0a, 0x09, 0x63, 0x61, 0x6c, 0x6c, - 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x43, 0x61, 0x6c, 0x6c, - 0x48, 0x00, 0x52, 0x08, 0x63, 0x61, 0x6c, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x12, 0x38, 0x0a, 0x09, - 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x08, 0x6c, 0x69, - 0x73, 0x74, 0x45, 0x78, 0x70, 0x72, 0x12, 0x3e, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, - 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x65, - 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x73, 0x74, 0x72, 0x75, - 0x63, 0x74, 0x45, 0x78, 0x70, 0x72, 0x12, 0x4d, 0x0a, 0x12, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, - 0x68, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, - 0x70, 0x72, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, - 0x48, 0x00, 0x52, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x45, 0x78, 0x70, 0x72, 0x1a, 0x1b, 0x0a, 0x05, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x1a, 0x65, 0x0a, 0x06, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x28, 0x0a, 0x07, - 0x6f, 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x07, 0x6f, - 0x70, 0x65, 0x72, 0x61, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x1b, 0x0a, 0x09, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x74, 0x65, 0x73, 0x74, 0x4f, 0x6e, 0x6c, 0x79, 0x1a, 0x6e, 0x0a, 0x04, 0x43, 0x61, 0x6c, - 0x6c, 0x12, 0x26, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, - 0x72, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x75, 0x6e, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, - 0x78, 0x70, 0x72, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x1a, 0x63, 0x0a, 0x0a, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, - 0x69, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0f, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x1a, 0xab, - 0x02, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, - 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, - 0x78, 0x70, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, - 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x1a, - 0xba, 0x01, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x09, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x07, 0x6d, 0x61, 0x70, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x61, 0x70, - 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, - 0x70, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0d, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x42, 0x0a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x1a, 0xad, 0x02, 0x0a, - 0x0d, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, - 0x0a, 0x08, 0x69, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x69, 0x74, 0x65, 0x72, 0x56, 0x61, 0x72, 0x12, 0x2d, 0x0a, 0x0a, 0x69, 0x74, 0x65, - 0x72, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x09, 0x69, - 0x74, 0x65, 0x72, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x75, - 0x5f, 0x76, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x63, 0x63, 0x75, - 0x56, 0x61, 0x72, 0x12, 0x2b, 0x0a, 0x09, 0x61, 0x63, 0x63, 0x75, 0x5f, 0x69, 0x6e, 0x69, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, - 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x08, 0x61, 0x63, 0x63, 0x75, 0x49, 0x6e, 0x69, 0x74, - 0x12, 0x35, 0x0a, 0x0e, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, - 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x0d, 0x6c, 0x6f, 0x6f, 0x70, 0x43, 0x6f, - 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x09, 0x6c, 0x6f, 0x6f, 0x70, 0x5f, - 0x73, 0x74, 0x65, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x08, 0x6c, 0x6f, 0x6f, 0x70, - 0x53, 0x74, 0x65, 0x70, 0x12, 0x26, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x45, 0x78, 0x70, 0x72, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x0b, 0x0a, 0x09, - 0x65, 0x78, 0x70, 0x72, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0xc1, 0x03, 0x0a, 0x08, 0x43, 0x6f, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x12, 0x3b, 0x0a, 0x0a, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4e, 0x75, 0x6c, - 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6e, 0x75, 0x6c, 0x6c, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x74, - 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x75, 0x69, 0x6e, 0x74, 0x36, - 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, - 0x0b, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, - 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0a, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x46, 0x0a, 0x0e, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x02, 0x18, 0x01, - 0x48, 0x00, 0x52, 0x0d, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x49, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0f, 0x0a, 0x0d, - 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0xac, 0x06, - 0x0a, 0x0a, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x25, 0x0a, 0x0e, - 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x21, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x73, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0b, 0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, - 0x74, 0x73, 0x12, 0x41, 0x0a, 0x09, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, - 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x6f, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x45, 0x0a, 0x0b, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x5f, 0x63, - 0x61, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, - 0x2e, 0x4d, 0x61, 0x63, 0x72, 0x6f, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x0a, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x12, 0x3e, 0x0a, 0x0a, - 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1e, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x53, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3c, 0x0a, 0x0e, - 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4d, 0x0a, 0x0f, 0x4d, 0x61, - 0x63, 0x72, 0x6f, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x24, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, - 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0xe0, 0x02, 0x0a, 0x09, 0x45, 0x78, - 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x59, 0x0a, 0x13, 0x61, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x12, - 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, - 0x74, 0x73, 0x12, 0x40, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x35, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, - 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x22, 0x6f, 0x0a, 0x09, 0x43, - 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4d, 0x50, - 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, - 0x5f, 0x50, 0x41, 0x52, 0x53, 0x45, 0x52, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4d, - 0x50, 0x4f, 0x4e, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x48, 0x45, 0x43, - 0x4b, 0x45, 0x52, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4d, 0x50, 0x4f, 0x4e, 0x45, - 0x4e, 0x54, 0x5f, 0x52, 0x55, 0x4e, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x03, 0x42, 0x2e, 0x0a, 0x0c, - 0x64, 0x65, 0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x0b, 0x53, 0x79, - 0x6e, 0x74, 0x61, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, - 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} +const file_cel_expr_syntax_proto_rawDesc = "" + + "\n" + + "\x15cel/expr/syntax.proto\x12\bcel.expr\x1a\x1egoogle/protobuf/duration.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"g\n" + + "\n" + + "ParsedExpr\x12\"\n" + + "\x04expr\x18\x02 \x01(\v2\x0e.cel.expr.ExprR\x04expr\x125\n" + + "\vsource_info\x18\x03 \x01(\v2\x14.cel.expr.SourceInfoR\n" + + "sourceInfo\"\x9a\v\n" + + "\x04Expr\x12\x0e\n" + + "\x02id\x18\x02 \x01(\x03R\x02id\x123\n" + + "\n" + + "const_expr\x18\x03 \x01(\v2\x12.cel.expr.ConstantH\x00R\tconstExpr\x125\n" + + "\n" + + "ident_expr\x18\x04 \x01(\v2\x14.cel.expr.Expr.IdentH\x00R\tidentExpr\x128\n" + + "\vselect_expr\x18\x05 \x01(\v2\x15.cel.expr.Expr.SelectH\x00R\n" + + "selectExpr\x122\n" + + "\tcall_expr\x18\x06 \x01(\v2\x13.cel.expr.Expr.CallH\x00R\bcallExpr\x128\n" + + "\tlist_expr\x18\a \x01(\v2\x19.cel.expr.Expr.CreateListH\x00R\blistExpr\x12>\n" + + "\vstruct_expr\x18\b \x01(\v2\x1b.cel.expr.Expr.CreateStructH\x00R\n" + + "structExpr\x12M\n" + + "\x12comprehension_expr\x18\t \x01(\v2\x1c.cel.expr.Expr.ComprehensionH\x00R\x11comprehensionExpr\x1a\x1b\n" + + "\x05Ident\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x1ae\n" + + "\x06Select\x12(\n" + + "\aoperand\x18\x01 \x01(\v2\x0e.cel.expr.ExprR\aoperand\x12\x14\n" + + "\x05field\x18\x02 \x01(\tR\x05field\x12\x1b\n" + + "\ttest_only\x18\x03 \x01(\bR\btestOnly\x1an\n" + + "\x04Call\x12&\n" + + "\x06target\x18\x01 \x01(\v2\x0e.cel.expr.ExprR\x06target\x12\x1a\n" + + "\bfunction\x18\x02 \x01(\tR\bfunction\x12\"\n" + + "\x04args\x18\x03 \x03(\v2\x0e.cel.expr.ExprR\x04args\x1ac\n" + + "\n" + + "CreateList\x12*\n" + + "\belements\x18\x01 \x03(\v2\x0e.cel.expr.ExprR\belements\x12)\n" + + "\x10optional_indices\x18\x02 \x03(\x05R\x0foptionalIndices\x1a\xab\x02\n" + + "\fCreateStruct\x12!\n" + + "\fmessage_name\x18\x01 \x01(\tR\vmessageName\x12;\n" + + "\aentries\x18\x02 \x03(\v2!.cel.expr.Expr.CreateStruct.EntryR\aentries\x1a\xba\x01\n" + + "\x05Entry\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x1d\n" + + "\tfield_key\x18\x02 \x01(\tH\x00R\bfieldKey\x12)\n" + + "\amap_key\x18\x03 \x01(\v2\x0e.cel.expr.ExprH\x00R\x06mapKey\x12$\n" + + "\x05value\x18\x04 \x01(\v2\x0e.cel.expr.ExprR\x05value\x12%\n" + + "\x0eoptional_entry\x18\x05 \x01(\bR\roptionalEntryB\n" + + "\n" + + "\bkey_kind\x1a\xca\x02\n" + + "\rComprehension\x12\x19\n" + + "\biter_var\x18\x01 \x01(\tR\aiterVar\x12\x1b\n" + + "\titer_var2\x18\b \x01(\tR\biterVar2\x12-\n" + + "\n" + + "iter_range\x18\x02 \x01(\v2\x0e.cel.expr.ExprR\titerRange\x12\x19\n" + + "\baccu_var\x18\x03 \x01(\tR\aaccuVar\x12+\n" + + "\taccu_init\x18\x04 \x01(\v2\x0e.cel.expr.ExprR\baccuInit\x125\n" + + "\x0eloop_condition\x18\x05 \x01(\v2\x0e.cel.expr.ExprR\rloopCondition\x12+\n" + + "\tloop_step\x18\x06 \x01(\v2\x0e.cel.expr.ExprR\bloopStep\x12&\n" + + "\x06result\x18\a \x01(\v2\x0e.cel.expr.ExprR\x06resultB\v\n" + + "\texpr_kind\"\xc1\x03\n" + + "\bConstant\x12;\n" + + "\n" + + "null_value\x18\x01 \x01(\x0e2\x1a.google.protobuf.NullValueH\x00R\tnullValue\x12\x1f\n" + + "\n" + + "bool_value\x18\x02 \x01(\bH\x00R\tboolValue\x12!\n" + + "\vint64_value\x18\x03 \x01(\x03H\x00R\n" + + "int64Value\x12#\n" + + "\fuint64_value\x18\x04 \x01(\x04H\x00R\vuint64Value\x12#\n" + + "\fdouble_value\x18\x05 \x01(\x01H\x00R\vdoubleValue\x12#\n" + + "\fstring_value\x18\x06 \x01(\tH\x00R\vstringValue\x12!\n" + + "\vbytes_value\x18\a \x01(\fH\x00R\n" + + "bytesValue\x12F\n" + + "\x0eduration_value\x18\b \x01(\v2\x19.google.protobuf.DurationB\x02\x18\x01H\x00R\rdurationValue\x12I\n" + + "\x0ftimestamp_value\x18\t \x01(\v2\x1a.google.protobuf.TimestampB\x02\x18\x01H\x00R\x0etimestampValueB\x0f\n" + + "\rconstant_kind\"\xac\x06\n" + + "\n" + + "SourceInfo\x12%\n" + + "\x0esyntax_version\x18\x01 \x01(\tR\rsyntaxVersion\x12\x1a\n" + + "\blocation\x18\x02 \x01(\tR\blocation\x12!\n" + + "\fline_offsets\x18\x03 \x03(\x05R\vlineOffsets\x12A\n" + + "\tpositions\x18\x04 \x03(\v2#.cel.expr.SourceInfo.PositionsEntryR\tpositions\x12E\n" + + "\vmacro_calls\x18\x05 \x03(\v2$.cel.expr.SourceInfo.MacroCallsEntryR\n" + + "macroCalls\x12>\n" + + "\n" + + "extensions\x18\x06 \x03(\v2\x1e.cel.expr.SourceInfo.ExtensionR\n" + + "extensions\x1a<\n" + + "\x0ePositionsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\x03R\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\x05R\x05value:\x028\x01\x1aM\n" + + "\x0fMacroCallsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\x03R\x03key\x12$\n" + + "\x05value\x18\x02 \x01(\v2\x0e.cel.expr.ExprR\x05value:\x028\x01\x1a\xe0\x02\n" + + "\tExtension\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12Y\n" + + "\x13affected_components\x18\x02 \x03(\x0e2(.cel.expr.SourceInfo.Extension.ComponentR\x12affectedComponents\x12@\n" + + "\aversion\x18\x03 \x01(\v2&.cel.expr.SourceInfo.Extension.VersionR\aversion\x1a5\n" + + "\aVersion\x12\x14\n" + + "\x05major\x18\x01 \x01(\x03R\x05major\x12\x14\n" + + "\x05minor\x18\x02 \x01(\x03R\x05minor\"o\n" + + "\tComponent\x12\x19\n" + + "\x15COMPONENT_UNSPECIFIED\x10\x00\x12\x14\n" + + "\x10COMPONENT_PARSER\x10\x01\x12\x1a\n" + + "\x16COMPONENT_TYPE_CHECKER\x10\x02\x12\x15\n" + + "\x11COMPONENT_RUNTIME\x10\x03B.\n" + + "\fdev.cel.exprB\vSyntaxProtoP\x01Z\fcel.dev/expr\xf8\x01\x01b\x06proto3" var ( file_cel_expr_syntax_proto_rawDescOnce sync.Once - file_cel_expr_syntax_proto_rawDescData = file_cel_expr_syntax_proto_rawDesc + file_cel_expr_syntax_proto_rawDescData []byte ) func file_cel_expr_syntax_proto_rawDescGZIP() []byte { file_cel_expr_syntax_proto_rawDescOnce.Do(func() { - file_cel_expr_syntax_proto_rawDescData = protoimpl.X.CompressGZIP(file_cel_expr_syntax_proto_rawDescData) + file_cel_expr_syntax_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cel_expr_syntax_proto_rawDesc), len(file_cel_expr_syntax_proto_rawDesc))) }) return file_cel_expr_syntax_proto_rawDescData } var file_cel_expr_syntax_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_cel_expr_syntax_proto_msgTypes = make([]protoimpl.MessageInfo, 15) -var file_cel_expr_syntax_proto_goTypes = []interface{}{ +var file_cel_expr_syntax_proto_goTypes = []any{ (SourceInfo_Extension_Component)(0), // 0: cel.expr.SourceInfo.Extension.Component (*ParsedExpr)(nil), // 1: cel.expr.ParsedExpr (*Expr)(nil), // 2: cel.expr.Expr @@ -1429,165 +1349,7 @@ func file_cel_expr_syntax_proto_init() { if File_cel_expr_syntax_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_cel_expr_syntax_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ParsedExpr); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Constant); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SourceInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_Ident); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_Select); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_Call); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_CreateList); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_CreateStruct); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_Comprehension); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Expr_CreateStruct_Entry); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SourceInfo_Extension); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_syntax_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SourceInfo_Extension_Version); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_cel_expr_syntax_proto_msgTypes[1].OneofWrappers = []interface{}{ + file_cel_expr_syntax_proto_msgTypes[1].OneofWrappers = []any{ (*Expr_ConstExpr)(nil), (*Expr_IdentExpr)(nil), (*Expr_SelectExpr)(nil), @@ -1596,7 +1358,7 @@ func file_cel_expr_syntax_proto_init() { (*Expr_StructExpr)(nil), (*Expr_ComprehensionExpr)(nil), } - file_cel_expr_syntax_proto_msgTypes[2].OneofWrappers = []interface{}{ + file_cel_expr_syntax_proto_msgTypes[2].OneofWrappers = []any{ (*Constant_NullValue)(nil), (*Constant_BoolValue)(nil), (*Constant_Int64Value)(nil), @@ -1607,7 +1369,7 @@ func file_cel_expr_syntax_proto_init() { (*Constant_DurationValue)(nil), (*Constant_TimestampValue)(nil), } - file_cel_expr_syntax_proto_msgTypes[10].OneofWrappers = []interface{}{ + file_cel_expr_syntax_proto_msgTypes[10].OneofWrappers = []any{ (*Expr_CreateStruct_Entry_FieldKey)(nil), (*Expr_CreateStruct_Entry_MapKey)(nil), } @@ -1615,7 +1377,7 @@ func file_cel_expr_syntax_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cel_expr_syntax_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_cel_expr_syntax_proto_rawDesc), len(file_cel_expr_syntax_proto_rawDesc)), NumEnums: 1, NumMessages: 15, NumExtensions: 0, @@ -1627,7 +1389,6 @@ func file_cel_expr_syntax_proto_init() { MessageInfos: file_cel_expr_syntax_proto_msgTypes, }.Build() File_cel_expr_syntax_proto = out.File - file_cel_expr_syntax_proto_rawDesc = nil file_cel_expr_syntax_proto_goTypes = nil file_cel_expr_syntax_proto_depIdxs = nil } diff --git a/vendor/cel.dev/expr/value.pb.go b/vendor/cel.dev/expr/value.pb.go index e5e29228c2..1f53a6a296 100644 --- a/vendor/cel.dev/expr/value.pb.go +++ b/vendor/cel.dev/expr/value.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.5 +// protoc-gen-go v1.36.10 +// protoc v5.27.1 // source: cel/expr/value.proto package expr @@ -13,6 +13,7 @@ import ( structpb "google.golang.org/protobuf/types/known/structpb" reflect "reflect" sync "sync" + unsafe "unsafe" ) const ( @@ -23,11 +24,8 @@ const ( ) type Value struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Kind: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Kind: // // *Value_NullValue // *Value_BoolValue @@ -41,16 +39,16 @@ type Value struct { // *Value_MapValue // *Value_ListValue // *Value_TypeValue - Kind isValue_Kind `protobuf_oneof:"kind"` + Kind isValue_Kind `protobuf_oneof:"kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Value) Reset() { *x = Value{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_value_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_value_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Value) String() string { @@ -61,7 +59,7 @@ func (*Value) ProtoMessage() {} func (x *Value) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_value_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -76,93 +74,117 @@ func (*Value) Descriptor() ([]byte, []int) { return file_cel_expr_value_proto_rawDescGZIP(), []int{0} } -func (m *Value) GetKind() isValue_Kind { - if m != nil { - return m.Kind +func (x *Value) GetKind() isValue_Kind { + if x != nil { + return x.Kind } return nil } func (x *Value) GetNullValue() structpb.NullValue { - if x, ok := x.GetKind().(*Value_NullValue); ok { - return x.NullValue + if x != nil { + if x, ok := x.Kind.(*Value_NullValue); ok { + return x.NullValue + } } return structpb.NullValue(0) } func (x *Value) GetBoolValue() bool { - if x, ok := x.GetKind().(*Value_BoolValue); ok { - return x.BoolValue + if x != nil { + if x, ok := x.Kind.(*Value_BoolValue); ok { + return x.BoolValue + } } return false } func (x *Value) GetInt64Value() int64 { - if x, ok := x.GetKind().(*Value_Int64Value); ok { - return x.Int64Value + if x != nil { + if x, ok := x.Kind.(*Value_Int64Value); ok { + return x.Int64Value + } } return 0 } func (x *Value) GetUint64Value() uint64 { - if x, ok := x.GetKind().(*Value_Uint64Value); ok { - return x.Uint64Value + if x != nil { + if x, ok := x.Kind.(*Value_Uint64Value); ok { + return x.Uint64Value + } } return 0 } func (x *Value) GetDoubleValue() float64 { - if x, ok := x.GetKind().(*Value_DoubleValue); ok { - return x.DoubleValue + if x != nil { + if x, ok := x.Kind.(*Value_DoubleValue); ok { + return x.DoubleValue + } } return 0 } func (x *Value) GetStringValue() string { - if x, ok := x.GetKind().(*Value_StringValue); ok { - return x.StringValue + if x != nil { + if x, ok := x.Kind.(*Value_StringValue); ok { + return x.StringValue + } } return "" } func (x *Value) GetBytesValue() []byte { - if x, ok := x.GetKind().(*Value_BytesValue); ok { - return x.BytesValue + if x != nil { + if x, ok := x.Kind.(*Value_BytesValue); ok { + return x.BytesValue + } } return nil } func (x *Value) GetEnumValue() *EnumValue { - if x, ok := x.GetKind().(*Value_EnumValue); ok { - return x.EnumValue + if x != nil { + if x, ok := x.Kind.(*Value_EnumValue); ok { + return x.EnumValue + } } return nil } func (x *Value) GetObjectValue() *anypb.Any { - if x, ok := x.GetKind().(*Value_ObjectValue); ok { - return x.ObjectValue + if x != nil { + if x, ok := x.Kind.(*Value_ObjectValue); ok { + return x.ObjectValue + } } return nil } func (x *Value) GetMapValue() *MapValue { - if x, ok := x.GetKind().(*Value_MapValue); ok { - return x.MapValue + if x != nil { + if x, ok := x.Kind.(*Value_MapValue); ok { + return x.MapValue + } } return nil } func (x *Value) GetListValue() *ListValue { - if x, ok := x.GetKind().(*Value_ListValue); ok { - return x.ListValue + if x != nil { + if x, ok := x.Kind.(*Value_ListValue); ok { + return x.ListValue + } } return nil } func (x *Value) GetTypeValue() string { - if x, ok := x.GetKind().(*Value_TypeValue); ok { - return x.TypeValue + if x != nil { + if x, ok := x.Kind.(*Value_TypeValue); ok { + return x.TypeValue + } } return "" } @@ -244,21 +266,18 @@ func (*Value_ListValue) isValue_Kind() {} func (*Value_TypeValue) isValue_Kind() {} type EnumValue struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Value int32 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` unknownFields protoimpl.UnknownFields - - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - Value int32 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` + sizeCache protoimpl.SizeCache } func (x *EnumValue) Reset() { *x = EnumValue{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_value_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_value_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *EnumValue) String() string { @@ -269,7 +288,7 @@ func (*EnumValue) ProtoMessage() {} func (x *EnumValue) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_value_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -299,20 +318,17 @@ func (x *EnumValue) GetValue() int32 { } type ListValue struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` unknownFields protoimpl.UnknownFields - - Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ListValue) Reset() { *x = ListValue{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_value_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_value_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ListValue) String() string { @@ -323,7 +339,7 @@ func (*ListValue) ProtoMessage() {} func (x *ListValue) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_value_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -346,20 +362,17 @@ func (x *ListValue) GetValues() []*Value { } type MapValue struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Entries []*MapValue_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` unknownFields protoimpl.UnknownFields - - Entries []*MapValue_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` + sizeCache protoimpl.SizeCache } func (x *MapValue) Reset() { *x = MapValue{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_value_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_value_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MapValue) String() string { @@ -370,7 +383,7 @@ func (*MapValue) ProtoMessage() {} func (x *MapValue) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_value_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -393,21 +406,18 @@ func (x *MapValue) GetEntries() []*MapValue_Entry { } type MapValue_Entry struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Key *Value `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value *Value `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` unknownFields protoimpl.UnknownFields - - Key *Value `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Value *Value `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + sizeCache protoimpl.SizeCache } func (x *MapValue_Entry) Reset() { *x = MapValue_Entry{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_value_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_value_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MapValue_Entry) String() string { @@ -418,7 +428,7 @@ func (*MapValue_Entry) ProtoMessage() {} func (x *MapValue_Entry) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_value_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -449,83 +459,58 @@ func (x *MapValue_Entry) GetValue() *Value { var File_cel_expr_value_proto protoreflect.FileDescriptor -var file_cel_expr_value_proto_rawDesc = []byte{ - 0x0a, 0x14, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, - 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, - 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9d, 0x04, 0x0a, 0x05, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6e, 0x75, 0x6c, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x0b, 0x75, 0x69, - 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x64, 0x6f, 0x75, - 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x48, - 0x00, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, - 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, 0x0a, 0x0a, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, - 0x00, 0x52, 0x09, 0x65, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x39, 0x0a, 0x0c, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x48, 0x00, 0x52, 0x0b, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x6d, 0x61, 0x70, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00, - 0x52, 0x08, 0x6d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, 0x0a, 0x0a, 0x6c, 0x69, - 0x73, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x1f, 0x0a, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x74, 0x79, 0x70, 0x65, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0x35, 0x0a, 0x09, 0x45, 0x6e, 0x75, - 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0x34, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x27, 0x0a, - 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x08, 0x4d, 0x61, 0x70, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, - 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, - 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x51, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x21, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x25, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2d, 0x0a, 0x0c, 0x64, 0x65, - 0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x0a, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64, 0x65, - 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} +const file_cel_expr_value_proto_rawDesc = "" + + "\n" + + "\x14cel/expr/value.proto\x12\bcel.expr\x1a\x19google/protobuf/any.proto\x1a\x1cgoogle/protobuf/struct.proto\"\x9d\x04\n" + + "\x05Value\x12;\n" + + "\n" + + "null_value\x18\x01 \x01(\x0e2\x1a.google.protobuf.NullValueH\x00R\tnullValue\x12\x1f\n" + + "\n" + + "bool_value\x18\x02 \x01(\bH\x00R\tboolValue\x12!\n" + + "\vint64_value\x18\x03 \x01(\x03H\x00R\n" + + "int64Value\x12#\n" + + "\fuint64_value\x18\x04 \x01(\x04H\x00R\vuint64Value\x12#\n" + + "\fdouble_value\x18\x05 \x01(\x01H\x00R\vdoubleValue\x12#\n" + + "\fstring_value\x18\x06 \x01(\tH\x00R\vstringValue\x12!\n" + + "\vbytes_value\x18\a \x01(\fH\x00R\n" + + "bytesValue\x124\n" + + "\n" + + "enum_value\x18\t \x01(\v2\x13.cel.expr.EnumValueH\x00R\tenumValue\x129\n" + + "\fobject_value\x18\n" + + " \x01(\v2\x14.google.protobuf.AnyH\x00R\vobjectValue\x121\n" + + "\tmap_value\x18\v \x01(\v2\x12.cel.expr.MapValueH\x00R\bmapValue\x124\n" + + "\n" + + "list_value\x18\f \x01(\v2\x13.cel.expr.ListValueH\x00R\tlistValue\x12\x1f\n" + + "\n" + + "type_value\x18\x0f \x01(\tH\x00R\ttypeValueB\x06\n" + + "\x04kind\"5\n" + + "\tEnumValue\x12\x12\n" + + "\x04type\x18\x01 \x01(\tR\x04type\x12\x14\n" + + "\x05value\x18\x02 \x01(\x05R\x05value\"4\n" + + "\tListValue\x12'\n" + + "\x06values\x18\x01 \x03(\v2\x0f.cel.expr.ValueR\x06values\"\x91\x01\n" + + "\bMapValue\x122\n" + + "\aentries\x18\x01 \x03(\v2\x18.cel.expr.MapValue.EntryR\aentries\x1aQ\n" + + "\x05Entry\x12!\n" + + "\x03key\x18\x01 \x01(\v2\x0f.cel.expr.ValueR\x03key\x12%\n" + + "\x05value\x18\x02 \x01(\v2\x0f.cel.expr.ValueR\x05valueB-\n" + + "\fdev.cel.exprB\n" + + "ValueProtoP\x01Z\fcel.dev/expr\xf8\x01\x01b\x06proto3" var ( file_cel_expr_value_proto_rawDescOnce sync.Once - file_cel_expr_value_proto_rawDescData = file_cel_expr_value_proto_rawDesc + file_cel_expr_value_proto_rawDescData []byte ) func file_cel_expr_value_proto_rawDescGZIP() []byte { file_cel_expr_value_proto_rawDescOnce.Do(func() { - file_cel_expr_value_proto_rawDescData = protoimpl.X.CompressGZIP(file_cel_expr_value_proto_rawDescData) + file_cel_expr_value_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cel_expr_value_proto_rawDesc), len(file_cel_expr_value_proto_rawDesc))) }) return file_cel_expr_value_proto_rawDescData } var file_cel_expr_value_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_cel_expr_value_proto_goTypes = []interface{}{ +var file_cel_expr_value_proto_goTypes = []any{ (*Value)(nil), // 0: cel.expr.Value (*EnumValue)(nil), // 1: cel.expr.EnumValue (*ListValue)(nil), // 2: cel.expr.ListValue @@ -556,69 +541,7 @@ func file_cel_expr_value_proto_init() { if File_cel_expr_value_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_cel_expr_value_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Value); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_value_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EnumValue); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_value_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListValue); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_value_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MapValue); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_value_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MapValue_Entry); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_cel_expr_value_proto_msgTypes[0].OneofWrappers = []interface{}{ + file_cel_expr_value_proto_msgTypes[0].OneofWrappers = []any{ (*Value_NullValue)(nil), (*Value_BoolValue)(nil), (*Value_Int64Value)(nil), @@ -636,7 +559,7 @@ func file_cel_expr_value_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cel_expr_value_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_cel_expr_value_proto_rawDesc), len(file_cel_expr_value_proto_rawDesc)), NumEnums: 0, NumMessages: 5, NumExtensions: 0, @@ -647,7 +570,6 @@ func file_cel_expr_value_proto_init() { MessageInfos: file_cel_expr_value_proto_msgTypes, }.Build() File_cel_expr_value_proto = out.File - file_cel_expr_value_proto_rawDesc = nil file_cel_expr_value_proto_goTypes = nil file_cel_expr_value_proto_depIdxs = nil } diff --git a/vendor/cloud.google.com/go/auth/CHANGES.md b/vendor/cloud.google.com/go/auth/CHANGES.md index c2f636c288..4deca44353 100644 --- a/vendor/cloud.google.com/go/auth/CHANGES.md +++ b/vendor/cloud.google.com/go/auth/CHANGES.md @@ -1,3 +1,10 @@ +## [0.17.0](https://github.com/googleapis/google-cloud-go/releases/tag/auth%2Fv0.17.0) (2025-10-02) + +### Features + +* Add trust boundary support for service accounts and impersonation (HTTP/gRPC) (#11870) ([5c2b665](https://github.com/googleapis/google-cloud-go/commit/5c2b665f392e6dd90192f107188720aa1357e7da)) +* add trust boundary support for external accounts (#12864) ([a67a146](https://github.com/googleapis/google-cloud-go/commit/a67a146a6a88a6f1ba10c409dfce8015ecd60a64)) + # Changelog ## [0.16.5](https://github.com/googleapis/google-cloud-go/compare/auth/v0.16.4...auth/v0.16.5) (2025-08-14) diff --git a/vendor/cloud.google.com/go/auth/auth.go b/vendor/cloud.google.com/go/auth/auth.go index fb24c43eb5..c6d8015833 100644 --- a/vendor/cloud.google.com/go/auth/auth.go +++ b/vendor/cloud.google.com/go/auth/auth.go @@ -483,6 +483,8 @@ type Options2LO struct { Audience string // PrivateClaims allows specifying any custom claims for the JWT. Optional. PrivateClaims map[string]interface{} + // UniverseDomain is the default service domain for a given Cloud universe. + UniverseDomain string // Client is the client to be used to make the underlying token requests. // Optional. diff --git a/vendor/cloud.google.com/go/auth/credentials/compute.go b/vendor/cloud.google.com/go/auth/credentials/compute.go index e4a8078f8b..a2d5c310a4 100644 --- a/vendor/cloud.google.com/go/auth/credentials/compute.go +++ b/vendor/cloud.google.com/go/auth/credentials/compute.go @@ -92,11 +92,11 @@ func (cs *computeProvider) Token(ctx context.Context) (*auth.Token, error) { if res.ExpiresInSec == 0 || res.AccessToken == "" { return nil, errors.New("credentials: incomplete token received from metadata") } - return &auth.Token{ + token := &auth.Token{ Value: res.AccessToken, Type: res.TokenType, Expiry: time.Now().Add(time.Duration(res.ExpiresInSec) * time.Second), Metadata: computeTokenMetadata, - }, nil - + } + return token, nil } diff --git a/vendor/cloud.google.com/go/auth/credentials/detect.go b/vendor/cloud.google.com/go/auth/credentials/detect.go index ad3267eb28..6700e33e14 100644 --- a/vendor/cloud.google.com/go/auth/credentials/detect.go +++ b/vendor/cloud.google.com/go/auth/credentials/detect.go @@ -27,6 +27,7 @@ import ( "cloud.google.com/go/auth" "cloud.google.com/go/auth/internal" "cloud.google.com/go/auth/internal/credsfile" + "cloud.google.com/go/auth/internal/trustboundary" "cloud.google.com/go/compute/metadata" "github.com/googleapis/gax-go/v2/internallog" ) @@ -95,6 +96,10 @@ func DetectDefault(opts *DetectOptions) (*auth.Credentials, error) { if err := opts.validate(); err != nil { return nil, err } + trustBoundaryEnabled, err := trustboundary.IsEnabled() + if err != nil { + return nil, err + } if len(opts.CredentialsJSON) > 0 { return readCredentialsFileJSON(opts.CredentialsJSON, opts) } @@ -119,14 +124,26 @@ func DetectDefault(opts *DetectOptions) (*auth.Credentials, error) { Logger: opts.logger(), UseDefaultClient: true, }) + gceUniverseDomainProvider := &internal.ComputeUniverseDomainProvider{ + MetadataClient: metadataClient, + } + + tp := computeTokenProvider(opts, metadataClient) + if trustBoundaryEnabled { + gceConfigProvider := trustboundary.NewGCEConfigProvider(gceUniverseDomainProvider) + var err error + tp, err = trustboundary.NewProvider(opts.client(), gceConfigProvider, opts.logger(), tp) + if err != nil { + return nil, fmt.Errorf("credentials: failed to initialize GCE trust boundary provider: %w", err) + } + + } return auth.NewCredentials(&auth.CredentialsOptions{ - TokenProvider: computeTokenProvider(opts, metadataClient), + TokenProvider: tp, ProjectIDProvider: auth.CredentialsPropertyFunc(func(ctx context.Context) (string, error) { return metadataClient.ProjectIDWithContext(ctx) }), - UniverseDomainProvider: &internal.ComputeUniverseDomainProvider{ - MetadataClient: metadataClient, - }, + UniverseDomainProvider: gceUniverseDomainProvider, }), nil } diff --git a/vendor/cloud.google.com/go/auth/credentials/filetypes.go b/vendor/cloud.google.com/go/auth/credentials/filetypes.go index 8605e52eec..d2a0424702 100644 --- a/vendor/cloud.google.com/go/auth/credentials/filetypes.go +++ b/vendor/cloud.google.com/go/auth/credentials/filetypes.go @@ -25,6 +25,7 @@ import ( "cloud.google.com/go/auth/credentials/internal/impersonate" internalauth "cloud.google.com/go/auth/internal" "cloud.google.com/go/auth/internal/credsfile" + "cloud.google.com/go/auth/internal/trustboundary" ) func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) { @@ -136,19 +137,34 @@ func handleServiceAccount(f *credsfile.ServiceAccountFile, opts *DetectOptions) return configureSelfSignedJWT(f, opts) } opts2LO := &auth.Options2LO{ - Email: f.ClientEmail, - PrivateKey: []byte(f.PrivateKey), - PrivateKeyID: f.PrivateKeyID, - Scopes: opts.scopes(), - TokenURL: f.TokenURL, - Subject: opts.Subject, - Client: opts.client(), - Logger: opts.logger(), + Email: f.ClientEmail, + PrivateKey: []byte(f.PrivateKey), + PrivateKeyID: f.PrivateKeyID, + Scopes: opts.scopes(), + TokenURL: f.TokenURL, + Subject: opts.Subject, + Client: opts.client(), + Logger: opts.logger(), + UniverseDomain: ud, } if opts2LO.TokenURL == "" { opts2LO.TokenURL = jwtTokenURL } - return auth.New2LOTokenProvider(opts2LO) + + tp, err := auth.New2LOTokenProvider(opts2LO) + if err != nil { + return nil, err + } + + trustBoundaryEnabled, err := trustboundary.IsEnabled() + if err != nil { + return nil, err + } + if !trustBoundaryEnabled { + return tp, nil + } + saConfig := trustboundary.NewServiceAccountConfigProvider(opts2LO.Email, opts2LO.UniverseDomain) + return trustboundary.NewProvider(opts.client(), saConfig, opts.logger(), tp) } func handleUserCredential(f *credsfile.UserCredentialsFile, opts *DetectOptions) (auth.TokenProvider, error) { @@ -187,7 +203,39 @@ func handleExternalAccount(f *credsfile.ExternalAccountFile, opts *DetectOptions if f.ServiceAccountImpersonation != nil { externalOpts.ServiceAccountImpersonationLifetimeSeconds = f.ServiceAccountImpersonation.TokenLifetimeSeconds } - return externalaccount.NewTokenProvider(externalOpts) + tp, err := externalaccount.NewTokenProvider(externalOpts) + if err != nil { + return nil, err + } + trustBoundaryEnabled, err := trustboundary.IsEnabled() + if err != nil { + return nil, err + } + if !trustBoundaryEnabled { + return tp, nil + } + + ud := resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) + var configProvider trustboundary.ConfigProvider + + if f.ServiceAccountImpersonationURL == "" { + // No impersonation, this is a direct external account credential. + // The trust boundary is based on the workload/workforce pool. + var err error + configProvider, err = trustboundary.NewExternalAccountConfigProvider(f.Audience, ud) + if err != nil { + return nil, err + } + } else { + // Impersonation is used. The trust boundary is based on the target service account. + targetSAEmail, err := impersonate.ExtractServiceAccountEmail(f.ServiceAccountImpersonationURL) + if err != nil { + return nil, fmt.Errorf("credentials: could not extract target service account email for trust boundary: %w", err) + } + configProvider = trustboundary.NewServiceAccountConfigProvider(targetSAEmail, ud) + } + + return trustboundary.NewProvider(opts.client(), configProvider, opts.logger(), tp) } func handleExternalAccountAuthorizedUser(f *credsfile.ExternalAccountAuthorizedUserFile, opts *DetectOptions) (auth.TokenProvider, error) { @@ -202,7 +250,24 @@ func handleExternalAccountAuthorizedUser(f *credsfile.ExternalAccountAuthorizedU Client: opts.client(), Logger: opts.logger(), } - return externalaccountuser.NewTokenProvider(externalOpts) + tp, err := externalaccountuser.NewTokenProvider(externalOpts) + if err != nil { + return nil, err + } + trustBoundaryEnabled, err := trustboundary.IsEnabled() + if err != nil { + return nil, err + } + if !trustBoundaryEnabled { + return tp, nil + } + + ud := resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) + configProvider, err := trustboundary.NewExternalAccountConfigProvider(f.Audience, ud) + if err != nil { + return nil, err + } + return trustboundary.NewProvider(opts.client(), configProvider, opts.logger(), tp) } func handleImpersonatedServiceAccount(f *credsfile.ImpersonatedServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { @@ -210,20 +275,38 @@ func handleImpersonatedServiceAccount(f *credsfile.ImpersonatedServiceAccountFil return nil, errors.New("missing 'source_credentials' field or 'service_account_impersonation_url' in credentials") } - tp, err := fileCredentials(f.CredSource, opts) + sourceTP, err := fileCredentials(f.CredSource, opts) if err != nil { return nil, err } - return impersonate.NewTokenProvider(&impersonate.Options{ - URL: f.ServiceAccountImpersonationURL, - Scopes: opts.scopes(), - Tp: tp, - Delegates: f.Delegates, - Client: opts.client(), - Logger: opts.logger(), - }) + ud := resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) + impOpts := &impersonate.Options{ + URL: f.ServiceAccountImpersonationURL, + Scopes: opts.scopes(), + Tp: sourceTP, + Delegates: f.Delegates, + Client: opts.client(), + Logger: opts.logger(), + UniverseDomain: ud, + } + tp, err := impersonate.NewTokenProvider(impOpts) + if err != nil { + return nil, err + } + trustBoundaryEnabled, err := trustboundary.IsEnabled() + if err != nil { + return nil, err + } + if !trustBoundaryEnabled { + return tp, nil + } + targetSAEmail, err := impersonate.ExtractServiceAccountEmail(f.ServiceAccountImpersonationURL) + if err != nil { + return nil, fmt.Errorf("credentials: could not extract target service account email for trust boundary: %w", err) + } + targetSAConfig := trustboundary.NewServiceAccountConfigProvider(targetSAEmail, ud) + return trustboundary.NewProvider(opts.client(), targetSAConfig, opts.logger(), tp) } - func handleGDCHServiceAccount(f *credsfile.GDCHServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { return gdch.NewTokenProvider(f, &gdch.Options{ STSAudience: opts.STSAudience, diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go b/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go index b3a99261fa..8253376ef8 100644 --- a/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go +++ b/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go @@ -22,10 +22,12 @@ import ( "fmt" "log/slog" "net/http" + "regexp" "time" "cloud.google.com/go/auth" "cloud.google.com/go/auth/internal" + "cloud.google.com/go/auth/internal/transport/headers" "github.com/googleapis/gax-go/v2/internallog" ) @@ -34,6 +36,8 @@ const ( authHeaderKey = "Authorization" ) +var serviceAccountEmailRegex = regexp.MustCompile(`serviceAccounts/(.+?):generateAccessToken`) + // generateAccesstokenReq is used for service account impersonation type generateAccessTokenReq struct { Delegates []string `json:"delegates,omitempty"` @@ -81,6 +85,8 @@ type Options struct { // enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default // logger will be used. Optional. Logger *slog.Logger + // UniverseDomain is the default service domain for a given Cloud universe. + UniverseDomain string } func (o *Options) validate() error { @@ -114,9 +120,11 @@ func (o *Options) Token(ctx context.Context) (*auth.Token, error) { return nil, fmt.Errorf("credentials: unable to create impersonation request: %w", err) } req.Header.Set("Content-Type", "application/json") - if err := setAuthHeader(ctx, o.Tp, req); err != nil { + sourceToken, err := o.Tp.Token(ctx) + if err != nil { return nil, err } + headers.SetAuthHeader(sourceToken, req) logger.DebugContext(ctx, "impersonated token request", "request", internallog.HTTPRequest(req, b)) resp, body, err := internal.DoRequest(o.Client, req) if err != nil { @@ -135,22 +143,26 @@ func (o *Options) Token(ctx context.Context) (*auth.Token, error) { if err != nil { return nil, fmt.Errorf("credentials: unable to parse expiry: %w", err) } - return &auth.Token{ + token := &auth.Token{ Value: accessTokenResp.AccessToken, Expiry: expiry, Type: internal.TokenTypeBearer, - }, nil + } + return token, nil } -func setAuthHeader(ctx context.Context, tp auth.TokenProvider, r *http.Request) error { - t, err := tp.Token(ctx) - if err != nil { - return err - } - typ := t.Type - if typ == "" { - typ = internal.TokenTypeBearer +// ExtractServiceAccountEmail extracts the service account email from the impersonation URL. +// The impersonation URL is expected to be in the format: +// https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/{SERVICE_ACCOUNT_EMAIL}:generateAccessToken +// or +// https://iamcredentials.googleapis.com/v1/projects/{PROJECT_ID}/serviceAccounts/{SERVICE_ACCOUNT_EMAIL}:generateAccessToken +// Returns an error if the email cannot be extracted. +func ExtractServiceAccountEmail(impersonationURL string) (string, error) { + matches := serviceAccountEmailRegex.FindStringSubmatch(impersonationURL) + + if len(matches) < 2 { + return "", fmt.Errorf("credentials: invalid impersonation URL format: %s", impersonationURL) } - r.Header.Set(authHeaderKey, typ+" "+t.Value) - return nil + + return matches[1], nil } diff --git a/vendor/cloud.google.com/go/auth/httptransport/httptransport.go b/vendor/cloud.google.com/go/auth/httptransport/httptransport.go index 5758e85b5d..c9126535d7 100644 --- a/vendor/cloud.google.com/go/auth/httptransport/httptransport.go +++ b/vendor/cloud.google.com/go/auth/httptransport/httptransport.go @@ -25,8 +25,8 @@ import ( "cloud.google.com/go/auth" detect "cloud.google.com/go/auth/credentials" - "cloud.google.com/go/auth/internal" "cloud.google.com/go/auth/internal/transport" + "cloud.google.com/go/auth/internal/transport/headers" "github.com/googleapis/gax-go/v2/internallog" ) @@ -236,12 +236,10 @@ func NewClient(opts *Options) (*http.Client, error) { }, nil } -// SetAuthHeader uses the provided token to set the Authorization header on a -// request. If the token.Type is empty, the type is assumed to be Bearer. +// SetAuthHeader uses the provided token to set the Authorization and trust +// boundary headers on an http.Request. If the token.Type is empty, the type is +// assumed to be Bearer. This is the recommended way to set authorization +// headers on a custom http.Request. func SetAuthHeader(token *auth.Token, req *http.Request) { - typ := token.Type - if typ == "" { - typ = internal.TokenTypeBearer - } - req.Header.Set("Authorization", typ+" "+token.Value) + headers.SetAuthHeader(token, req) } diff --git a/vendor/cloud.google.com/go/auth/httptransport/transport.go b/vendor/cloud.google.com/go/auth/httptransport/transport.go index ee215b6dc6..3feb997c76 100644 --- a/vendor/cloud.google.com/go/auth/httptransport/transport.go +++ b/vendor/cloud.google.com/go/auth/httptransport/transport.go @@ -27,6 +27,7 @@ import ( "cloud.google.com/go/auth/internal" "cloud.google.com/go/auth/internal/transport" "cloud.google.com/go/auth/internal/transport/cert" + "cloud.google.com/go/auth/internal/transport/headers" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "golang.org/x/net/http2" ) @@ -228,7 +229,7 @@ func (t *authTransport) RoundTrip(req *http.Request) (*http.Response, error) { } } req2 := req.Clone(req.Context()) - SetAuthHeader(token, req2) + headers.SetAuthHeader(token, req2) reqBodyClosed = true return t.base.RoundTrip(req2) } diff --git a/vendor/cloud.google.com/go/auth/internal/internal.go b/vendor/cloud.google.com/go/auth/internal/internal.go index 6a8eab6eb9..72a8a6b7a5 100644 --- a/vendor/cloud.google.com/go/auth/internal/internal.go +++ b/vendor/cloud.google.com/go/auth/internal/internal.go @@ -47,6 +47,12 @@ const ( // DefaultUniverseDomain is the default value for universe domain. // Universe domain is the default service domain for a given Cloud universe. DefaultUniverseDomain = "googleapis.com" + + // TrustBoundaryNoOp is a constant indicating no trust boundary is enforced. + TrustBoundaryNoOp = "0x0" + + // TrustBoundaryDataKey is the key used to store trust boundary data in a token's metadata. + TrustBoundaryDataKey = "google.auth.trust_boundary_data" ) type clonableTransport interface { @@ -223,3 +229,56 @@ func getMetadataUniverseDomain(ctx context.Context, client *metadata.Client) (st func FormatIAMServiceAccountResource(name string) string { return fmt.Sprintf("projects/-/serviceAccounts/%s", name) } + +// TrustBoundaryData represents the trust boundary data associated with a token. +// It contains information about the regions or environments where the token is valid. +type TrustBoundaryData struct { + // Locations is the list of locations that the token is allowed to be used in. + Locations []string + // EncodedLocations represents the locations in an encoded format. + EncodedLocations string +} + +// NewTrustBoundaryData returns a new TrustBoundaryData with the specified locations and encoded locations. +func NewTrustBoundaryData(locations []string, encodedLocations string) *TrustBoundaryData { + // Ensure consistency by treating a nil slice as an empty slice. + if locations == nil { + locations = []string{} + } + locationsCopy := make([]string, len(locations)) + copy(locationsCopy, locations) + return &TrustBoundaryData{ + Locations: locationsCopy, + EncodedLocations: encodedLocations, + } +} + +// NewNoOpTrustBoundaryData returns a new TrustBoundaryData with no restrictions. +func NewNoOpTrustBoundaryData() *TrustBoundaryData { + return &TrustBoundaryData{ + Locations: []string{}, + EncodedLocations: TrustBoundaryNoOp, + } +} + +// TrustBoundaryHeader returns the value for the x-allowed-locations header and a bool +// indicating if the header should be set. The return values are structured to +// handle three distinct states required by the backend: +// 1. Header not set: (value="", present=false) -> data is empty. +// 2. Header set to an empty string: (value="", present=true) -> data is a no-op. +// 3. Header set to a value: (value="...", present=true) -> data has locations. +func (t TrustBoundaryData) TrustBoundaryHeader() (value string, present bool) { + if t.EncodedLocations == "" { + // If the data is empty, the header should not be present. + return "", false + } + + // If data is not empty, the header should always be present. + present = true + value = "" + if t.EncodedLocations != TrustBoundaryNoOp { + value = t.EncodedLocations + } + // For a no-op, the backend requires an empty string. + return value, present +} diff --git a/vendor/cloud.google.com/go/auth/internal/retry/retry.go b/vendor/cloud.google.com/go/auth/internal/retry/retry.go new file mode 100644 index 0000000000..276cc4a3e2 --- /dev/null +++ b/vendor/cloud.google.com/go/auth/internal/retry/retry.go @@ -0,0 +1,117 @@ +// Copyright 2025 Google LLC +// +// 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. + +package retry + +import ( + "context" + "io" + "math/rand" + "net/http" + "time" +) + +const ( + maxRetryAttempts = 5 +) + +var ( + syscallRetryable = func(error) bool { return false } +) + +// defaultBackoff is basically equivalent to gax.Backoff without the need for +// the dependency. +type defaultBackoff struct { + max time.Duration + mul float64 + cur time.Duration +} + +func (b *defaultBackoff) Pause() time.Duration { + d := time.Duration(1 + rand.Int63n(int64(b.cur))) + b.cur = time.Duration(float64(b.cur) * b.mul) + if b.cur > b.max { + b.cur = b.max + } + return d +} + +// Sleep is the equivalent of gax.Sleep without the need for the dependency. +func Sleep(ctx context.Context, d time.Duration) error { + t := time.NewTimer(d) + select { + case <-ctx.Done(): + t.Stop() + return ctx.Err() + case <-t.C: + return nil + } +} + +// New returns a new Retryer with the default backoff strategy. +func New() *Retryer { + return &Retryer{bo: &defaultBackoff{ + cur: 100 * time.Millisecond, + max: 30 * time.Second, + mul: 2, + }} +} + +type backoff interface { + Pause() time.Duration +} + +// Retryer is a retryer for HTTP requests. +type Retryer struct { + bo backoff + attempts int +} + +// Retry determines if a request should be retried. +func (r *Retryer) Retry(status int, err error) (time.Duration, bool) { + if status == http.StatusOK { + return 0, false + } + retryOk := shouldRetry(status, err) + if !retryOk { + return 0, false + } + if r.attempts == maxRetryAttempts { + return 0, false + } + r.attempts++ + return r.bo.Pause(), true +} + +func shouldRetry(status int, err error) bool { + if 500 <= status && status <= 599 { + return true + } + if err == io.ErrUnexpectedEOF { + return true + } + // Transient network errors should be retried. + if syscallRetryable(err) { + return true + } + if err, ok := err.(interface{ Temporary() bool }); ok { + if err.Temporary() { + return true + } + } + if err, ok := err.(interface{ Unwrap() error }); ok { + return shouldRetry(status, err.Unwrap()) + } + return false +} diff --git a/vendor/cloud.google.com/go/auth/internal/transport/headers/headers.go b/vendor/cloud.google.com/go/auth/internal/transport/headers/headers.go new file mode 100644 index 0000000000..5483a763c4 --- /dev/null +++ b/vendor/cloud.google.com/go/auth/internal/transport/headers/headers.go @@ -0,0 +1,61 @@ +// Copyright 2025 Google LLC +// +// 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. + +package headers + +import ( + "net/http" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/internal" +) + +// SetAuthHeader uses the provided token to set the Authorization and trust +// boundary headers on a request. If the token.Type is empty, the type is +// assumed to be Bearer. +func SetAuthHeader(token *auth.Token, req *http.Request) { + typ := token.Type + if typ == "" { + typ = internal.TokenTypeBearer + } + req.Header.Set("Authorization", typ+" "+token.Value) + + if headerVal, setHeader := getTrustBoundaryHeader(token); setHeader { + req.Header.Set("x-allowed-locations", headerVal) + } +} + +// SetAuthMetadata uses the provided token to set the Authorization and trust +// boundary metadata. If the token.Type is empty, the type is assumed to be +// Bearer. +func SetAuthMetadata(token *auth.Token, m map[string]string) { + typ := token.Type + if typ == "" { + typ = internal.TokenTypeBearer + } + m["authorization"] = typ + " " + token.Value + + if headerVal, setHeader := getTrustBoundaryHeader(token); setHeader { + m["x-allowed-locations"] = headerVal + } +} + +func getTrustBoundaryHeader(token *auth.Token) (val string, present bool) { + if data, ok := token.Metadata[internal.TrustBoundaryDataKey]; ok { + if tbd, ok := data.(internal.TrustBoundaryData); ok { + return tbd.TrustBoundaryHeader() + } + } + return "", false +} diff --git a/vendor/cloud.google.com/go/auth/internal/trustboundary/external_accounts_config_providers.go b/vendor/cloud.google.com/go/auth/internal/trustboundary/external_accounts_config_providers.go new file mode 100644 index 0000000000..8fa5600bdc --- /dev/null +++ b/vendor/cloud.google.com/go/auth/internal/trustboundary/external_accounts_config_providers.go @@ -0,0 +1,100 @@ +// Copyright 2025 Google LLC +// +// 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. + +package trustboundary + +import ( + "context" + "fmt" + "regexp" +) + +const ( + workloadAllowedLocationsEndpoint = "https://iamcredentials.%s/v1/projects/%s/locations/global/workloadIdentityPools/%s/allowedLocations" + workforceAllowedLocationsEndpoint = "https://iamcredentials.%s/v1/locations/global/workforcePools/%s/allowedLocations" +) + +var ( + workforceAudiencePattern = regexp.MustCompile(`//iam\.([^/]+)/locations/global/workforcePools/([^/]+)`) + workloadAudiencePattern = regexp.MustCompile(`//iam\.([^/]+)/projects/([^/]+)/locations/global/workloadIdentityPools/([^/]+)`) +) + +// NewExternalAccountConfigProvider creates a new ConfigProvider for external accounts. +func NewExternalAccountConfigProvider(audience, inputUniverseDomain string) (ConfigProvider, error) { + var audienceDomain, projectNumber, poolID string + var isWorkload bool + + matches := workloadAudiencePattern.FindStringSubmatch(audience) + if len(matches) == 4 { // Expecting full match, domain, projectNumber, poolID + audienceDomain = matches[1] + projectNumber = matches[2] + poolID = matches[3] + isWorkload = true + } else { + matches = workforceAudiencePattern.FindStringSubmatch(audience) + if len(matches) == 3 { // Expecting full match, domain, poolID + audienceDomain = matches[1] + poolID = matches[2] + isWorkload = false + } else { + return nil, fmt.Errorf("trustboundary: unknown audience format: %q", audience) + } + } + + effectiveUniverseDomain := inputUniverseDomain + if effectiveUniverseDomain == "" { + effectiveUniverseDomain = audienceDomain + } else if audienceDomain != "" && effectiveUniverseDomain != audienceDomain { + return nil, fmt.Errorf("trustboundary: provided universe domain (%q) does not match domain in audience (%q)", inputUniverseDomain, audienceDomain) + } + + if isWorkload { + return &workloadIdentityPoolConfigProvider{ + projectNumber: projectNumber, + poolID: poolID, + universeDomain: effectiveUniverseDomain, + }, nil + } + return &workforcePoolConfigProvider{ + poolID: poolID, + universeDomain: effectiveUniverseDomain, + }, nil +} + +type workforcePoolConfigProvider struct { + poolID string + universeDomain string +} + +func (p *workforcePoolConfigProvider) GetTrustBoundaryEndpoint(ctx context.Context) (string, error) { + return fmt.Sprintf(workforceAllowedLocationsEndpoint, p.universeDomain, p.poolID), nil +} + +func (p *workforcePoolConfigProvider) GetUniverseDomain(ctx context.Context) (string, error) { + return p.universeDomain, nil +} + +type workloadIdentityPoolConfigProvider struct { + projectNumber string + poolID string + universeDomain string +} + +func (p *workloadIdentityPoolConfigProvider) GetTrustBoundaryEndpoint(ctx context.Context) (string, error) { + return fmt.Sprintf(workloadAllowedLocationsEndpoint, p.universeDomain, p.projectNumber, p.poolID), nil +} + +func (p *workloadIdentityPoolConfigProvider) GetUniverseDomain(ctx context.Context) (string, error) { + return p.universeDomain, nil +} diff --git a/vendor/cloud.google.com/go/auth/internal/trustboundary/trust_boundary.go b/vendor/cloud.google.com/go/auth/internal/trustboundary/trust_boundary.go new file mode 100644 index 0000000000..bf898fffd6 --- /dev/null +++ b/vendor/cloud.google.com/go/auth/internal/trustboundary/trust_boundary.go @@ -0,0 +1,392 @@ +// Copyright 2025 Google LLC +// +// 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. + +package trustboundary + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "net/http" + "os" + "strings" + "sync" + + "cloud.google.com/go/auth" + "cloud.google.com/go/auth/internal" + "cloud.google.com/go/auth/internal/retry" + "cloud.google.com/go/auth/internal/transport/headers" + "github.com/googleapis/gax-go/v2/internallog" +) + +const ( + // serviceAccountAllowedLocationsEndpoint is the URL for fetching allowed locations for a given service account email. + serviceAccountAllowedLocationsEndpoint = "https://iamcredentials.%s/v1/projects/-/serviceAccounts/%s/allowedLocations" +) + +// isEnabled wraps isTrustBoundaryEnabled with sync.OnceValues to ensure it's +// called only once. +var isEnabled = sync.OnceValues(isTrustBoundaryEnabled) + +// IsEnabled returns if the trust boundary feature is enabled and an error if +// the configuration is invalid. The underlying check is performed only once. +func IsEnabled() (bool, error) { + return isEnabled() +} + +// isTrustBoundaryEnabled checks if the trust boundary feature is enabled via +// GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED environment variable. +// +// If the environment variable is not set, it is considered false. +// +// The environment variable is interpreted as a boolean with the following +// (case-insensitive) rules: +// - "true", "1" are considered true. +// - "false", "0" are considered false. +// +// Any other values will return an error. +func isTrustBoundaryEnabled() (bool, error) { + const envVar = "GOOGLE_AUTH_TRUST_BOUNDARY_ENABLED" + val, ok := os.LookupEnv(envVar) + if !ok { + return false, nil + } + val = strings.ToLower(val) + switch val { + case "true", "1": + return true, nil + case "false", "0": + return false, nil + default: + return false, fmt.Errorf(`invalid value for %s: %q. Must be one of "true", "false", "1", or "0"`, envVar, val) + } +} + +// ConfigProvider provides specific configuration for trust boundary lookups. +type ConfigProvider interface { + // GetTrustBoundaryEndpoint returns the endpoint URL for the trust boundary lookup. + GetTrustBoundaryEndpoint(ctx context.Context) (url string, err error) + // GetUniverseDomain returns the universe domain associated with the credential. + // It may return an error if the universe domain cannot be determined. + GetUniverseDomain(ctx context.Context) (string, error) +} + +// AllowedLocationsResponse is the structure of the response from the Trust Boundary API. +type AllowedLocationsResponse struct { + // Locations is the list of allowed locations. + Locations []string `json:"locations"` + // EncodedLocations is the encoded representation of the allowed locations. + EncodedLocations string `json:"encodedLocations"` +} + +// fetchTrustBoundaryData fetches the trust boundary data from the API. +func fetchTrustBoundaryData(ctx context.Context, client *http.Client, url string, token *auth.Token, logger *slog.Logger) (*internal.TrustBoundaryData, error) { + if logger == nil { + logger = slog.New(slog.NewTextHandler(io.Discard, nil)) + } + if client == nil { + return nil, errors.New("trustboundary: HTTP client is required") + } + + if url == "" { + return nil, errors.New("trustboundary: URL cannot be empty") + } + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return nil, fmt.Errorf("trustboundary: failed to create trust boundary request: %w", err) + } + + if token == nil || token.Value == "" { + return nil, errors.New("trustboundary: access token required for lookup API authentication") + } + headers.SetAuthHeader(token, req) + logger.DebugContext(ctx, "trust boundary request", "request", internallog.HTTPRequest(req, nil)) + + retryer := retry.New() + var response *http.Response + for { + response, err = client.Do(req) + + var statusCode int + if response != nil { + statusCode = response.StatusCode + } + pause, shouldRetry := retryer.Retry(statusCode, err) + + if !shouldRetry { + break + } + + if response != nil { + // Drain and close the body to reuse the connection + io.Copy(io.Discard, response.Body) + response.Body.Close() + } + + if err := retry.Sleep(ctx, pause); err != nil { + return nil, err + } + } + + if err != nil { + return nil, fmt.Errorf("trustboundary: failed to fetch trust boundary: %w", err) + } + defer response.Body.Close() + + body, err := io.ReadAll(response.Body) + if err != nil { + return nil, fmt.Errorf("trustboundary: failed to read trust boundary response: %w", err) + } + + logger.DebugContext(ctx, "trust boundary response", "response", internallog.HTTPResponse(response, body)) + + if response.StatusCode != http.StatusOK { + return nil, fmt.Errorf("trustboundary: trust boundary request failed with status: %s, body: %s", response.Status, string(body)) + } + + apiResponse := AllowedLocationsResponse{} + if err := json.Unmarshal(body, &apiResponse); err != nil { + return nil, fmt.Errorf("trustboundary: failed to unmarshal trust boundary response: %w", err) + } + + if apiResponse.EncodedLocations == "" { + return nil, errors.New("trustboundary: invalid API response: encodedLocations is empty") + } + + return internal.NewTrustBoundaryData(apiResponse.Locations, apiResponse.EncodedLocations), nil +} + +// serviceAccountConfig holds configuration for SA trust boundary lookups. +// It implements the ConfigProvider interface. +type serviceAccountConfig struct { + ServiceAccountEmail string + UniverseDomain string +} + +// NewServiceAccountConfigProvider creates a new config for service accounts. +func NewServiceAccountConfigProvider(saEmail, universeDomain string) ConfigProvider { + return &serviceAccountConfig{ + ServiceAccountEmail: saEmail, + UniverseDomain: universeDomain, + } +} + +// GetTrustBoundaryEndpoint returns the formatted URL for fetching allowed locations +// for the configured service account and universe domain. +func (sac *serviceAccountConfig) GetTrustBoundaryEndpoint(ctx context.Context) (url string, err error) { + if sac.ServiceAccountEmail == "" { + return "", errors.New("trustboundary: service account email cannot be empty for config") + } + ud := sac.UniverseDomain + if ud == "" { + ud = internal.DefaultUniverseDomain + } + return fmt.Sprintf(serviceAccountAllowedLocationsEndpoint, ud, sac.ServiceAccountEmail), nil +} + +// GetUniverseDomain returns the configured universe domain, defaulting to +// [internal.DefaultUniverseDomain] if not explicitly set. +func (sac *serviceAccountConfig) GetUniverseDomain(ctx context.Context) (string, error) { + if sac.UniverseDomain == "" { + return internal.DefaultUniverseDomain, nil + } + return sac.UniverseDomain, nil +} + +// DataProvider fetches and caches trust boundary Data. +// It implements the DataProvider interface and uses a ConfigProvider +// to get type-specific details for the lookup. +type DataProvider struct { + client *http.Client + configProvider ConfigProvider + data *internal.TrustBoundaryData + logger *slog.Logger + base auth.TokenProvider +} + +// NewProvider wraps the provided base [auth.TokenProvider] to create a new +// provider that injects tokens with trust boundary data. It uses the provided +// HTTP client and configProvider to fetch the data and attach it to the token's +// metadata. +func NewProvider(client *http.Client, configProvider ConfigProvider, logger *slog.Logger, base auth.TokenProvider) (*DataProvider, error) { + if client == nil { + return nil, errors.New("trustboundary: HTTP client cannot be nil for DataProvider") + } + if configProvider == nil { + return nil, errors.New("trustboundary: ConfigProvider cannot be nil for DataProvider") + } + p := &DataProvider{ + client: client, + configProvider: configProvider, + logger: internallog.New(logger), + base: base, + } + return p, nil +} + +// Token retrieves a token from the base provider and injects it with trust +// boundary data. +func (p *DataProvider) Token(ctx context.Context) (*auth.Token, error) { + // Get the original token. + token, err := p.base.Token(ctx) + if err != nil { + return nil, err + } + + tbData, err := p.GetTrustBoundaryData(ctx, token) + if err != nil { + return nil, fmt.Errorf("trustboundary: error fetching the trust boundary data: %w", err) + } + if tbData != nil { + if token.Metadata == nil { + token.Metadata = make(map[string]interface{}) + } + token.Metadata[internal.TrustBoundaryDataKey] = *tbData + } + return token, nil +} + +// GetTrustBoundaryData retrieves the trust boundary data. +// It first checks the universe domain: if it's non-default, a NoOp is returned. +// Otherwise, it checks a local cache. If the data is not cached as NoOp, +// it fetches new data from the endpoint provided by its ConfigProvider, +// using the given accessToken for authentication. Results are cached. +// If fetching fails, it returns previously cached data if available, otherwise the fetch error. +func (p *DataProvider) GetTrustBoundaryData(ctx context.Context, token *auth.Token) (*internal.TrustBoundaryData, error) { + // Check the universe domain. + uniDomain, err := p.configProvider.GetUniverseDomain(ctx) + if err != nil { + return nil, fmt.Errorf("trustboundary: error getting universe domain: %w", err) + } + if uniDomain != "" && uniDomain != internal.DefaultUniverseDomain { + if p.data == nil || p.data.EncodedLocations != internal.TrustBoundaryNoOp { + p.data = internal.NewNoOpTrustBoundaryData() + } + return p.data, nil + } + + // Check cache for a no-op result from a previous API call. + cachedData := p.data + if cachedData != nil && cachedData.EncodedLocations == internal.TrustBoundaryNoOp { + return cachedData, nil + } + + // Get the endpoint + url, err := p.configProvider.GetTrustBoundaryEndpoint(ctx) + if err != nil { + return nil, fmt.Errorf("trustboundary: error getting the lookup endpoint: %w", err) + } + + // Proceed to fetch new data. + newData, fetchErr := fetchTrustBoundaryData(ctx, p.client, url, token, p.logger) + + if fetchErr != nil { + // Fetch failed. Fallback to cachedData if available. + if cachedData != nil { + return cachedData, nil // Successful fallback + } + // No cache to fallback to. + return nil, fmt.Errorf("trustboundary: failed to fetch trust boundary data for endpoint %s and no cache available: %w", url, fetchErr) + } + + // Fetch successful. Update cache. + p.data = newData + return newData, nil +} + +// GCEConfigProvider implements ConfigProvider for GCE environments. +// It lazily fetches and caches the necessary metadata (service account email, universe domain) +// from the GCE metadata server. +type GCEConfigProvider struct { + // universeDomainProvider provides the universe domain and underlying metadata client. + universeDomainProvider *internal.ComputeUniverseDomainProvider + + // Caching for service account email + saOnce sync.Once + saEmail string + saEmailErr error + + // Caching for universe domain + udOnce sync.Once + ud string + udErr error +} + +// NewGCEConfigProvider creates a new GCEConfigProvider +// which uses the provided gceUDP to interact with the GCE metadata server. +func NewGCEConfigProvider(gceUDP *internal.ComputeUniverseDomainProvider) *GCEConfigProvider { + // The validity of gceUDP and its internal MetadataClient will be checked + // within the GetTrustBoundaryEndpoint and GetUniverseDomain methods. + return &GCEConfigProvider{ + universeDomainProvider: gceUDP, + } +} + +func (g *GCEConfigProvider) fetchSA(ctx context.Context) { + if g.universeDomainProvider == nil || g.universeDomainProvider.MetadataClient == nil { + g.saEmailErr = errors.New("trustboundary: GCEConfigProvider not properly initialized (missing ComputeUniverseDomainProvider or MetadataClient)") + return + } + mdClient := g.universeDomainProvider.MetadataClient + saEmail, err := mdClient.EmailWithContext(ctx, "default") + if err != nil { + g.saEmailErr = fmt.Errorf("trustboundary: GCE config: failed to get service account email: %w", err) + return + } + g.saEmail = saEmail +} + +func (g *GCEConfigProvider) fetchUD(ctx context.Context) { + if g.universeDomainProvider == nil || g.universeDomainProvider.MetadataClient == nil { + g.udErr = errors.New("trustboundary: GCEConfigProvider not properly initialized (missing ComputeUniverseDomainProvider or MetadataClient)") + return + } + ud, err := g.universeDomainProvider.GetProperty(ctx) + if err != nil { + g.udErr = fmt.Errorf("trustboundary: GCE config: failed to get universe domain: %w", err) + return + } + if ud == "" { + ud = internal.DefaultUniverseDomain + } + g.ud = ud +} + +// GetTrustBoundaryEndpoint constructs the trust boundary lookup URL for a GCE environment. +// It uses cached metadata (service account email, universe domain) after the first call. +func (g *GCEConfigProvider) GetTrustBoundaryEndpoint(ctx context.Context) (string, error) { + g.saOnce.Do(func() { g.fetchSA(ctx) }) + if g.saEmailErr != nil { + return "", g.saEmailErr + } + g.udOnce.Do(func() { g.fetchUD(ctx) }) + if g.udErr != nil { + return "", g.udErr + } + return fmt.Sprintf(serviceAccountAllowedLocationsEndpoint, g.ud, g.saEmail), nil +} + +// GetUniverseDomain retrieves the universe domain from the GCE metadata server. +// It uses a cached value after the first call. +func (g *GCEConfigProvider) GetUniverseDomain(ctx context.Context) (string, error) { + g.udOnce.Do(func() { g.fetchUD(ctx) }) + if g.udErr != nil { + return "", g.udErr + } + return g.ud, nil +} diff --git a/vendor/cloud.google.com/go/auth/internal/version.go b/vendor/cloud.google.com/go/auth/internal/version.go new file mode 100644 index 0000000000..e2f56cf4d8 --- /dev/null +++ b/vendor/cloud.google.com/go/auth/internal/version.go @@ -0,0 +1,20 @@ +// Copyright 2025 Google LLC +// +// 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. + +// Code generated by gapicgen. DO NOT EDIT. + +package internal + +// Version is the current tagged release of the library. +const Version = "0.17.0" diff --git a/vendor/cloud.google.com/go/compute/metadata/CHANGES.md b/vendor/cloud.google.com/go/compute/metadata/CHANGES.md index a2a643ef74..e384683c50 100644 --- a/vendor/cloud.google.com/go/compute/metadata/CHANGES.md +++ b/vendor/cloud.google.com/go/compute/metadata/CHANGES.md @@ -1,5 +1,40 @@ # Changes +## [0.9.0](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.8.4...compute/metadata/v0.9.0) (2025-09-24) + + +### Features + +* **compute/metadata:** Retry on HTTP 429 ([#12932](https://github.com/googleapis/google-cloud-go/issues/12932)) ([1e91f5c](https://github.com/googleapis/google-cloud-go/commit/1e91f5c07acacd38ecdd4ff3e83e092b745e0bc2)) + +## [0.8.4](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.8.3...compute/metadata/v0.8.4) (2025-09-18) + + +### Bug Fixes + +* **compute/metadata:** Set subClient for UseDefaultClient case ([#12911](https://github.com/googleapis/google-cloud-go/issues/12911)) ([9e2646b](https://github.com/googleapis/google-cloud-go/commit/9e2646b1821231183fd775bb107c062865eeaccd)) + +## [0.8.3](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.8.2...compute/metadata/v0.8.3) (2025-09-17) + + +### Bug Fixes + +* **compute/metadata:** Disable Client timeouts for subscription client ([#12910](https://github.com/googleapis/google-cloud-go/issues/12910)) ([187a58a](https://github.com/googleapis/google-cloud-go/commit/187a58a540494e1e8562b046325b8cad8cf7af4a)) + +## [0.8.2](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.8.1...compute/metadata/v0.8.2) (2025-09-17) + + +### Bug Fixes + +* **compute/metadata:** Racy test and uninitialized subClient ([#12892](https://github.com/googleapis/google-cloud-go/issues/12892)) ([4943ca2](https://github.com/googleapis/google-cloud-go/commit/4943ca2bf83908a23806247bc4252dfb440d09cc)), refs [#12888](https://github.com/googleapis/google-cloud-go/issues/12888) + +## [0.8.1](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.8.0...compute/metadata/v0.8.1) (2025-09-16) + + +### Bug Fixes + +* **compute/metadata:** Use separate client for subscribe methods ([#12885](https://github.com/googleapis/google-cloud-go/issues/12885)) ([76b80f8](https://github.com/googleapis/google-cloud-go/commit/76b80f8df9bf9339d175407e8c15936fe1ac1c9c)) + ## [0.8.0](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.7.0...compute/metadata/v0.8.0) (2025-08-06) diff --git a/vendor/cloud.google.com/go/compute/metadata/metadata.go b/vendor/cloud.google.com/go/compute/metadata/metadata.go index 6873ad8d1a..6bd1891660 100644 --- a/vendor/cloud.google.com/go/compute/metadata/metadata.go +++ b/vendor/cloud.google.com/go/compute/metadata/metadata.go @@ -22,6 +22,7 @@ package metadata // import "cloud.google.com/go/compute/metadata" import ( "context" "encoding/json" + "errors" "fmt" "io" "log/slog" @@ -62,21 +63,26 @@ var ( ) var defaultClient = &Client{ - hc: newDefaultHTTPClient(), - logger: slog.New(noOpHandler{}), + hc: newDefaultHTTPClient(true), + subClient: newDefaultHTTPClient(false), + logger: slog.New(noOpHandler{}), } -func newDefaultHTTPClient() *http.Client { - return &http.Client{ - Transport: &http.Transport{ - Dial: (&net.Dialer{ - Timeout: 2 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - IdleConnTimeout: 60 * time.Second, - }, - Timeout: 5 * time.Second, +func newDefaultHTTPClient(enableTimeouts bool) *http.Client { + transport := &http.Transport{ + Dial: (&net.Dialer{ + Timeout: 2 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, } + c := &http.Client{ + Transport: transport, + } + if enableTimeouts { + transport.IdleConnTimeout = 60 * time.Second + c.Timeout = 5 * time.Second + } + return c } // NotDefinedError is returned when requested metadata is not defined. @@ -350,8 +356,12 @@ func strsContains(ss []string, s string) bool { // A Client provides metadata. type Client struct { - hc *http.Client - logger *slog.Logger + hc *http.Client + // subClient by default is a HTTP Client that is only used for subscribe + // methods that should not specify a timeout. If the user specifies a client + // this with be the same as 'hc'. + subClient *http.Client + logger *slog.Logger } // Options for configuring a [Client]. @@ -383,7 +393,7 @@ func NewClient(c *http.Client) *Client { return defaultClient } // Return a new client with a no-op logger for backward compatibility. - return &Client{hc: c, logger: slog.New(noOpHandler{})} + return &Client{hc: c, subClient: c, logger: slog.New(noOpHandler{})} } // NewWithOptions returns a Client that is configured with the provided Options. @@ -399,19 +409,21 @@ func NewWithOptions(opts *Options) *Client { if logger == nil { logger = slog.New(noOpHandler{}) } - return &Client{hc: defaultClient.hc, logger: logger} + return &Client{hc: defaultClient.hc, subClient: defaultClient.subClient, logger: logger} } // Handle isolated client creation. client := opts.Client + subClient := opts.Client if client == nil { - client = newDefaultHTTPClient() + client = newDefaultHTTPClient(true) + subClient = newDefaultHTTPClient(false) } logger := opts.Logger if logger == nil { logger = slog.New(noOpHandler{}) } - return &Client{hc: client, logger: logger} + return &Client{hc: client, subClient: subClient, logger: logger} } // NOTE: metadataRequestStrategy is assigned to a variable for test stubbing purposes. @@ -495,6 +507,10 @@ func (c *Client) OnGCEWithContext(ctx context.Context) bool { // getETag returns a value from the metadata service as well as the associated ETag. // This func is otherwise equivalent to Get. func (c *Client) getETag(ctx context.Context, suffix string) (value, etag string, err error) { + return c.getETagWithSubClient(ctx, suffix, false) +} + +func (c *Client) getETagWithSubClient(ctx context.Context, suffix string, enableSubClient bool) (value, etag string, err error) { // Using a fixed IP makes it very difficult to spoof the metadata service in // a container, which is an important use-case for local testing of cloud // deployments. To enable spoofing of the metadata service, the environment @@ -521,9 +537,13 @@ func (c *Client) getETag(ctx context.Context, suffix string) (value, etag string var reqErr error var body []byte retryer := newRetryer() + hc := c.hc + if enableSubClient { + hc = c.subClient + } for { c.logger.DebugContext(ctx, "metadata request", "request", httpRequest(req, nil)) - res, reqErr = c.hc.Do(req) + res, reqErr = hc.Do(req) var code int if res != nil { code = res.StatusCode @@ -869,7 +889,7 @@ func (c *Client) SubscribeWithContext(ctx context.Context, suffix string, fn fun const failedSubscribeSleep = time.Second * 5 // First check to see if the metadata value exists at all. - val, lastETag, err := c.getETag(ctx, suffix) + val, lastETag, err := c.getETagWithSubClient(ctx, suffix, true) if err != nil { return err } @@ -885,8 +905,11 @@ func (c *Client) SubscribeWithContext(ctx context.Context, suffix string, fn fun suffix += "?wait_for_change=true&last_etag=" } for { - val, etag, err := c.getETag(ctx, suffix+url.QueryEscape(lastETag)) + val, etag, err := c.getETagWithSubClient(ctx, suffix+url.QueryEscape(lastETag), true) if err != nil { + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return err + } if _, deleted := err.(NotDefinedError); !deleted { time.Sleep(failedSubscribeSleep) continue // Retry on other errors. diff --git a/vendor/cloud.google.com/go/compute/metadata/retry.go b/vendor/cloud.google.com/go/compute/metadata/retry.go index 3d4bc75ddf..d516f30f80 100644 --- a/vendor/cloud.google.com/go/compute/metadata/retry.go +++ b/vendor/cloud.google.com/go/compute/metadata/retry.go @@ -95,6 +95,9 @@ func shouldRetry(status int, err error) bool { if 500 <= status && status <= 599 { return true } + if status == http.StatusTooManyRequests { + return true + } if err == io.ErrUnexpectedEOF { return true } diff --git a/vendor/cuelabs.dev/go/oci/ociregistry/internal/ocirequest/create.go b/vendor/cuelabs.dev/go/oci/ociregistry/internal/ocirequest/create.go index 3a1e9b4dd1..0bcda25119 100644 --- a/vendor/cuelabs.dev/go/oci/ociregistry/internal/ocirequest/create.go +++ b/vendor/cuelabs.dev/go/oci/ociregistry/internal/ocirequest/create.go @@ -40,7 +40,7 @@ func (req *Request) MustConstruct() (method string, ustr string) { return method, ustr } -func (req *Request) construct() (method string, url string) { +func (req *Request) construct() (method string, urlStr string) { switch req.Kind { case ReqPing: return "GET", "/v2/" @@ -77,7 +77,11 @@ func (req *Request) construct() (method string, url string) { case ReqTagsList: return "GET", "/v2/" + req.Repo + "/tags/list" + req.listParams() case ReqReferrersList: - return "GET", "/v2/" + req.Repo + "/referrers/" + req.Digest + p := "/v2/" + req.Repo + "/referrers/" + req.Digest + if req.ArtifactType != "" { + p += "?" + url.Values{"artifactType": {req.ArtifactType}}.Encode() + } + return "GET", p case ReqCatalogList: return "GET", "/v2/_catalog" + req.listParams() default: diff --git a/vendor/cuelabs.dev/go/oci/ociregistry/internal/ocirequest/request.go b/vendor/cuelabs.dev/go/oci/ociregistry/internal/ocirequest/request.go index 99b281574b..05a8f2e6b8 100644 --- a/vendor/cuelabs.dev/go/oci/ociregistry/internal/ocirequest/request.go +++ b/vendor/cuelabs.dev/go/oci/ociregistry/internal/ocirequest/request.go @@ -16,8 +16,8 @@ package ocirequest import ( "encoding/base64" - "errors" "fmt" + "net/http" "net/url" "strconv" "strings" @@ -27,27 +27,20 @@ import ( "cuelabs.dev/go/oci/ociregistry/ociref" ) -// ParseError represents an error that can happen when parsing. -// The Err field holds one of the possible error values below. -type ParseError struct { - Err error -} +var ( + errBadlyFormedDigest = ociregistry.NewError("badly formed digest", ociregistry.ErrDigestInvalid.Code(), nil) + errMethodNotAllowed = httpErrorf(http.StatusMethodNotAllowed, "method not allowed") + errNotFound = httpErrorf(http.StatusNotFound, "page not found") +) -func (e *ParseError) Error() string { - return e.Err.Error() +func badRequestf(f string, a ...any) error { + return httpErrorf(http.StatusBadRequest, f, a...) } -func (e *ParseError) Unwrap() error { - return e.Err +func httpErrorf(statusCode int, f string, a ...any) error { + return ociregistry.NewHTTPError(fmt.Errorf(f, a...), statusCode, nil, nil) } -var ( - ErrNotFound = errors.New("page not found") - ErrBadlyFormedDigest = errors.New("badly formed digest") - ErrMethodNotAllowed = errors.New("method not allowed") - ErrBadRequest = errors.New("bad request") -) - type Request struct { Kind Kind @@ -98,17 +91,22 @@ type Request struct { // Valid for: // ReqTagsList // ReqCatalog - // ReqReferrers ListN int - // listLast holds the item to start just after + // ListLast holds the item to start just after // when listing. // // Valid for: // ReqTagsList // ReqCatalog - // ReqReferrers ListLast string + + // ArtifactType holds the artifact type to filter by when + // listing. + // + // Valid for: + // ReqReferrersList + ArtifactType string } type Kind int @@ -185,22 +183,14 @@ const ( // Parse parses the given HTTP method and URL as an OCI registry request. // It understands the endpoints described in the [distribution spec]. // -// If it returns an error, it will be of type *ParseError. +// If it returns an error, it will be of type [ociregistry.Error] or [ociregistry.HTTPError]. // // [distribution spec]: https://github.com/opencontainers/distribution-spec/blob/main/spec.md#endpoints func Parse(method string, u *url.URL) (*Request, error) { - req, err := parse(method, u) - if err != nil { - return nil, &ParseError{err} - } - return req, nil -} - -func parse(method string, u *url.URL) (*Request, error) { path := u.Path urlq, err := url.ParseQuery(u.RawQuery) if err != nil { - return nil, err + return nil, badRequestf("invalid query parameters: %v", err) } var rreq Request @@ -214,7 +204,7 @@ func parse(method string, u *url.URL) (*Request, error) { } if path == "_catalog" { if method != "GET" { - return nil, ErrMethodNotAllowed + return nil, errMethodNotAllowed } rreq.Kind = ReqCatalogList setListQueryParams(&rreq, urlq) @@ -230,7 +220,7 @@ func parse(method string, u *url.URL) (*Request, error) { return nil, ociregistry.ErrNameInvalid } if method != "POST" { - return nil, ErrMethodNotAllowed + return nil, errMethodNotAllowed } if d := urlq.Get("mount"); d != "" { // end-11 @@ -257,7 +247,7 @@ func parse(method string, u *url.URL) (*Request, error) { // end-4b rreq.Digest = d if !ociref.IsValidDigest(d) { - return nil, ErrBadlyFormedDigest + return nil, errBadlyFormedDigest } rreq.Kind = ReqBlobUploadBlob return &rreq, nil @@ -268,17 +258,17 @@ func parse(method string, u *url.URL) (*Request, error) { } path, last, ok := cutLast(path, "/") if !ok { - return nil, ErrNotFound + return nil, errNotFound } path, lastButOne, ok := cutLast(path, "/") if !ok { - return nil, ErrNotFound + return nil, errNotFound } switch lastButOne { case "blobs": rreq.Repo = path if !ociref.IsValidDigest(last) { - return nil, ErrBadlyFormedDigest + return nil, errBadlyFormedDigest } if !ociref.IsValidRepository(rreq.Repo) { return nil, ociregistry.ErrNameInvalid @@ -292,7 +282,7 @@ func parse(method string, u *url.URL) (*Request, error) { case "DELETE": rreq.Kind = ReqBlobDelete default: - return nil, ErrMethodNotAllowed + return nil, errMethodNotAllowed } return &rreq, nil case "uploads": @@ -300,7 +290,7 @@ func parse(method string, u *url.URL) (*Request, error) { // isn't part of the OCI registry spec. repo, ok := strings.CutSuffix(path, "/blobs") if !ok { - return nil, ErrNotFound + return nil, errNotFound } rreq.Repo = repo if !ociref.IsValidRepository(rreq.Repo) { @@ -308,14 +298,14 @@ func parse(method string, u *url.URL) (*Request, error) { } uploadID64 := last if uploadID64 == "" { - return nil, ErrNotFound + return nil, errNotFound } uploadID, err := base64.RawURLEncoding.DecodeString(uploadID64) if err != nil { - return nil, fmt.Errorf("invalid upload ID %q (cannot decode)", uploadID64) + return nil, badRequestf("invalid upload ID %q (cannot decode)", uploadID64) } if !utf8.Valid(uploadID) { - return nil, fmt.Errorf("upload ID %q decoded to invalid utf8", uploadID64) + return nil, badRequestf("upload ID %q decoded to invalid utf8", uploadID64) } rreq.UploadID = string(uploadID) @@ -328,10 +318,10 @@ func parse(method string, u *url.URL) (*Request, error) { rreq.Kind = ReqBlobCompleteUpload rreq.Digest = urlq.Get("digest") if !ociref.IsValidDigest(rreq.Digest) { - return nil, ErrBadlyFormedDigest + return nil, errBadlyFormedDigest } default: - return nil, ErrMethodNotAllowed + return nil, errMethodNotAllowed } return &rreq, nil case "manifests": @@ -345,7 +335,7 @@ func parse(method string, u *url.URL) (*Request, error) { case ociref.IsValidTag(last): rreq.Tag = last default: - return nil, ErrNotFound + return nil, errNotFound } switch method { case "GET": @@ -357,19 +347,19 @@ func parse(method string, u *url.URL) (*Request, error) { case "DELETE": rreq.Kind = ReqManifestDelete default: - return nil, ErrMethodNotAllowed + return nil, errMethodNotAllowed } return &rreq, nil case "tags": if last != "list" { - return nil, ErrNotFound + return nil, errNotFound } if err := setListQueryParams(&rreq, urlq); err != nil { return nil, err } if method != "GET" { - return nil, ErrMethodNotAllowed + return nil, errMethodNotAllowed } rreq.Repo = path if !ociref.IsValidRepository(rreq.Repo) { @@ -379,23 +369,24 @@ func parse(method string, u *url.URL) (*Request, error) { return &rreq, nil case "referrers": if !ociref.IsValidDigest(last) { - return nil, ErrBadlyFormedDigest + return nil, errBadlyFormedDigest } if method != "GET" { - return nil, ErrMethodNotAllowed + return nil, errMethodNotAllowed } rreq.Repo = path if !ociref.IsValidRepository(rreq.Repo) { return nil, ociregistry.ErrNameInvalid } - // TODO is there any kind of pagination for referrers? - // We'll set ListN to be future-proof. + // Unlike other list-oriented endpoints, there appears to be no defined way for the client + // to indicate the desired number of results, but set ListN anyway to be future-proof. rreq.ListN = -1 rreq.Digest = last + rreq.ArtifactType = urlq.Get("artifactType") rreq.Kind = ReqReferrersList return &rreq, nil } - return nil, ErrNotFound + return nil, errNotFound } func setListQueryParams(rreq *Request, urlq url.Values) error { @@ -403,7 +394,7 @@ func setListQueryParams(rreq *Request, urlq url.Values) error { if nstr := urlq.Get("n"); nstr != "" { n, err := strconv.Atoi(nstr) if err != nil { - return fmt.Errorf("n is not a valid integer: %w", ErrBadRequest) + return badRequestf("query parameter n is not a valid integer") } rreq.ListN = n } diff --git a/vendor/cuelabs.dev/go/oci/ociregistry/iter.go b/vendor/cuelabs.dev/go/oci/ociregistry/iter.go index a60d06a39b..fcc034dc97 100644 --- a/vendor/cuelabs.dev/go/oci/ociregistry/iter.go +++ b/vendor/cuelabs.dev/go/oci/ociregistry/iter.go @@ -14,7 +14,7 @@ package ociregistry -// TODO(go1.23) when we can depend on Go 1.23, this should be: +// TODO(go1.24) when we can depend on Go 1.24, this should be: // type Seq[T any] = iter.Seq2[T, error] // Seq defines the type of an iterator sequence returned from @@ -22,18 +22,15 @@ package ociregistry // error means that the item is the last in the sequence. type Seq[T any] func(yield func(T, error) bool) -func All[T any](it Seq[T]) (_ []T, _err error) { +func All[T any](it Seq[T]) ([]T, error) { xs := []T{} - // TODO(go1.23) for x, err := range it - it(func(x T, err error) bool { + for x, err := range it { if err != nil { - _err = err - return false + return nil, err } xs = append(xs, x) - return true - }) - return xs, _err + } + return xs, nil } func SliceSeq[T any](xs []T) Seq[T] { diff --git a/vendor/cuelabs.dev/go/oci/ociregistry/ociauth/challenge.go b/vendor/cuelabs.dev/go/oci/ociregistry/ociauth/challenge.go index 8ca1a3016b..d5a133e6d9 100644 --- a/vendor/cuelabs.dev/go/oci/ociregistry/ociauth/challenge.go +++ b/vendor/cuelabs.dev/go/oci/ociregistry/ociauth/challenge.go @@ -32,7 +32,7 @@ func init() { // token = 1* // qdtext = > - for c := 0; c < 256; c++ { + for c := range 256 { var t octetType isCtl := c <= 31 || c == 127 isChar := 0 <= c && c <= 127 diff --git a/vendor/cuelabs.dev/go/oci/ociregistry/ociclient/client.go b/vendor/cuelabs.dev/go/oci/ociregistry/ociclient/client.go index 5c3a39f2ed..3322a8a981 100644 --- a/vendor/cuelabs.dev/go/oci/ociregistry/ociclient/client.go +++ b/vendor/cuelabs.dev/go/oci/ociregistry/ociclient/client.go @@ -25,6 +25,7 @@ import ( "log" "net/http" "net/url" + "slices" "strconv" "strings" "sync/atomic" @@ -324,10 +325,8 @@ func (c *client) do(req *http.Request, okStatuses ...int) (*http.Response, error if len(okStatuses) == 0 && resp.StatusCode == http.StatusOK { return resp, nil } - for _, status := range okStatuses { - if resp.StatusCode == status { - return resp, nil - } + if slices.Contains(okStatuses, resp.StatusCode) { + return resp, nil } defer resp.Body.Close() if !isOKStatus(resp.StatusCode) { diff --git a/vendor/cuelabs.dev/go/oci/ociregistry/ociclient/lister.go b/vendor/cuelabs.dev/go/oci/ociregistry/ociclient/lister.go index b629712e2b..a804e93029 100644 --- a/vendor/cuelabs.dev/go/oci/ociregistry/ociclient/lister.go +++ b/vendor/cuelabs.dev/go/oci/ociregistry/ociclient/lister.go @@ -17,9 +17,11 @@ package ociclient import ( "context" "encoding/json" + "errors" "fmt" "io" "net/http" + "slices" "strings" ocispec "github.com/opencontainers/image-spec/specs-go/v1" @@ -29,11 +31,11 @@ import ( ) func (c *client) Repositories(ctx context.Context, startAfter string) ociregistry.Seq[string] { - return c.pager(ctx, &ocirequest.Request{ + return pager(ctx, c, &ocirequest.Request{ Kind: ocirequest.ReqCatalogList, ListN: c.listPageSize, ListLast: startAfter, - }, func(resp *http.Response) ([]string, error) { + }, true, func(resp *http.Response) ([]string, error) { data, err := io.ReadAll(resp.Body) if err != nil { return nil, err @@ -49,12 +51,12 @@ func (c *client) Repositories(ctx context.Context, startAfter string) ociregistr } func (c *client) Tags(ctx context.Context, repoName, startAfter string) ociregistry.Seq[string] { - return c.pager(ctx, &ocirequest.Request{ + return pager(ctx, c, &ocirequest.Request{ Kind: ocirequest.ReqTagsList, Repo: repoName, ListN: c.listPageSize, ListLast: startAfter, - }, func(resp *http.Response) ([]string, error) { + }, true, func(resp *http.Response) ([]string, error) { data, err := io.ReadAll(resp.Body) if err != nil { return nil, err @@ -71,54 +73,80 @@ func (c *client) Tags(ctx context.Context, repoName, startAfter string) ociregis } func (c *client) Referrers(ctx context.Context, repoName string, digest ociregistry.Digest, artifactType string) ociregistry.Seq[ociregistry.Descriptor] { - // TODO paging - resp, err := c.doRequest(ctx, &ocirequest.Request{ - Kind: ocirequest.ReqReferrersList, - Repo: repoName, - Digest: string(digest), - ListN: c.listPageSize, - }) - if err != nil { - return ociregistry.ErrorSeq[ociregistry.Descriptor](err) - } - - data, err := io.ReadAll(resp.Body) - resp.Body.Close() - if err != nil { - return ociregistry.ErrorSeq[ociregistry.Descriptor](err) - } - var referrersResponse ocispec.Index - if err := json.Unmarshal(data, &referrersResponse); err != nil { - return ociregistry.ErrorSeq[ociregistry.Descriptor](fmt.Errorf("cannot unmarshal referrers response: %v", err)) - } - return ociregistry.SliceSeq(referrersResponse.Manifests) + return pager(ctx, c, &ocirequest.Request{ + Kind: ocirequest.ReqReferrersList, + Repo: repoName, + Digest: string(digest), + ListN: c.listPageSize, + ArtifactType: artifactType, + }, false, func(resp *http.Response) ([]ociregistry.Descriptor, error) { + body := resp.Body + if resp.StatusCode == http.StatusNotFound { + body.Close() + body = nil + // Fall back to the referrers tag API. + // From https://github.com/opencontainers/distribution-spec/blob/main/spec.md#unavailable-referrers-api : + // A client querying the referrers API and receiving a + // 404 Not Found MUST fallback to using an image index + // pushed to a tag described by the referrers tag + // schema. + r, err := c.GetTag(ctx, repoName, referrersTag(digest)) + if err != nil { + if errors.Is(err, ociregistry.ErrManifestUnknown) { + return nil, nil + } + return nil, err + } + body = r + } + data, err := io.ReadAll(body) + body.Close() + if err != nil { + return nil, err + } + var referrersResponse ocispec.Index + if err := json.Unmarshal(data, &referrersResponse); err != nil { + return nil, fmt.Errorf("cannot unmarshal referrers response: %v", err) + } + if artifactType == "" || resp.Header.Get("OCI-Filters-Applied") == "artifactType" { + return referrersResponse.Manifests, nil + } + // The server hasn't filtered the responses, so we must. + // TODO is it OK to assume that the index contains correctly populated + // artifact type and attributes fields when we've fallen back to the referrer tags API? + // If not, we might have to retrieve all the individual manifests to check that info. + manifests := slices.DeleteFunc(referrersResponse.Manifests, func(desc ociregistry.Descriptor) bool { + return desc.ArtifactType != artifactType + }) + return manifests, nil + }, http.StatusOK, http.StatusNotFound) } // pager returns an iterator for a list entry point. It starts by sending the given // initial request and parses each response into its component items using // parseResponse. It tries to use the Link header in each response to continue -// the iteration, falling back to using the "last" query parameter. -func (c *client) pager(ctx context.Context, initialReq *ocirequest.Request, parseResponse func(*http.Response) ([]string, error)) ociregistry.Seq[string] { - return func(yield func(string, error) bool) { - // We assume that the same scope is applicable to all page requests. +// the iteration, falling back to using the "last" query parameter if +// canUseLast is true. +func pager[T any](ctx context.Context, c *client, initialReq *ocirequest.Request, canUseLast bool, parseResponse func(*http.Response) ([]T, error), okStatuses ...int) ociregistry.Seq[T] { + return func(yield func(T, error) bool) { + // We assume that the same auth scope is applicable to all page requests. req, err := newRequest(ctx, initialReq, nil) if err != nil { - yield("", err) + yield(*new(T), err) return } for { - resp, err := c.do(req) + resp, err := c.do(req, okStatuses...) if err != nil { - yield("", err) + yield(*new(T), err) return } items, err := parseResponse(resp) resp.Body.Close() if err != nil { - yield("", err) + yield(*new(T), err) return } - // TODO sanity check that items are in lexical order? for _, item := range items { if !yield(item, nil) { return @@ -131,28 +159,35 @@ func (c *client) pager(ctx context.Context, initialReq *ocirequest.Request, pars // is less than . return } - req, err = nextLink(ctx, resp, initialReq, items[len(items)-1]) + req, err = nextLink(ctx, resp, initialReq, canUseLast, items[len(items)-1]) if err != nil { - yield("", fmt.Errorf("invalid Link header in response: %v", err)) + yield(*new(T), fmt.Errorf("invalid Link header in response: %v", err)) + return + } + if req == nil { + // No link found; assume there are no more items. return } } } } -// nextLink tries to form a request that can be sent to obtain the next page +// nextLink ttries to form a request that can be sent to obtain the next page // in a set of list results. // The given response holds the response received from the previous // list request; initialReq holds the request that initiated the listing, // and last holds the final item returned in the previous response. -func nextLink(ctx context.Context, resp *http.Response, initialReq *ocirequest.Request, last string) (*http.Request, error) { +func nextLink[T any](ctx context.Context, resp *http.Response, initialReq *ocirequest.Request, canUseLast bool, last T) (*http.Request, error) { link0 := resp.Header.Get("Link") if link0 == "" { + if !canUseLast { + return nil, nil + } // This is beyond the first page and there was no Link // in the previous response (the standard doesn't mandate // one), so add a "last" parameter to the initial request. rreq := *initialReq - rreq.ListLast = last + rreq.ListLast = fmt.Sprint(last) req, err := newRequest(ctx, &rreq, nil) if err != nil { // Given that we could form the initial request, this should @@ -178,3 +213,38 @@ func nextLink(ctx context.Context, resp *http.Response, initialReq *ocirequest.R } return http.NewRequestWithContext(ctx, "GET", linkURL.String(), nil) } + +// referrersTag returns the referrers tag for the given digest, as described +// in https://github.com/opencontainers/distribution-spec/blob/main/spec.md#referrers-tag-schema +func referrersTag(digest ociregistry.Digest) string { + // It's hard to know what the spec means by "with any characters not allowed by tags replaced with -", + // because different characters are allowed in different contexts (for example, a dot character + // is allowed except when it's at the start. + // In practice, however, the set of characters is very limited, and the only + // disallowed character in common use is :, so just use a naive algorithm. + return truncateAndMap(digest.Algorithm().String(), 32) + "-" + truncateAndMap(digest.Encoded(), 64) +} + +func truncateAndMap(s string, n int) string { + // regexp: [a-zA-Z0-9_][a-zA-Z0-9._-]{0,127} + + s = strings.Map(func(r rune) rune { + switch { + case 'a' <= r && r <= 'z': + return r + case 'A' <= r && r <= 'Z': + return r + case '0' <= r && r <= '9': + return r + case r == '.' || r == '_' || r == '-': + return r + } + return '-' + }, s) + // Note: it's OK to use n as a byte index because the + // above Map has eliminated all non-ASCII characters. + if len(s) <= n { + return s + } + return s[:n] +} diff --git a/vendor/cuelang.org/go/cue/ast/ast.go b/vendor/cuelang.org/go/cue/ast/ast.go index b66749f5ab..6d9c9b9fd5 100644 --- a/vendor/cuelang.org/go/cue/ast/ast.go +++ b/vendor/cuelang.org/go/cue/ast/ast.go @@ -18,6 +18,7 @@ package ast import ( "fmt" + "iter" "strings" "cuelang.org/go/cue/literal" @@ -147,9 +148,6 @@ func (c *comments) Comments() []*CommentGroup { return *c.groups } -// // AddComment adds the given comments to the fields. -// // If line is true the comment is inserted at the preceding token. - func (c *comments) AddComment(cg *CommentGroup) { if cg == nil { return @@ -169,6 +167,13 @@ func (c *comments) AddComment(cg *CommentGroup) { func (c *comments) SetComments(cgs []*CommentGroup) { if c.groups == nil { + if cgs == nil { + // Replacing no comments with a nil slice is a no-op. + // Avoid allocating below. + // Note that we continue for other zero-length slices, + // as the caller may want to reuse memory. + return + } a := cgs c.groups = &a return @@ -250,10 +255,10 @@ func (g *CommentGroup) Text() string { } // Split on newlines. - cl := strings.Split(c, "\n") + cl := strings.SplitSeq(c, "\n") // Walk lines, stripping trailing white space and adding to list. - for _, l := range cl { + for l := range cl { lines = append(lines, stripTrailingWhitespace(l)) } } @@ -301,13 +306,18 @@ func (a *Attribute) Split() (key, body string) { // A Field represents a field declaration in a struct. type Field struct { - Label Label // must have at least one element. - Optional token.Pos // Deprecated + // TODO(mvdan): remove the deprecated fields below in early 2026. + + Label Label // must have at least one element. + Alias *PostfixAlias // optional postfix alias (nil if no alias) + // Deprecated: use [Field.Constraint] + Optional token.Pos Constraint token.Token // token.ILLEGAL, token.OPTION, or token.NOT // No TokenPos: Value must be an StructLit with one field. TokenPos token.Pos - Token token.Token // Deprecated: always token.COLON + // Deprecated: the value is always [token.COLON] + Token token.Token Value Expr // the value associated with this field. @@ -346,6 +356,35 @@ func (a *Alias) Pos() token.Pos { return a.Ident.Pos() } func (a *Alias) pos() *token.Pos { return a.Ident.pos() } func (a *Alias) End() token.Pos { return a.Expr.End() } +// A PostfixAlias represents the new postfix alias syntax using ~. +// It appears in field declarations after the label. +// +// Simple form: label~X where X captures the field reference +// Dual form: label~(K,V) where K captures the label name string and V captures the field reference +type PostfixAlias struct { + Tilde token.Pos // position of "~" + + // Dual form: ~(K,V) + Lparen token.Pos // position of "(" (invalid if simple form) + Label *Ident // K: label name capture (nil if simple form) + Comma token.Pos // position of "," (invalid if simple form) + Rparen token.Pos // position of ")" (invalid if simple form) + + // Both forms: the field reference (always non-nil) + Field *Ident // X or V: captures the field reference + + comments +} + +func (a *PostfixAlias) Pos() token.Pos { return a.Tilde } +func (a *PostfixAlias) pos() *token.Pos { return &a.Tilde } +func (a *PostfixAlias) End() token.Pos { + if a.Rparen.IsValid() { + return a.Rparen.Add(1) + } + return a.Field.End() +} + // A Comprehension node represents a comprehension declaration. type Comprehension struct { Clauses []Clause // There must be at least one clause. @@ -398,7 +437,7 @@ type Ident struct { Name string Scope Node // scope in which node was found or nil if referring directly - Node Node + Node Node // node referenced by this identifier, if any; see [cuelang.org/go/cue/ast/astutil.Resolve] comments label @@ -416,10 +455,22 @@ type BasicLit struct { label } -// TODO: introduce and use NewLabel and NewBytes and perhaps NewText (in the +// TODO: introduce and use NewBytes and perhaps NewText (in the // later case NewString would return a string or bytes type) to distinguish from // NewString. Consider how to pass indentation information. +// NewStringLabel creates a new string label with the given string, +// quoting it as a string literal only if necessary, +// as outlined in [StringLabelNeedsQuoting]. +// +// To create labels for definition or hidden fields, use [NewIdent]. +func NewStringLabel(name string) Label { + if StringLabelNeedsQuoting(name) { + return NewString(name) + } + return NewIdent(name) +} + // NewString creates a new BasicLit with a string value without position. // It quotes the given string. // Useful for ASTs generated by code other than the CUE parser. @@ -729,6 +780,16 @@ type BinaryExpr struct { expr } +// A PostfixExpr node represents an expression followed by a postfix operator. +type PostfixExpr struct { + X Expr // expression + Op token.Token // postfix operator // ... or ? + OpPos token.Pos // position of operator + + comments + expr +} + // NewBinExpr creates for list of expressions of length 2 or greater a chained // binary expression of the form (((x1 op x2) op x3) ...). For lists of length // 1 it returns the expression itself. It panics for empty lists. @@ -788,6 +849,8 @@ func (x *UnaryExpr) Pos() token.Pos { return x.OpPos } func (x *UnaryExpr) pos() *token.Pos { return &x.OpPos } func (x *BinaryExpr) Pos() token.Pos { return x.X.Pos() } func (x *BinaryExpr) pos() *token.Pos { return x.X.pos() } +func (x *PostfixExpr) Pos() token.Pos { return x.X.Pos() } +func (x *PostfixExpr) pos() *token.Pos { return x.X.pos() } func (x *BottomLit) Pos() token.Pos { return x.Bottom } func (x *BottomLit) pos() *token.Pos { return &x.Bottom } @@ -822,7 +885,15 @@ func (x *SliceExpr) End() token.Pos { return x.Rbrack.Add(1) } func (x *CallExpr) End() token.Pos { return x.Rparen.Add(1) } func (x *UnaryExpr) End() token.Pos { return x.X.End() } func (x *BinaryExpr) End() token.Pos { return x.Y.End() } -func (x *BottomLit) End() token.Pos { return x.Bottom.Add(1) } +func (x *PostfixExpr) End() token.Pos { + switch x.Op { + case token.ELLIPSIS: + return x.OpPos.Add(3) // len("...") + default: + return x.OpPos.Add(1) // most single-char operators + } +} +func (x *BottomLit) End() token.Pos { return x.Bottom.Add(1) } // ---------------------------------------------------------------------------- // Convenience functions for Idents @@ -870,10 +941,6 @@ func (s *ImportSpec) pos() *token.Pos { return s.Path.pos() } -// func (s *AliasSpec) Pos() token.Pos { return s.Name.Pos() } -// func (s *ValueSpec) Pos() token.Pos { return s.Names[0].Pos() } -// func (s *TypeSpec) Pos() token.Pos { return s.Name.Pos() } - func (s *ImportSpec) End() token.Pos { if s.EndPos != token.NoPos { return s.EndPos @@ -949,8 +1016,18 @@ type File struct { Filename string Decls []Decl // top-level declarations; or nil - Imports []*ImportSpec // imports in this file - Unresolved []*Ident // unresolved identifiers in this file + // Deprecated: use [File.ImportSpecs]. + // TODO(mvdan): remove in mid 2026. + Imports []*ImportSpec // imports in this file + + Unresolved []*Ident // unresolved identifiers in this file + + // TODO remove this field: it's here as a temporary + // entity so that tests can determine which version + // the file was parsed with. A better approach is probably to + // include the language version in the `token.File` so + // it's available in every Position. + LanguageVersion string // The language version as configured by [parser.ParseFile]. comments } @@ -975,16 +1052,43 @@ outer: return f.Decls[:p] } +// VisitImports iterates through the import declarations in the file. +// +// Deprecated: use [File.ImportDecls]. func (f *File) VisitImports(fn func(d *ImportDecl)) { - for _, d := range f.Decls { - switch x := d.(type) { - case *CommentGroup: - case *Package: - case *Attribute: - case *ImportDecl: - fn(x) - default: - return + for d := range f.ImportDecls() { + fn(d) + } +} + +// ImportDecls iterates through the import declarations in the file. +func (f *File) ImportDecls() iter.Seq[*ImportDecl] { + return func(yield func(d *ImportDecl) bool) { + for _, d := range f.Decls { + switch x := d.(type) { + case *CommentGroup: + case *Package: + case *Attribute: + case *ImportDecl: + if !yield(x) { + return + } + default: + return + } + } + } +} + +// ImportSpecs iterates through all the import specs from all the import decls in the file. +func (f *File) ImportSpecs() iter.Seq[*ImportSpec] { + return func(yield func(d *ImportSpec) bool) { + for d := range f.ImportDecls() { + for _, spec := range d.Specs { + if !yield(spec) { + return + } + } } } } diff --git a/vendor/cuelang.org/go/cue/ast/astutil/apply.go b/vendor/cuelang.org/go/cue/ast/astutil/apply.go index 1f71faf106..046df24803 100644 --- a/vendor/cuelang.org/go/cue/ast/astutil/apply.go +++ b/vendor/cuelang.org/go/cue/ast/astutil/apply.go @@ -71,6 +71,14 @@ type Cursor interface { // Unless n is wrapped by ApplyRecursively, Apply does not walk n. InsertBefore(n ast.Node) + // Modified reports whether the cursor has been modified. + // Use ClearEnclosingModified to reset the flag. + Modified() bool + + // ClearEnclosingModified resets the Modified flag of the cursor so that + // the processing of enclosing nodes do not observe the modification. + ClearEnclosingModified() + self() *cursor } @@ -98,6 +106,7 @@ type cursor struct { typ interface{} // the type of the node index int // position of any of the sub types. replaced bool + modified bool } func newCursor(parent Cursor, n ast.Node, typ interface{}) *cursor { @@ -118,10 +127,12 @@ func fileInfo(c Cursor) (info *info) { return nil } -func (c *cursor) self() *cursor { return c } -func (c *cursor) Parent() Cursor { return c.parent } -func (c *cursor) Index() int { return c.index } -func (c *cursor) Node() ast.Node { return c.node } +func (c *cursor) self() *cursor { return c } +func (c *cursor) Parent() Cursor { return c.parent } +func (c *cursor) Index() int { return c.index } +func (c *cursor) Node() ast.Node { return c.node } +func (c *cursor) Modified() bool { return c.modified } +func (c *cursor) ClearEnclosingModified() { c.modified = false } // Deprecated: use [ast.NewImport] as an [ast.Ident.Node], and then // [Sanitize]. @@ -131,7 +142,7 @@ func (c *cursor) Import(importPath string) *ast.Ident { return nil } - name := ImportPathName(importPath) + name := ast.ParseImportPath(importPath).Qualifier // TODO: come up with something much better. // For instance, hoist the uniquer form cue/export.go to @@ -158,6 +169,7 @@ func (c *cursor) Replace(n ast.Node) { if ast.Comments(n) != nil { CopyComments(n, c.node) } + c.modified = true if r, ok := n.(recursive); ok { n = r.Node } else { @@ -190,16 +202,34 @@ func (c *cursor) Delete() { panic("unsupported") } // Children are traversed in the order in which they appear in the // respective node's struct definition. func Apply(node ast.Node, before, after func(Cursor) bool) ast.Node { - apply(&applier{before: before, after: after}, nil, &node) + a := &applier{before: before, after: after} + apply(a, nil, &node) + + // Fix certain references. + if a.fieldValueMap != nil { + ast.Walk(node, func(n ast.Node) bool { + if x, ok := n.(*ast.Ident); ok { + if v, ok := a.fieldValueMap[x.Node]; ok { + x.Node = v + } + } + return true + }, nil) + } return node } -// A applyVisitor's before method is invoked for each node encountered by Walk. +// A applyVisitor's Before method is invoked for each node encountered by Walk. // If the result applyVisitor w is true, Walk visits each of the children // of node with the applyVisitor w, followed by a call of w.After. +// The Mapping method is used to record changes to values that affect +// Ident.Node and Ident.Scope fields. +// TODO: currently, Mapping is only used to record Field.Value changes. Track +// more changes in the future. type applyVisitor interface { Before(Cursor) applyVisitor After(Cursor) bool + Mapping(before, after ast.Node) } // Helper functions for common node lists. They may be empty. @@ -211,6 +241,7 @@ type declsCursor struct { } func (c *declsCursor) InsertAfter(n ast.Node) { + c.modified = true if r, ok := n.(recursive); ok { n = r.Node c.process = append(c.process, n.(ast.Decl)) @@ -219,6 +250,7 @@ func (c *declsCursor) InsertAfter(n ast.Node) { } func (c *declsCursor) InsertBefore(n ast.Node) { + c.modified = true if r, ok := n.(recursive); ok { n = r.Node c.process = append(c.process, n.(ast.Decl)) @@ -226,7 +258,10 @@ func (c *declsCursor) InsertBefore(n ast.Node) { c.decls = append(c.decls, n.(ast.Decl)) } -func (c *declsCursor) Delete() { c.delete = true } +func (c *declsCursor) Delete() { + c.modified = true + c.delete = true +} func applyDeclList(v applyVisitor, parent Cursor, list []ast.Decl) []ast.Decl { c := &declsCursor{ @@ -244,6 +279,10 @@ func applyDeclList(v applyVisitor, parent Cursor, list []ast.Decl) []ast.Decl { c.decls = append(c.decls, c.node.(ast.Decl)) } c.delete = false + if c.modified { + parent.self().modified = true + c.modified = false + } for i := 0; i < len(c.process); i++ { x := c.process[i] c.node = x @@ -282,6 +321,9 @@ func apply[N ast.Node](v applyVisitor, parent Cursor, nodePtr *N) { node := *nodePtr c := newCursor(parent, node, nodePtr) applyCursor(v, c) + if c.modified && parent != nil { + parent.self().modified = true + } if ast.Node(node) != c.node { *nodePtr = c.node.(N) } @@ -292,6 +334,10 @@ func applyList[N ast.Node](v applyVisitor, parent Cursor, list []N) { for i, node := range list { c.index = i c.node = node + if c.modified { + parent.self().modified = true + c.modified = false + } c.typ = &list[i] applyCursor(v, c) if ast.Node(node) != c.node { @@ -316,6 +362,8 @@ func applyCursor(v applyVisitor, c Cursor) { // parsing and printing? applyList(v, c, ast.Comments(node)) + var beforeValue ast.Node // Used for Field + // apply children // (the order of the cases matches the order // of the corresponding node types in go) @@ -331,7 +379,11 @@ func applyCursor(v applyVisitor, c Cursor) { // nothing to do case *ast.Field: + beforeValue = n.Value apply(v, c, &n.Label) + if n.Alias != nil { + apply(v, c, &n.Alias) + } if n.Value != nil { apply(v, c, &n.Value) } @@ -386,6 +438,9 @@ func applyCursor(v applyVisitor, c Cursor) { apply(v, c, &n.X) apply(v, c, &n.Y) + case *ast.PostfixExpr: + apply(v, c, &n.X) + // Declarations case *ast.ImportSpec: if n.Name != nil { @@ -410,6 +465,14 @@ func applyCursor(v applyVisitor, c Cursor) { apply(v, c, &n.Ident) apply(v, c, &n.Expr) + case *ast.PostfixAlias: + if n.Label != nil { + apply(v, c, &n.Label) + } + if n.Field != nil { + apply(v, c, &n.Field) + } + case *ast.Comprehension: applyList(v, c, n.Clauses) apply(v, c, &n.Value) @@ -436,6 +499,9 @@ func applyCursor(v applyVisitor, c Cursor) { } v.After(c) + if f, ok := node.(*ast.Field); ok && beforeValue != f.Value { + v.Mapping(beforeValue, f.Value) + } } type applier struct { @@ -444,6 +510,15 @@ type applier struct { commentStack []commentFrame current commentFrame + + fieldValueMap map[ast.Node]ast.Node +} + +func (f *applier) Mapping(before, after ast.Node) { + if f.fieldValueMap == nil { + f.fieldValueMap = make(map[ast.Node]ast.Node) + } + f.fieldValueMap[before] = after } type commentFrame struct { diff --git a/vendor/cuelang.org/go/cue/ast/astutil/resolve.go b/vendor/cuelang.org/go/cue/ast/astutil/resolve.go index 9f1d020ed3..a987e4fc54 100644 --- a/vendor/cuelang.org/go/cue/ast/astutil/resolve.go +++ b/vendor/cuelang.org/go/cue/ast/astutil/resolve.go @@ -57,13 +57,20 @@ type ErrFunc func(pos token.Pos, msg string, args ...interface{}) // Value // X in a: X=y Field Alias // Fields -// X in X: y File/Struct Expr (y) +// y in X: y File/Struct Expr (y) // X in X=x: y File/Struct Field // X in X=(x): y File/Struct Field // X in X="\(x)": y File/Struct Field // X in [X=x]: y Field Expr (x) // X in X=[x]: y Field Field // +// V in foo~(K,V): v File/Struct Field +// K in foo~(K,V): v Field Expr "foo" +// V in [x]~(K,V): y Field Field +// K in [x]~(K,V): y Field Expr (x) +// V in (x)~(K,V): y File/Struct Field +// K in (x)~(K,V): y Field Expr (x) +// // for k, v in ForClause Ident // let x = y LetClause Ident // @@ -72,20 +79,34 @@ type ErrFunc func(pos token.Pos, msg string, args ...interface{}) // Value Field Field // Pkg nil ImportSpec -// Resolve resolves all identifiers in a file. Unresolved identifiers are -// recorded in Unresolved. It will not overwrite already resolved values. +// Resolve resolves all identifiers in a file, populating [ast.Ident.Node] fields. +// Unresolved identifiers are recorded in [ast.File.Unresolved]. +// It will not overwrite already resolved identifiers. func Resolve(f *ast.File, errFn ErrFunc) { - walkVisitor(f, &scope{errFn: errFn, identFn: resolveIdent}) + stack := make([]*scope, 0, 8) + visitor := &scope{ + errFn: errFn, + identFn: resolveIdent, + scopeStack: &stack, + } + ast.Walk(f, visitor.Before, nil) } -// Resolve resolves all identifiers in an expression. +// ResolveExpr resolves all identifiers in an expression. // It will not overwrite already resolved values. func ResolveExpr(e ast.Expr, errFn ErrFunc) { f := &ast.File{} - walkVisitor(e, &scope{file: f, errFn: errFn, identFn: resolveIdent}) + stack := make([]*scope, 0, 8) + visitor := &scope{ + file: f, + errFn: errFn, + identFn: resolveIdent, + scopeStack: &stack, + } + ast.Walk(e, visitor.Before, nil) } -// A Scope maintains the set of named language entities declared +// A scope maintains the set of named language entities declared // in the scope and a link to the immediately surrounding (outer) // scope. type scope struct { @@ -98,24 +119,60 @@ type scope struct { identFn func(s *scope, n *ast.Ident) bool nameFn func(name string) errFn func(p token.Pos, msg string, args ...interface{}) + + // scopeStack is used to reuse scope allocations. + // The pointer is shared between the root scope and all its children. + scopeStack *[]*scope } type entry struct { - node ast.Node - link ast.Node // Alias, LetClause, or Field + node ast.Node + link ast.Node // Alias, LetClause, or Field + field *ast.Field // Used for LabelAliases } -func newScope(f *ast.File, outer *scope, node ast.Node, decls []ast.Decl) *scope { - const n = 4 // initial scope capacity - s := &scope{ - file: f, - outer: outer, - node: node, - index: make(map[string]entry, n), - identFn: outer.identFn, - nameFn: outer.nameFn, - errFn: outer.errFn, +func (s *scope) allocScope() *scope { + if n := len(*s.scopeStack); n > 0 { + scope := (*s.scopeStack)[n-1] + *s.scopeStack = (*s.scopeStack)[:n-1] + return scope + } + return &scope{ + index: make(map[string]entry, 4), + scopeStack: s.scopeStack, + } +} + +func (s *scope) freeScope() { + // Ensure no pointers remain, which can hold onto memory. + // We only reuse the index map capacity, and keep the scopeStack pointer. + *s = scope{index: s.index, scopeStack: s.scopeStack} + clear(s.index) + *s.scopeStack = append(*s.scopeStack, s) +} + +// freeScopesUntil frees all scopes from s up to (but not including) 'ancestor'. +func (s *scope) freeScopesUntil(ancestor *scope) { + for s != ancestor { + if s == nil { + panic("ancestor scope not found") + } + next := s.outer + s.freeScope() + s = next } +} + +func newScope(f *ast.File, outer *scope, node ast.Node, decls []ast.Decl) *scope { + s := outer.allocScope() + s.file = f + s.outer = outer + s.node = node + s.inField = false + s.identFn = outer.identFn + s.nameFn = outer.nameFn + s.errFn = outer.errFn + for _, d := range decls { switch x := d.(type) { case *ast.Field: @@ -124,11 +181,23 @@ func newScope(f *ast.File, outer *scope, node ast.Node, decls []ast.Decl) *scope if a, ok := x.Label.(*ast.Alias); ok { name := a.Ident.Name if _, ok := a.Expr.(*ast.ListLit); !ok { - s.insert(name, x, a) + s.insert(name, x, a, nil) + } + if x.Alias != nil { + // Error: cannot have both old-style label alias and postfix + // alias + s.errFn(x.Pos(), + "field has both label alias and postfix alias") + } + } + if _, isPattern := label.(*ast.ListLit); !isPattern { + if a := x.Alias; a != nil { + insertPostfixAliases(s, x, a.Label) } } - // default: + // TODO(perf): replace labelName with quick tests: this generates an + // error in many cases. name, isIdent, _ := ast.LabelName(label) if isIdent { v := x.Value @@ -136,22 +205,22 @@ func newScope(f *ast.File, outer *scope, node ast.Node, decls []ast.Decl) *scope if a, ok := v.(*ast.Alias); ok { v = a.Expr } - s.insert(name, v, x) + s.insert(name, v, x, nil) } case *ast.LetClause: name, isIdent, _ := ast.LabelName(x.Ident) if isIdent { - s.insert(name, x, x) + s.insert(name, x, x, nil) } case *ast.Alias: name, isIdent, _ := ast.LabelName(x.Ident) if isIdent { - s.insert(name, x, x) + s.insert(name, x, x, nil) } case *ast.ImportDecl: for _, spec := range x.Specs { info, _ := ParseImportSpec(spec) - s.insert(info.Ident, spec, spec) + s.insert(info.Ident, spec, spec, nil) } } } @@ -182,7 +251,7 @@ func (s *scope) mustBeUnique(n ast.Node) bool { return false } -func (s *scope) insert(name string, n, link ast.Node) { +func (s *scope) insert(name string, n, link ast.Node, f *ast.Field) { if name == "" { return } @@ -213,7 +282,7 @@ func (s *scope) insert(name string, n, link ast.Node) { // s.errFn(n.Pos(), "alias %q already declared in enclosing scope", name) } } - s.index[name] = entry{node: n, link: link} + s.index[name] = entry{node: n, link: link, field: f} } func (s *scope) resolveScope(name string, node ast.Node) (scope ast.Node, e entry, ok bool) { @@ -241,7 +310,12 @@ func (s *scope) lookup(name string) (p *scope, obj ast.Node, node entry) { if _, ok := n.node.(*ast.ImportSpec); ok { return s, nil, n } - return s, s.node, n + obj := s.node + if n.field != nil { + // Label alias case. + obj = n.field + } + return s, obj, n } // s, last = s.outer, s s = s.outer @@ -249,24 +323,64 @@ func (s *scope) lookup(name string) (p *scope, obj ast.Node, node entry) { return nil, nil, entry{} } -func (s *scope) After(n ast.Node) {} -func (s *scope) Before(n ast.Node) (w visitor) { +func insertPostfixAliases(s *scope, x *ast.Field, expr ast.Node) { + a := x.Alias + if a == nil { + return + } + hasField := a.Field != nil && a.Field.Name != "_" + + if a.Label == nil { + // Single form: ~X + if !hasField { + s.errFn(a.Pos(), + "single postfix alias %q field cannot be the blank identifier", a.Label.Name) + } else { + s.insert(a.Field.Name, x, a, nil) + } + return + } + + // Double form: ~(X,Y) + hasLabel := a.Label != nil && a.Label.Name != "_" + if !hasField && !hasLabel { + s.errFn(a.Pos(), + "both label and field in postfix alias cannot be the blank identifier") + return + } + if hasLabel { + s.insert(a.Label.Name, expr, a, x) + } + if hasField { + s.insert(a.Field.Name, x, a, nil) + } +} + +func (s *scope) Before(n ast.Node) bool { switch x := n.(type) { case *ast.File: - s := newScope(x, s, x, x.Decls) + s = newScope(x, s, x, x.Decls) + defer s.freeScope() // Support imports. for _, d := range x.Decls { - walkVisitor(d, s) + ast.Walk(d, s.Before, nil) } - return nil + return false case *ast.StructLit: - return newScope(s.file, s, x, x.Elts) + s = newScope(s.file, s, x, x.Elts) + defer s.freeScope() + for _, elt := range x.Elts { + ast.Walk(elt, s.Before, nil) + } + return false case *ast.Comprehension: + outer := s s = scopeClauses(s, x.Clauses) - walkVisitor(x.Value, s) - return nil + defer s.freeScopesUntil(outer) + ast.Walk(x.Value, s.Before, nil) + return false case *ast.Field: var n ast.Node = x.Label @@ -277,25 +391,32 @@ func (s *scope) Before(n ast.Node) (w visitor) { switch label := n.(type) { case *ast.ParenExpr: - walkVisitor(label, s) + ast.Walk(label, s.Before, nil) case *ast.Interpolation: - walkVisitor(label, s) + ast.Walk(label, s.Before, nil) case *ast.ListLit: if len(label.Elts) != 1 { break } s = newScope(s.file, s, x, nil) + defer s.freeScope() if alias != nil { if name, _, _ := ast.LabelName(alias.Ident); name != "" { - s.insert(name, x, alias) + s.insert(name, x, alias, nil) } } expr := label.Elts[0] if a, ok := expr.(*ast.Alias); ok { + if x.Alias != nil { + // Error: cannot have both old-style pattern alias and + // postfix alias + s.errFn(x.Pos(), + "pattern constraint has both label alias and postfix alias") + } expr = a.Expr // Add to current scope, instead of the value's, and allow @@ -304,7 +425,9 @@ func (s *scope) Before(n ast.Node) (w visitor) { // illegal name clashes, and it allows giving better error // messages. This puts the burden on clients of this library // to detect illegal usage, though. - s.insert(a.Ident.Name, a.Expr, a) + s.insert(a.Ident.Name, a.Expr, a, x) + } else { + insertPostfixAliases(s, x, expr) } ast.Walk(expr, nil, func(n ast.Node) { @@ -317,23 +440,25 @@ func (s *scope) Before(n ast.Node) (w visitor) { } } }) - walkVisitor(expr, s) + ast.Walk(expr, s.Before, nil) } if n := x.Value; n != nil { + // Handle value aliases. if alias, ok := x.Value.(*ast.Alias); ok { // TODO: this should move into Before once decl attributes // have been fully deprecated and embed attributes are introduced. s = newScope(s.file, s, x, nil) - s.insert(alias.Ident.Name, alias, x) + defer s.freeScope() + s.insert(alias.Ident.Name, alias, x, nil) n = alias.Expr } s.inField = true - walkVisitor(n, s) + ast.Walk(n, s.Before, nil) s.inField = false } - return nil + return false case *ast.LetClause: // Disallow referring to the current LHS name. @@ -341,11 +466,9 @@ func (s *scope) Before(n ast.Node) (w visitor) { saved := s.index[name] delete(s.index, name) // The same name may still appear in another scope - if x.Expr != nil { - walkVisitor(x.Expr, s) - } + ast.Walk(x.Expr, s.Before, nil) s.index[name] = saved - return nil + return false case *ast.Alias: // Disallow referring to the current LHS name. @@ -353,29 +476,27 @@ func (s *scope) Before(n ast.Node) (w visitor) { saved := s.index[name] delete(s.index, name) // The same name may still appear in another scope - if x.Expr != nil { - walkVisitor(x.Expr, s) - } + ast.Walk(x.Expr, s.Before, nil) s.index[name] = saved - return nil + return false case *ast.ImportSpec: - return nil + return false case *ast.Attribute: // TODO: tokenize attributes, resolve identifiers and store the ones // that resolve in a list. case *ast.SelectorExpr: - walkVisitor(x.X, s) - return nil + ast.Walk(x.X, s.Before, nil) + return false case *ast.Ident: if s.identFn(s, x) { - return nil + return false } } - return s + return true } func resolveIdent(s *scope, x *ast.Ident) bool { @@ -410,20 +531,20 @@ func scopeClauses(s *scope, clauses []ast.Clause) *scope { for _, c := range clauses { switch x := c.(type) { case *ast.ForClause: - walkVisitor(x.Source, s) + ast.Walk(x.Source, s.Before, nil) s = newScope(s.file, s, x, nil) if x.Key != nil { - s.insert(x.Key.Name, x.Key, x) + s.insert(x.Key.Name, x.Key, x, nil) } - s.insert(x.Value.Name, x.Value, x) + s.insert(x.Value.Name, x.Value, x, nil) case *ast.LetClause: - walkVisitor(x.Expr, s) + ast.Walk(x.Expr, s.Before, nil) s = newScope(s.file, s, x, nil) - s.insert(x.Ident.Name, x.Ident, x) + s.insert(x.Ident.Name, x.Ident, x, nil) default: - walkVisitor(c, s) + ast.Walk(c, s.Before, nil) } } return s diff --git a/vendor/cuelang.org/go/cue/ast/astutil/sanitize.go b/vendor/cuelang.org/go/cue/ast/astutil/sanitize.go index 98f9fc8209..48b5a00d89 100644 --- a/vendor/cuelang.org/go/cue/ast/astutil/sanitize.go +++ b/vendor/cuelang.org/go/cue/ast/astutil/sanitize.go @@ -16,7 +16,7 @@ package astutil import ( "fmt" - "math/rand" + "math/rand/v2" "strings" "cuelang.org/go/cue/ast" @@ -41,7 +41,7 @@ import ( func Sanitize(f *ast.File) error { z := &sanitizer{ file: f, - rand: rand.New(rand.NewSource(808)), + rand: rand.New(rand.NewPCG(123, 456)), // ensure determinism between runs names: map[string]bool{}, importMap: map[string]*ast.ImportSpec{}, @@ -50,24 +50,29 @@ func Sanitize(f *ast.File) error { } // Gather all names. - walkVisitor(f, &scope{ - errFn: z.errf, - nameFn: z.addName, - identFn: z.markUsed, - }) + stack := make([]*scope, 0, 8) + s := &scope{ + errFn: z.errf, + nameFn: z.addName, + identFn: z.markUsed, + scopeStack: &stack, + } + ast.Walk(f, s.Before, nil) if z.errs != nil { return z.errs } // Add imports and unshadow. - s := &scope{ - file: f, - errFn: z.errf, - identFn: z.handleIdent, - index: make(map[string]entry), + stack = stack[:0] + s = &scope{ + file: f, + errFn: z.errf, + identFn: z.handleIdent, + index: make(map[string]entry), + scopeStack: &stack, } z.fileScope = s - walkVisitor(f, s) + ast.Walk(f, s.Before, nil) if z.errs != nil { return z.errs } @@ -169,7 +174,7 @@ func (z *sanitizer) markUsed(s *scope, n *ast.Ident) bool { func (z *sanitizer) cleanImports() { var fileImports []*ast.ImportSpec - z.file.VisitImports(func(decl *ast.ImportDecl) { + for decl := range z.file.ImportDecls() { newLen := 0 for _, spec := range decl.Specs { if _, ok := z.referenced[spec]; ok { @@ -179,18 +184,15 @@ func (z *sanitizer) cleanImports() { } } decl.Specs = decl.Specs[:newLen] - }) + } z.file.Imports = fileImports // Ensure that the first import always starts a new section // so that if the file has a comment, it won't be associated with // the import comment rather than the file. - first := true - z.file.VisitImports(func(decl *ast.ImportDecl) { - if first { - ast.SetRelPos(decl, token.NewSection) - first = false - } - }) + for decl := range z.file.ImportDecls() { + ast.SetRelPos(decl, token.NewSection) + break + } } func (z *sanitizer) handleIdent(s *scope, n *ast.Ident) bool { @@ -211,7 +213,7 @@ func (z *sanitizer) handleIdent(s *scope, n *ast.Ident) bool { _ = z.addImport(spec) info, _ := ParseImportSpec(spec) - z.fileScope.insert(info.Ident, spec, spec) + z.fileScope.insert(info.Ident, spec, spec, nil) return true } @@ -241,7 +243,7 @@ func (z *sanitizer) handleIdent(s *scope, n *ast.Ident) bool { Path: x.Path, }) z.importMap[xi.ID] = spec - z.fileScope.insert(name, spec, spec) + z.fileScope.insert(name, spec, spec, nil) } info, _ := ParseImportSpec(spec) @@ -347,8 +349,8 @@ func (z *sanitizer) uniqueName(base string, hidden bool) string { const mask = 0xff_ffff_ffff_ffff // max bits; stay clear of int64 overflow const shift = 4 // rate of growth - for n := int64(0x10); ; n = int64(mask&((n< 0 { - name = name[p+1:] - } - return name + return ast.ParseImportPath(id).Qualifier } // ImportInfo describes the information contained in an ImportSpec. @@ -43,32 +42,30 @@ type ImportInfo struct { Ident string // identifier used to refer to the import PkgName string // name of the package ID string // full import path, including the name - Dir string // import path, excluding the name + + // Deprecated: use [ast.ParseImportPath](ID).Path instead. + Dir string // import path, excluding the name } // ParseImportSpec returns the name and full path of an ImportSpec. -func ParseImportSpec(spec *ast.ImportSpec) (info ImportInfo, err error) { +func ParseImportSpec(spec *ast.ImportSpec) (ImportInfo, error) { str, err := strconv.Unquote(spec.Path.Value) if err != nil { - return info, err + return ImportInfo{}, err } - - info.ID = str - - if p := strings.LastIndexByte(str, ':'); p > 0 { - info.Dir = str[:p] - info.PkgName = str[p+1:] - } else { - info.Dir = str - info.PkgName = path.Base(str) + ip := ast.ParseImportPath(str) + info := ImportInfo{ + ID: str, + Ident: ip.Qualifier, + PkgName: ip.Qualifier, + // Note: this still leave the major version suffix in place + // so this "directory" isn't likely to correspond to any + // actual directory if there's a version present. + Dir: ip.Unqualified().String(), } - if spec.Name != nil { info.Ident = spec.Name.Name - } else { - info.Ident = info.PkgName } - return info, nil } diff --git a/vendor/cuelang.org/go/cue/ast/astutil/walk.go b/vendor/cuelang.org/go/cue/ast/astutil/walk.go deleted file mode 100644 index 6175a98af2..0000000000 --- a/vendor/cuelang.org/go/cue/ast/astutil/walk.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2018 The CUE Authors -// -// 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. - -package astutil - -import "cuelang.org/go/cue/ast" - -// walkVisitor traverses an AST in depth-first order with a [visitor]. -// -// TODO(mvdan): refactor away the need for walkVisitor; -// Resolve and Sanitize should be able to use ast.Walk directly. -func walkVisitor(node ast.Node, v visitor) { - sv := &stackVisitor{stack: []visitor{v}} - ast.Walk(node, sv.Before, sv.After) -} - -// stackVisitor helps implement visitor support on top of ast.Walk. -type stackVisitor struct { - stack []visitor -} - -func (v *stackVisitor) Before(node ast.Node) bool { - current := v.stack[len(v.stack)-1] - next := current.Before(node) - if next == nil { - return false - } - v.stack = append(v.stack, next) - return true -} - -func (v *stackVisitor) After(node ast.Node) { - v.stack[len(v.stack)-1] = nil // set visitor to nil so it can be garbage collected - v.stack = v.stack[:len(v.stack)-1] -} - -// A visitor's before method is invoked for each node encountered by Walk. -// If the result visitor w is true, Walk visits each of the children -// of node with the visitor w, followed by a call of w.After. -type visitor interface { - Before(node ast.Node) (w visitor) - After(node ast.Node) -} diff --git a/vendor/cuelang.org/go/cue/ast/ident.go b/vendor/cuelang.org/go/cue/ast/ident.go index 8e84aef3f9..9827bee91f 100644 --- a/vendor/cuelang.org/go/cue/ast/ident.go +++ b/vendor/cuelang.org/go/cue/ast/ident.go @@ -40,16 +40,12 @@ func IsValidIdent(ident string) bool { return false } - consumed := false - if strings.HasPrefix(ident, "_") { - ident = ident[1:] - consumed = true - if len(ident) == 0 { - return true - } + ident, consumed := strings.CutPrefix(ident, "_") + if ident == "" { + return true // "_" is a valid identifier } - if strings.HasPrefix(ident, "#") { - ident = ident[1:] + ident, consumedHash := strings.CutPrefix(ident, "#") + if consumedHash { // Note: _#0 is not allowed by the spec, although _0 is. // TODO: set consumed to true here to allow #0. consumed = false @@ -70,6 +66,21 @@ func IsValidIdent(ident string) bool { return true } +// StringLabelNeedsQuoting reports whether the given string +// must be quoted via [literal.Label].Quote to represent itself +// as a string label, such as a regular field. +// +// Note that a negative result does not mean you can simply use +// [NewIdent](name) to create a valid label without affecting any references. +// In the general case, you should use [Ident.Node] to ensure each identifier references +// exactly what they mean to, or quote any string label which doesn't need to be referenced. +// +// The main use case of this API is for simple scenarios, such as a JSON decoder +// where the input is all data without any references. +func StringLabelNeedsQuoting(name string) bool { + return strings.HasPrefix(name, "#") || strings.HasPrefix(name, "_") || !IsValidIdent(name) +} + // LabelName reports the name of a label, whether it is an identifier // (it binds a value to a scope), and whether it is valid. // Keywords that are allowed in label positions are interpreted accordingly. diff --git a/vendor/cuelang.org/go/cue/ast/importpath.go b/vendor/cuelang.org/go/cue/ast/importpath.go new file mode 100644 index 0000000000..ddec0c78be --- /dev/null +++ b/vendor/cuelang.org/go/cue/ast/importpath.go @@ -0,0 +1,156 @@ +package ast + +import ( + "cmp" + "strings" +) + +// ParseImportPath returns the various components of an import path. +// It does not check the result for validity. +func ParseImportPath(p string) ImportPath { + var parts ImportPath + pathWithoutQualifier := p + if i := strings.LastIndexAny(p, "/:"); i >= 0 && p[i] == ':' { + // Historically, `:pkgname` has been an alias for `.:pkgname`, + // and some users started relying on that behavior in the CLI + // even though it was never documented in `cue help inputs`. + // Keep support for it around for now, but perhaps reconsider in the future. + pathWithoutQualifier = cmp.Or(p[:i], ".") + + parts.Qualifier = p[i+1:] + parts.ExplicitQualifier = true + } + parts.Path = pathWithoutQualifier + if path, version, ok := SplitPackageVersion(pathWithoutQualifier); ok { + parts.Version = version + parts.Path = path + } + if !parts.ExplicitQualifier { + parts.Qualifier = impliedQualifier(parts.Path) + } + return parts +} + +// ImportPath holds the various components of an import path. +type ImportPath struct { + // Path holds the base package/directory path, similar + // to that returned by [Version.BasePath]. + Path string + + // Version holds the version of the import + // or empty if not present. Note: in general this + // will contain a major version only, but there's no + // guarantee of that. + Version string + + // Qualifier holds the package qualifier within the path. + // This will be derived from the last component of Path + // if it wasn't explicitly present in the import path. + // This is not guaranteed to be a valid CUE identifier. + Qualifier string + + // ExplicitQualifier holds whether the qualifier will + // always be added regardless of whether it matches + // the final path element. + ExplicitQualifier bool +} + +// Canonical returns the canonical form of the import path. +// Specifically, it will only include the package qualifier +// if it's different from the last component of parts.Path. +// +// It also ensures that the Qualifier field is set when +// appropriate. +func (parts ImportPath) Canonical() ImportPath { + q := impliedQualifier(parts.Path) + if q == "" { + parts.ExplicitQualifier = parts.Qualifier != "" + return parts + } + if q == parts.Qualifier { + // The qualifier matches the implied qualifier, so ensure that + // it is not included in string representations. + parts.ExplicitQualifier = false + } else if parts.Qualifier == "" && !parts.ExplicitQualifier { + // There's an implied qualifier but none set; this + // could happen if someone has manually constructed the + // ImportPath instance (it should never happen otherwise), + // so be defensive and set the qualifier anyway. + parts.Qualifier = q + parts.ExplicitQualifier = false + } else { + // There's a qualifier set that does not match the implied + // qualifier. This must be explicit. + parts.ExplicitQualifier = true + } + return parts +} + +// Unqualified returns the import path without any package qualifier. +func (parts ImportPath) Unqualified() ImportPath { + parts.Qualifier = "" + parts.ExplicitQualifier = false + return parts +} + +func (parts ImportPath) String() string { + needQualifier := parts.ExplicitQualifier + if !needQualifier && parts.Qualifier != "" { + if impliedQualifier(parts.Path) != parts.Qualifier { + needQualifier = true + } + } + if parts.Version == "" && !needQualifier { + // Fast path. + return parts.Path + } + var buf strings.Builder + buf.WriteString(parts.Path) + if parts.Version != "" { + buf.WriteByte('@') + buf.WriteString(parts.Version) + } + if needQualifier { + buf.WriteByte(':') + buf.WriteString(parts.Qualifier) + } + return buf.String() +} + +// impliedQualifier returns the package qualifier implied +// from the last component of the (bare) package path. +func impliedQualifier(path string) string { + var q string + if i := strings.LastIndex(path, "/"); i >= 0 { + q = path[i+1:] + } else { + q = path + } + if !IsValidIdent(q) || strings.HasPrefix(q, "#") || q == "_" { + return "" + } + return q +} + +// SplitPackageVersion returns a prefix and version suffix such that +// prefix+"@"+version == path. +// +// SplitPackageVersion returns (path, "", false) when there is no `@` +// character splitting the path or if the version is empty. +// +// It does not check that the version is valid in any way other than +// checking that it is not empty. +// +// For example: +// +// SplitPackageVersion("foo.com/bar@v0.1") returns ("foo.com/bar", "v0.1", true). +// SplitPackageVersion("foo.com/bar@badvers") returns ("foo.com/bar", "badvers", true). +// SplitPackageVersion("foo.com/bar") returns ("foo.com/bar", "", false). +// SplitPackageVersion("foo.com/bar@") returns ("foo.com/bar@", "", false). +func SplitPackageVersion(path string) (prefix, version string, ok bool) { + prefix, vers, ok := strings.Cut(path, "@") + if vers == "" { + ok = false + } + return prefix, vers, ok +} diff --git a/vendor/cuelang.org/go/cue/ast/walk.go b/vendor/cuelang.org/go/cue/ast/walk.go index 53429f975d..073b8f12bd 100644 --- a/vendor/cuelang.org/go/cue/ast/walk.go +++ b/vendor/cuelang.org/go/cue/ast/walk.go @@ -53,6 +53,9 @@ func Walk(node Node, before func(Node) bool, after func(Node)) { case *Field: Walk(n.Label, before, after) + if n.Alias != nil { + Walk(n.Alias, before, after) + } if n.Value != nil { Walk(n.Value, before, after) } @@ -111,6 +114,9 @@ func Walk(node Node, before func(Node) bool, after func(Node)) { Walk(n.X, before, after) Walk(n.Y, before, after) + case *PostfixExpr: + Walk(n.X, before, after) + // Declarations case *ImportSpec: if n.Name != nil { @@ -135,6 +141,14 @@ func Walk(node Node, before func(Node) bool, after func(Node)) { Walk(n.Ident, before, after) Walk(n.Expr, before, after) + case *PostfixAlias: + if n.Label != nil { + Walk(n.Label, before, after) + } + if n.Field != nil { + Walk(n.Field, before, after) + } + case *Comprehension: walkList(n.Clauses, before, after) Walk(n.Value, before, after) diff --git a/vendor/cuelang.org/go/cue/build.go b/vendor/cuelang.org/go/cue/build.go index f8621ce8b2..2efc1e4e69 100644 --- a/vendor/cuelang.org/go/cue/build.go +++ b/vendor/cuelang.org/go/cue/build.go @@ -15,8 +15,6 @@ package cue import ( - "cuelang.org/go/cue/ast" - "cuelang.org/go/cue/ast/astutil" "cuelang.org/go/cue/build" "cuelang.org/go/cue/errors" "cuelang.org/go/internal/core/adt" @@ -65,59 +63,6 @@ func (r *hiddenRuntime) Compile(filename string, source interface{}) (*Instance, return r.complete(p, v) } -// CompileFile compiles the given source file into an Instance. The source may -// import builtin packages. Use Build to allow importing non-builtin packages. -// -// Deprecated: use [Context.BuildFile]. The use of [Instance] is being phased out. -func (r *hiddenRuntime) CompileFile(file *ast.File) (*Instance, error) { - v, p := r.runtime().CompileFile(nil, file) - return r.complete(p, v) -} - -// CompileExpr compiles the given source expression into an Instance. The source -// may import builtin packages. Use Build to allow importing non-builtin -// packages. -// -// Deprecated: use [Context.BuildExpr]. The use of [Instance] is being phased out. -func (r *hiddenRuntime) CompileExpr(expr ast.Expr) (*Instance, error) { - f, err := astutil.ToFile(expr) - if err != nil { - return nil, err - } - runtime := r.runtime() - v := (*Context)(runtime).BuildExpr(expr) - err = v.Err() - inst := &Instance{ - index: runtime, - root: v.v, - inst: &build.Instance{ - Files: []*ast.File{f}, - }, - Err: errors.Promote(err, ""), - Incomplete: err != nil, - } - return inst, err -} - -// Parse parses a CUE source value into a CUE Instance. The source code may be -// provided as a string, byte slice, or io.Reader. The name is used as the file -// name in position information. The source may import builtin packages. -// -// Deprecated: use [Context.CompileString] or [Context.CompileBytes]. -// The use of [Instance] is being phased out. -func (r *hiddenRuntime) Parse(name string, source interface{}) (*Instance, error) { - return r.Compile(name, source) -} - -// Build creates an Instance from the given build.Instance. A returned Instance -// may be incomplete, in which case its Err field is set. -// -// Deprecated: use [Context.BuildInstance]. The use of [Instance] is being phased out. -func (r *hiddenRuntime) Build(p *build.Instance) (*Instance, error) { - v, _ := r.runtime().Build(nil, p) - return r.complete(p, v) -} - // Deprecated: use [Context.BuildInstances]. The use of [Instance] is being phased out. func Build(instances []*build.Instance) []*Instance { if len(instances) == 0 { @@ -146,13 +91,3 @@ func (r *hiddenRuntime) BuildInstances(instances []*build.Instance) ([]*Instance // TODO: insert imports return loaded, errs } - -// FromExpr creates an instance from an expression. -// Any references must be resolved beforehand. -// -// Deprecated: use [Context.BuildExpr]. The use of [Instance] is being phased out. -func (r *hiddenRuntime) FromExpr(expr ast.Expr) (*Instance, error) { - return r.CompileFile(&ast.File{ - Decls: []ast.Decl{&ast.EmbedDecl{Expr: expr}}, - }) -} diff --git a/vendor/cuelang.org/go/cue/build/context.go b/vendor/cuelang.org/go/cue/build/context.go index c8eadbf294..240e6149b4 100644 --- a/vendor/cuelang.org/go/cue/build/context.go +++ b/vendor/cuelang.org/go/cue/build/context.go @@ -27,19 +27,21 @@ package build import ( "cuelang.org/go/cue/ast" + "cuelang.org/go/cue/parser" ) // A Context keeps track of state of building instances and caches work. type Context struct { loader LoadFunc - parseFunc func(str string, src interface{}) (*ast.File, error) + parseFunc func(str string, src interface{}, cfg parser.Config) (*ast.File, error) initialized bool imports map[string]*Instance } -// NewInstance creates an instance for this Context. +// NewInstance creates an instance for this Context. If the [LoadFunc] +// is nil, then the LoadFunc in the [Context] is used. func (c *Context) NewInstance(dir string, f LoadFunc) *Instance { if c == nil { c = &Context{} @@ -118,6 +120,9 @@ func Loader(f LoadFunc) Option { // to change the effective file contents or the behavior of the parser, // or to modify the syntax tree. For example, changing the backwards // compatibility. -func ParseFile(f func(filename string, src interface{}) (*ast.File, error)) Option { +// +// In general, the function should respect the parser configuration passed +// in, and modify it incrementally rather than overwriting it entirely. +func ParseFile(f func(filename string, src interface{}, cfg parser.Config) (*ast.File, error)) Option { return func(c *Context) { c.parseFunc = f } } diff --git a/vendor/cuelang.org/go/cue/build/file.go b/vendor/cuelang.org/go/cue/build/file.go index 945fe31e41..5e31ee088c 100644 --- a/vendor/cuelang.org/go/cue/build/file.go +++ b/vendor/cuelang.org/go/cue/build/file.go @@ -47,6 +47,7 @@ const ( JSON Encoding = "json" YAML Encoding = "yaml" TOML Encoding = "toml" + XML Encoding = "xml" JSONL Encoding = "jsonl" Text Encoding = "text" Binary Encoding = "binary" diff --git a/vendor/cuelang.org/go/cue/build/import.go b/vendor/cuelang.org/go/cue/build/import.go index 86d90a3cfa..2fe6a37909 100644 --- a/vendor/cuelang.org/go/cue/build/import.go +++ b/vendor/cuelang.org/go/cue/build/import.go @@ -15,6 +15,7 @@ package build import ( + "maps" "slices" "strconv" @@ -53,7 +54,7 @@ func (inst *Instance) complete() errors.Error { ) for _, f := range inst.Files { - for _, spec := range f.Imports { + for spec := range f.ImportSpecs() { quoted := spec.Path.Value path, err := strconv.Unquote(quoted) if err != nil { @@ -143,11 +144,7 @@ func (inst *Instance) complete() errors.Error { deps[path] = p1 } } - inst.Deps = make([]string, 0, len(deps)) - for dep := range deps { - inst.Deps = append(inst.Deps, dep) - } - slices.Sort(inst.Deps) + inst.Deps = slices.Sorted(maps.Keys(deps)) for _, dep := range inst.Deps { p1 := deps[dep] diff --git a/vendor/cuelang.org/go/cue/build/instance.go b/vendor/cuelang.org/go/cue/build/instance.go index 2c116c4fd0..af6395941c 100644 --- a/vendor/cuelang.org/go/cue/build/instance.go +++ b/vendor/cuelang.org/go/cue/build/instance.go @@ -26,6 +26,7 @@ import ( "cuelang.org/go/cue/errors" "cuelang.org/go/cue/parser" "cuelang.org/go/cue/token" + "cuelang.org/go/internal/mod/modfiledata" ) // An Instance describes the collection of files, and its imports, necessary @@ -80,6 +81,9 @@ type Instance struct { // imported by other packages, including those within the module. Module string + // ModuleFile holds the actual module file data, if available. + ModuleFile *modfiledata.File + // Root is the root of the directory hierarchy, it may be "" if this an // instance has no imports. // If Module != "", this corresponds to the module root. @@ -103,7 +107,10 @@ type Instance struct { Deps []string `api:"alpha"` DepsErrors []error `api:"alpha"` - Match []string `api:"alpha"` + // TODO: Match was declared for years but never set by any of the cue/build logic. + // If any user was trying to use it, we should implement it, + // but that seems unlikely given that it was always empty. + // Match []string `api:"alpha"` } // RelPath reports the path of f relative to the root of the instance's module @@ -178,10 +185,14 @@ func (inst *Instance) Context() *Context { } func (inst *Instance) parse(name string, src interface{}) (*ast.File, error) { + cfg := parser.NewConfig(parser.ParseComments) + if inst.ModuleFile != nil && inst.ModuleFile.Language != nil { + cfg = cfg.Apply(parser.Version(inst.ModuleFile.Language.Version)) + } if inst.ctxt != nil && inst.ctxt.parseFunc != nil { - return inst.ctxt.parseFunc(name, src) + return inst.ctxt.parseFunc(name, src, cfg) } - return parser.ParseFile(name, src, parser.ParseComments) + return parser.ParseFile(name, src, cfg) } // LookupImport defines a mapping from an ImportSpec's ImportPath to Instance. diff --git a/vendor/cuelang.org/go/cue/context.go b/vendor/cuelang.org/go/cue/context.go index 3c69e2802a..80a5f6adba 100644 --- a/vendor/cuelang.org/go/cue/context.go +++ b/vendor/cuelang.org/go/cue/context.go @@ -30,13 +30,17 @@ import ( "cuelang.org/go/internal/core/runtime" ) -// A Context is used for creating CUE [Value]s. +// A Context is used for creating CUE [Value] objects. // // A Context keeps track of loaded instances, indices of internal // representations of values, and defines the set of supported builtins. Any // operation that involves two Values should originate from the same Context. // // Use [cuelang.org/go/cue/cuecontext.New] to create a new context. +// +// Note that a context may grow in size as more values are created or loaded. +// If memory usage becomes a problem, consider avoiding long-lived contexts, +// such as using one context per task or periodically re-creating the context. type Context runtime.Runtime func (c *Context) runtime() *runtime.Runtime { @@ -369,18 +373,12 @@ func (c *Context) Encode(x interface{}, option ...EncodeOption) Value { ctx := c.ctx() // TODO: is true the right default? expr := convert.GoValueToValue(ctx, x, options.nilIsTop) - var n *adt.Vertex - if v, ok := expr.(*adt.Vertex); ok { - n = v - } else { - n = &adt.Vertex{} - n.AddConjunct(adt.MakeRootConjunct(nil, expr)) - } + n := exprToVertex(expr) n.Finalize(ctx) return c.make(n) } -// Encode converts a Go type to a CUE [Value]. +// EncodeType converts a Go type to a CUE [Value]. // // The returned value will represent an error, accessible through [Value.Err], // if any error occurred. @@ -395,13 +393,7 @@ func (c *Context) EncodeType(x interface{}, option ...EncodeOption) Value { if err != nil { return c.makeError(err) } - var n *adt.Vertex - if v, ok := expr.(*adt.Vertex); ok { - n = v - } else { - n = &adt.Vertex{} - n.AddConjunct(adt.MakeRootConjunct(nil, expr)) - } + n := exprToVertex(expr) n.Finalize(ctx) return c.make(n) } diff --git a/vendor/cuelang.org/go/cue/cuecontext/cuecontext.go b/vendor/cuelang.org/go/cue/cuecontext/cuecontext.go index 22a9879e37..a43f632209 100644 --- a/vendor/cuelang.org/go/cue/cuecontext/cuecontext.go +++ b/vendor/cuelang.org/go/cue/cuecontext/cuecontext.go @@ -18,6 +18,7 @@ import ( "fmt" "cuelang.org/go/cue" + "cuelang.org/go/cue/interpreter/embed" "cuelang.org/go/internal" "cuelang.org/go/internal/core/runtime" "cuelang.org/go/internal/cuedebug" @@ -40,6 +41,8 @@ type Option struct { // [cue help environment]: https://cuelang.org/docs/reference/command/cue-help-environment/ func New(options ...Option) *cue.Context { r := runtime.New() + // Embedding is always available. + r.SetInterpreter(embed.New()) for _, o := range options { o.apply(r) } @@ -61,21 +64,22 @@ func Interpreter(i ExternInterpreter) Option { type EvalVersion = internal.EvaluatorVersion const ( - // EvalDefault is the latest stable version of the evaluator. + // EvalDefault is the default version of the evaluator, which is selected based on + // the CUE_EXPERIMENT environment variable described in [cue help environment]. + // + // [cue help environment]: https://cuelang.org/docs/reference/command/cue-help-environment/ EvalDefault EvalVersion = internal.DefaultVersion - // EvalExperiment refers to the latest unstable version of the evaluator. - // Note that this version may change without notice. - EvalExperiment EvalVersion = internal.DevVersion + // EvalDefault is the latest stable version of the evaluator, currently [EvalV3]. + EvalStable EvalVersion = internal.StableVersion - // EvalV2 is the currently latest stable version of the evaluator. - // It was introduced in CUE version 0.3 and is being maintained until 2024. - EvalV2 EvalVersion = internal.EvalV2 + // EvalExperiment refers to the latest in-development version of the evaluator, + // currently [EvalV3]. Note that this version may change without notice. + EvalExperiment EvalVersion = internal.DevVersion - // EvalV3 is the currently experimental version of the evaluator. - // It was introduced in 2024 and brought a new disjunction algorithm, - // a new closedness algorithm, a new core scheduler, and adds performance - // enhancements like structure sharing. + // EvalV3 is the current version of the evaluator. It was introduced in 2024 + // and brought a new disjunction algorithm, a new closedness algorithm, a + // new core scheduler, and adds performance enhancements like structure sharing. EvalV3 EvalVersion = internal.EvalV3 ) diff --git a/vendor/cuelang.org/go/cue/decode.go b/vendor/cuelang.org/go/cue/decode.go index 713394d7f9..9e78a18009 100644 --- a/vendor/cuelang.org/go/cue/decode.go +++ b/vendor/cuelang.org/go/cue/decode.go @@ -19,7 +19,7 @@ import ( "cmp" "encoding" "encoding/json" - "math" + "math/big" "reflect" "slices" "strconv" @@ -30,7 +30,6 @@ import ( "cuelang.org/go/cue/errors" "cuelang.org/go/internal/core/adt" - "cuelang.org/go/internal/cueexperiment" ) // Decode initializes the value pointed to by x with Value v. @@ -102,7 +101,7 @@ func (d *decoder) decode(x reflect.Value, v Value, isPtr bool) { } switch x.Kind() { - case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Interface: + case reflect.Pointer, reflect.Map, reflect.Slice, reflect.Interface: // nullable types if v.IsNull() || !v.IsConcrete() { d.clear(x) @@ -127,6 +126,17 @@ func (d *decoder) decode(x reflect.Value, v Value, isPtr bool) { } if it != nil { + if _, ok := it.(*big.Float); ok { + f, err := v.Float(nil) + if err != nil { + err = errors.Wrapf(err, v.Pos(), "Decode") + d.addErr(err) + return + } + x.Elem().Set(reflect.ValueOf(*f)) + return + } + b, err := v.Bytes() if err != nil { err = errors.Wrapf(err, v.Pos(), "Decode") @@ -146,7 +156,7 @@ func (d *decoder) decode(x reflect.Value, v Value, isPtr bool) { } switch kind { - case reflect.Ptr: + case reflect.Pointer: d.decode(x.Elem(), v, true) case reflect.Bool: @@ -270,22 +280,15 @@ func (d *decoder) interfaceValue(v Value) (x interface{}) { case IntKind: if i, err := v.Int64(); err == nil { - cueexperiment.Init() - if cueexperiment.Flags.DecodeInt64 { - return i - } - // When the decodeint64 experiment is not enabled, we want to return the value - // as `int`, but that's not possible for large values on 32-bit architectures. - // To avoid overflows causing entirely wrong values to be returned to the user, - // let the logic continue below so that we return a *big.Int instead. - if i <= math.MaxInt && i >= math.MinInt { - return int(i) - } + return i } x, err = v.Int(nil) case FloatKind: - x, err = v.Float64() // or big int or + if f, err := v.Float64(); err == nil { + return f + } // or big int or + x, err = v.Float(nil) case StringKind: x, err = v.String() @@ -368,7 +371,7 @@ func (d *decoder) convertMap(x reflect.Value, v Value) { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: n, err := strconv.ParseInt(key, 10, 64) d.addErr(err) - if reflect.Zero(kt).OverflowInt(n) { + if kt.OverflowInt(n) { d.addErr(errors.Newf(v.Pos(), "key integer %d overflows %s", n, kt)) break } @@ -377,7 +380,7 @@ func (d *decoder) convertMap(x reflect.Value, v Value) { case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: n, err := strconv.ParseUint(key, 10, 64) d.addErr(err) - if reflect.Zero(kt).OverflowUint(n) { + if kt.OverflowUint(n) { d.addErr(errors.Newf(v.Pos(), "key integer %d overflows %s", n, kt)) break } @@ -433,7 +436,7 @@ func (d *decoder) convertStruct(x reflect.Value, v Value) { // Figure out field corresponding to key. subv := x for _, i := range f.index { - if subv.Kind() == reflect.Ptr { + if subv.Kind() == reflect.Pointer { if subv.IsNil() { // If a struct embeds a pointer to an unexported type, // it is not possible to set a newly allocated value @@ -537,12 +540,12 @@ func typeFields(t reflect.Type) structFields { visited[f.typ] = true // Scan f.typ for fields to include. - for i := 0; i < f.typ.NumField(); i++ { + for i := range f.typ.NumField() { sf := f.typ.Field(i) isUnexported := sf.PkgPath != "" if sf.Anonymous { t := sf.Type - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Pointer { t = t.Elem() } if isUnexported && t.Kind() != reflect.Struct { @@ -559,7 +562,7 @@ func typeFields(t reflect.Type) structFields { if tag == "-" { continue } - name, opts := parseTag(tag) + name, opts, _ := strings.Cut(tag, ",") if !isValidTag(name) { name = "" } @@ -568,7 +571,7 @@ func typeFields(t reflect.Type) structFields { index[len(f.index)] = i ft := sf.Type - if ft.Name() == "" && ft.Kind() == reflect.Ptr { + if ft.Name() == "" && ft.Kind() == reflect.Pointer { // Follow pointer. ft = ft.Elem() } @@ -584,7 +587,7 @@ func typeFields(t reflect.Type) structFields { tag: tagged, index: index, typ: ft, - omitEmpty: opts.Contains("omitempty"), + omitEmpty: tagOptions(opts).Contains("omitempty"), } field.nameBytes = []byte(field.name) field.equalFold = foldFunc(field.nameBytes) @@ -698,15 +701,6 @@ func cachedTypeFields(t reflect.Type) structFields { // tag, or the empty string. It does not include the leading comma. type tagOptions string -// parseTag splits a struct field's json tag into its name and -// comma-separated options. -func parseTag(tag string) (string, tagOptions) { - if idx := strings.Index(tag, ","); idx != -1 { - return tag[:idx], tagOptions(tag[idx+1:]) - } - return tag, tagOptions("") -} - // Contains reports whether a comma-separated list of options // contains a particular substr flag. substr must be surrounded by a // string boundary or commas. @@ -717,10 +711,7 @@ func (o tagOptions) Contains(optionName string) bool { s := string(o) for s != "" { var next string - i := strings.Index(s, ",") - if i >= 0 { - s, next = s[:i], s[i+1:] - } + s, next, _ = strings.Cut(s, ",") if s == optionName { return true } @@ -883,7 +874,7 @@ func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.Te // If v is a named type and is addressable, // start with its address, so that if the type has pointer methods, // we find them. - if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { + if v.Kind() != reflect.Pointer && v.Type().Name() != "" && v.CanAddr() { haveAddr = true v = v.Addr() } @@ -892,14 +883,14 @@ func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.Te // usefully addressable. if v.Kind() == reflect.Interface && !v.IsNil() { e := v.Elem() - if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) { + if e.Kind() == reflect.Pointer && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Pointer) { haveAddr = false v = e continue } } - if v.Kind() != reflect.Ptr { + if v.Kind() != reflect.Pointer { break } @@ -919,11 +910,11 @@ func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.Te } if v.Type().NumMethod() > 0 && v.CanInterface() { if u, ok := v.Interface().(json.Unmarshaler); ok { - return u, nil, reflect.Value{} + return u, nil, v } if !decodingNull { if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { - return nil, u, reflect.Value{} + return nil, u, v } } } diff --git a/vendor/cuelang.org/go/cue/errors/errors.go b/vendor/cuelang.org/go/cue/errors/errors.go index f1492f1021..de4557b5fd 100644 --- a/vendor/cuelang.org/go/cue/errors/errors.go +++ b/vendor/cuelang.org/go/cue/errors/errors.go @@ -29,6 +29,7 @@ import ( "strings" "cuelang.org/go/cue/token" + "cuelang.org/go/internal/core/format" ) // New is a convenience wrapper for [errors.New] in the core library. @@ -86,6 +87,8 @@ func NewMessagef(format string, args ...interface{}) Message { // NewMessage creates an error message for human consumption. // // Deprecated: Use [NewMessagef] instead. +// +//go:fix inline func NewMessage(format string, args []interface{}) Message { return NewMessagef(format, args...) } @@ -123,8 +126,8 @@ type Error interface { Msg() (format string, args []interface{}) } -// Positions returns all positions returned by an error, sorted -// by relevance when possible and with duplicates removed. +// Positions returns the printable positions returned by an error, +// sorted by relevance when possible and with duplicates removed. func Positions(err error) []token.Pos { e := Error(nil) if !errors.As(err, &e) { @@ -134,17 +137,21 @@ func Positions(err error) []token.Pos { a := make([]token.Pos, 0, 3) pos := e.Position() - if pos.IsValid() { + if pos.File() != nil { a = append(a, pos) } sortOffset := len(a) for _, p := range e.InputPositions() { - if p.IsValid() && p != pos { + if p.File() != nil && p != pos { a = append(a, p) } } + // TODO if the Error we found wraps another error that itself + // has positions, we won't return them here but perhaps we should? + + // TODO(mvdan): we can use [token.Pos.Compare] here and no tests break. slices.SortFunc(a[sortOffset:], comparePosWithNoPosFirst) return slices.Compact(a) } @@ -273,10 +280,10 @@ func Promote(err error, msg string) Error { var _ Error = &posError{} -// In an List, an error is represented by an *posError. -// The position Pos, if valid, points to the beginning of +// In a list, an error is represented by a *posError. +// The position pos, if valid, points to the beginning of // the offending token, and the error condition is described -// by Msg. +// by Message. type posError struct { pos token.Pos Message @@ -286,7 +293,11 @@ func (e *posError) Path() []string { return nil } func (e *posError) InputPositions() []token.Pos { return nil } func (e *posError) Position() token.Pos { return e.pos } -// Append combines two errors, flattening Lists as necessary. +// Append combines two errors, flattening lists as necessary. +// +// Note: this may mutate a if it is already a list, so +// must not be used if a might have been shared across multiple +// goroutines. func Append(a, b Error) Error { switch x := a.(type) { case nil: @@ -299,7 +310,7 @@ func Append(a, b Error) Error { } // Errors reports the individual errors associated with an error, which is -// the error itself if there is only one or, if the underlying type is List, +// the error itself if there is only one or, if the underlying type is list, // its individual elements. If the given error is not an Error, it will be // promoted to one. func Errors(err error) []Error { @@ -310,8 +321,11 @@ func Errors(err error) []Error { var errorErr Error switch { case As(err, &listErr): + // TODO if err itself wraps a list, then the wrapping + // error information will be lost here. return listErr case As(err, &errorErr): + // TODO similar error loss here. return []Error{errorErr} default: return []Error{Promote(err, "")} @@ -331,10 +345,8 @@ func appendToList(a list, err Error) list { } return a default: - for _, e := range a { - if e == err { - return a - } + if slices.Contains(a, err) { + return a } return append(a, err) } @@ -362,20 +374,6 @@ func (p list) As(target interface{}) bool { return false } -// AddNewf adds an Error with given position and error message to an List. -func (p *list) AddNewf(pos token.Pos, msg string, args ...interface{}) { - err := &posError{pos: pos, Message: Message{format: msg, args: args}} - *p = append(*p, err) -} - -// Add adds an Error with given position and error message to an List. -func (p *list) Add(err Error) { - *p = appendToList(*p, err) -} - -// Reset resets an List to no errors. -func (p *list) Reset() { *p = (*p)[:0] } - // Sanitize sorts multiple errors and removes duplicates on a best effort basis. // If err represents a single or no error, it returns the error as is. func Sanitize(err Error) Error { @@ -397,14 +395,13 @@ func (p list) sanitize() list { return p } a := slices.Clone(p) - a.RemoveMultiples() + a.removeMultiples() return a } -// Sort sorts an List. *posError entries are sorted by position, -// other errors are sorted by error message, and before any *posError -// entry. -func (p list) Sort() { +// sort sorts a list. *posError entries are sorted by position, +// other errors are sorted by error message, and before any *posError entry. +func (p list) sort() { slices.SortFunc(p, func(a, b Error) int { if c := comparePosWithNoPosFirst(a.Position(), b.Position()); c != 0 { return c @@ -413,23 +410,13 @@ func (p list) Sort() { return c } return cmp.Compare(a.Error(), b.Error()) - }) } -// RemoveMultiples sorts an List and removes all but the first error per line. -func (p *list) RemoveMultiples() { - p.Sort() - var last Error - i := 0 - for _, e := range *p { - if last == nil || !approximateEqual(last, e) { - last = e - (*p)[i] = e - i++ - } - } - (*p) = (*p)[0:i] +// removeMultiples sorts a list and removes all but the first error per line. +func (p *list) removeMultiples() { + p.sort() + *p = slices.CompactFunc(*p, approximateEqual) } func approximateEqual(a, b Error) bool { @@ -438,11 +425,17 @@ func approximateEqual(a, b Error) bool { if aPos == token.NoPos || bPos == token.NoPos { return a.Error() == b.Error() } - return comparePosWithNoPosFirst(aPos, bPos) == 0 && slices.Compare(a.Path(), b.Path()) == 0 + return aPos.Compare(bPos) == 0 && slices.Compare(a.Path(), b.Path()) == 0 } -// An List implements the error interface. +// A list implements the error interface by returning the +// string for the first error in the list. func (p list) Error() string { + // TODO in general Error.Msg does not include the message + // from errors that are wrapped (see [wrapped.Msg] which does + // not include any text from the wrapped error, so this implementation + // of Error means that we might lose information when + // just printing an error list with regular %v. format, args := p.Msg() return fmt.Sprintf(format, args...) } @@ -503,14 +496,22 @@ type Config struct { // ToSlash sets whether to use Unix paths. Mostly used for testing. ToSlash bool + + // OmitPath removes the path prefix from error messages. + OmitPath bool + + // Printer is used internally to detect printing cycles. + Printer format.Printer } +var zeroConfig = &Config{} + // Print is a utility function that prints a list of errors to w, -// one error per line, if the err parameter is an List. Otherwise +// one error per line, if the err parameter is a list. Otherwise // it prints the err string. func Print(w io.Writer, err error, cfg *Config) { if cfg == nil { - cfg = &Config{} + cfg = zeroConfig } for _, e := range list(Errors(err)).sanitize() { printError(w, e, cfg) @@ -528,20 +529,67 @@ func Details(err error, cfg *Config) string { // String generates a short message from a given Error. func String(err Error) string { var b strings.Builder - writeErr(&b, err) + writeErr(&b, err, zeroConfig) + return b.String() +} + +// StringWithConfig generates a short message from a given Error, using the +// provided configuration. +func StringWithConfig(err Error, cfg *Config) string { + var b strings.Builder + writeErr(&b, err, cfg) return b.String() } -func writeErr(w io.Writer, err Error) { - if path := strings.Join(err.Path(), "."); path != "" { - _, _ = io.WriteString(w, path) - _, _ = io.WriteString(w, ": ") +func writeErr(w io.Writer, err Error, cfg *Config) { + if !cfg.OmitPath { + if path := strings.Join(err.Path(), "."); path != "" { + _, _ = io.WriteString(w, path) + _, _ = io.WriteString(w, ": ") + } } for { u := errors.Unwrap(err) msg, args := err.Msg() + + // Just like [printError] does when printing one position per line, + // make sure that any position formatting arguments print as relative paths. + // + // Note that [Error.Msg] isn't clear about whether we should treat args as read-only, + // so we make a copy if we need to replace any arguments. + didCopy := false + for i, arg := range args { + var alt any + switch arg := arg.(type) { + case token.Pos: + pos := arg.Position() + pos.Filename = relPath(pos.Filename, cfg) + alt = pos + case token.Position: + pos := arg + pos.Filename = relPath(pos.Filename, cfg) + alt = pos + default: + if cfg.Printer == nil { + // We should always do something. Consider replacing + // vertices with a path if this is not set. + continue + } + var replaced bool + alt, replaced = cfg.Printer.ReplaceArg(arg) + if !replaced { + continue + } + } + if !didCopy { + args = slices.Clone(args) + didCopy = true + } + args[i] = alt + } + n, _ := fmt.Fprintf(w, msg, args...) if u == nil { @@ -573,7 +621,7 @@ func printError(w io.Writer, err error, cfg *Config) { } if e, ok := err.(Error); ok { - writeErr(w, e) + writeErr(w, e, cfg) } else { fprintf(w, "%v", err) } @@ -586,21 +634,7 @@ func printError(w io.Writer, err error, cfg *Config) { fprintf(w, ":\n") for _, p := range positions { pos := p.Position() - path := pos.Filename - if cfg.Cwd != "" { - if p, err := filepath.Rel(cfg.Cwd, path); err == nil { - path = p - // Some IDEs (e.g. VSCode) only recognize a path if it starts - // with a dot. This also helps to distinguish between local - // files and builtin packages. - if !strings.HasPrefix(path, ".") { - path = fmt.Sprintf(".%c%s", filepath.Separator, path) - } - } - } - if cfg.ToSlash { - path = filepath.ToSlash(path) - } + path := relPath(pos.Filename, cfg) fprintf(w, " %s", path) if pos.IsValid() { if path != "" { @@ -611,3 +645,21 @@ func printError(w io.Writer, err error, cfg *Config) { fprintf(w, "\n") } } + +func relPath(path string, cfg *Config) string { + if cfg.Cwd != "" { + if p, err := filepath.Rel(cfg.Cwd, path); err == nil { + path = p + // Some IDEs (e.g. VSCode) only recognize a path if it starts + // with a dot. This also helps to distinguish between local + // files and builtin packages. + if !strings.HasPrefix(path, ".") { + path = fmt.Sprintf(".%c%s", filepath.Separator, path) + } + } + } + if cfg.ToSlash { + path = filepath.ToSlash(path) + } + return path +} diff --git a/vendor/cuelang.org/go/cue/format/node.go b/vendor/cuelang.org/go/cue/format/node.go index 4d0e943b14..91503f74e1 100644 --- a/vendor/cuelang.org/go/cue/format/node.go +++ b/vendor/cuelang.org/go/cue/format/node.go @@ -16,6 +16,7 @@ package format import ( "fmt" + "slices" "strings" "cuelang.org/go/cue/ast" @@ -64,10 +65,6 @@ unsupported: return fmt.Errorf("cue/format: unsupported node type %T", node) } -func isRegularField(tok token.Token) bool { - return tok == token.ILLEGAL || tok == token.COLON -} - // Helper functions for common node lists. They may be empty. func nestDepth(f *ast.Field) int { @@ -127,7 +124,7 @@ func (f *formatter) walkDeclList(list []ast.Decl) { } } } - if f.printer.cfg.simplify && internal.IsEllipsis(x) { + if f.printer.cfg.simplify && isEllipsis(x) { ellipsis = x continue } @@ -166,6 +163,33 @@ func (f *formatter) walkDeclList(list []ast.Decl) { f.after(nil) } +// isEllipsis reports whether the declaration can be represented as an ellipsis. +func isEllipsis(x ast.Decl) bool { + // ... + if _, ok := x.(*ast.Ellipsis); ok { + return true + } + + // [string]: _ or [_]: _ + f, ok := x.(*ast.Field) + if !ok { + return false + } + v, ok := f.Value.(*ast.Ident) + if !ok || v.Name != "_" { + return false + } + l, ok := f.Label.(*ast.ListLit) + if !ok || len(l.Elts) != 1 { + return false + } + i, ok := l.Elts[0].(*ast.Ident) + if !ok { + return false + } + return i.Name == "string" || i.Name == "_" +} + func (f *formatter) walkSpecList(list []*ast.ImportSpec) { f.before(nil) for _, x := range list { @@ -205,7 +229,7 @@ func (f *formatter) walkListElems(list []ast.Expr) { splitComments := x.Pos().IsValid() if splitComments { for _, cg := range ast.Comments(x) { - if x.Pos().Before(cg.Pos()) { + if x.Pos().Compare(cg.Pos()) < 0 { commentsAfter = append(commentsAfter, cg) } } @@ -305,15 +329,32 @@ func (f *formatter) decl(decl ast.Decl) { switch n := decl.(type) { case *ast.Field: - constraint, _ := internal.ConstraintToken(n) - f.label(n.Label, constraint) + // Format label without constraint (we'll add constraint after alias) + f.label(n.Label, token.ILLEGAL) + + // Format postfix alias if present + if a := n.Alias; a != nil { + f.print(a.Tilde, token.TILDE, noblank) + if a.Label != nil { + // Dual form: ~(K,V) + // Assumes that ILLEGAL tokens are no-ops. + f.print(a.Lparen, token.LPAREN, noblank) + f.expr(a.Label) + f.print(a.Comma, token.COMMA, noblank) + f.expr(a.Field) + f.print(a.Rparen, token.RPAREN, noblank) + } else { + // Simple form: ~X + f.expr(a.Field) + } + } - regular := isRegularField(n.Token) - if regular { - f.print(noblank, nooverride, n.TokenPos, token.COLON) - } else { - f.print(blank, nooverride, n.Token) + // Format constraint marker (?, !) if present + if n.Constraint != token.ILLEGAL { + f.print(n.Constraint) } + + f.print(noblank, nooverride, n.TokenPos, token.COLON) f.visitComments(f.current.pos) if mem := f.inlineField(n); mem != nil { @@ -321,7 +362,7 @@ func (f *formatter) decl(decl ast.Decl) { default: fallthrough - case regular && f.cfg.simplify: + case f.cfg.simplify: f.print(blank, nooverride) f.decl(mem) @@ -466,6 +507,8 @@ func (f *formatter) nextNeedsFormfeed(n ast.Expr) bool { return f.nextNeedsFormfeed(x.X) case *ast.UnaryExpr: return f.nextNeedsFormfeed(x.X) + case *ast.PostfixExpr: + return f.nextNeedsFormfeed(x.X) case *ast.BinaryExpr: return f.nextNeedsFormfeed(x.X) || f.nextNeedsFormfeed(x.Y) case *ast.IndexExpr: @@ -473,10 +516,8 @@ func (f *formatter) nextNeedsFormfeed(n ast.Expr) bool { case *ast.SelectorExpr: return f.nextNeedsFormfeed(x.X) case *ast.CallExpr: - for _, arg := range x.Args { - if f.nextNeedsFormfeed(arg) { - return true - } + if slices.ContainsFunc(x.Args, f.nextNeedsFormfeed) { + return true } } return false @@ -506,7 +547,7 @@ func (f *formatter) label(l ast.Label, constraint token.Token) { // if the AST is not generated by the parser. name := n.Name if !ast.IsValidIdent(name) { - name = literal.Label.Quote(n.Name) + name = literal.Label.Quote(name) } f.print(n.NamePos, name) @@ -599,6 +640,10 @@ func (f *formatter) exprRaw(expr ast.Expr, prec1, depth int) { f.expr1(x.X, prec, depth) } + case *ast.PostfixExpr: + f.expr1(x.X, token.HighestPrec, depth) + f.print(x.Op) + case *ast.BasicLit: f.print(x.ValuePos, x) diff --git a/vendor/cuelang.org/go/cue/format/simplify.go b/vendor/cuelang.org/go/cue/format/simplify.go index d36c58e700..83b2aaf452 100644 --- a/vendor/cuelang.org/go/cue/format/simplify.go +++ b/vendor/cuelang.org/go/cue/format/simplify.go @@ -19,7 +19,6 @@ import ( "cuelang.org/go/cue/ast" "cuelang.org/go/cue/ast/astutil" - "cuelang.org/go/internal" ) // labelSimplifier rewrites string labels to identifiers if @@ -89,7 +88,7 @@ func (s *labelSimplifier) markStrings(n ast.Node) bool { switch x := n.(type) { case *ast.BasicLit: str, err := strconv.Unquote(x.Value) - if err != nil || !ast.IsValidIdent(str) || internal.IsDefOrHidden(str) { + if err != nil || ast.StringLabelNeedsQuoting(str) { return false } s.scope[str] = true @@ -107,7 +106,7 @@ func (s *labelSimplifier) replace(c astutil.Cursor) bool { switch x := c.Node().(type) { case *ast.BasicLit: str, err := strconv.Unquote(x.Value) - if err == nil && s.scope[str] && !internal.IsDefOrHidden(str) { + if err == nil && s.scope[str] { c.Replace(ast.NewIdent(str)) } } diff --git a/vendor/cuelang.org/go/cue/instance.go b/vendor/cuelang.org/go/cue/instance.go index 13d54ddb92..8cb45489dd 100644 --- a/vendor/cuelang.org/go/cue/instance.go +++ b/vendor/cuelang.org/go/cue/instance.go @@ -199,9 +199,7 @@ func (inst *hiddenInstance) Eval(expr ast.Expr) Value { return v.Context().BuildExpr(expr, Scope(v), InferBuiltins(true)) } -// DO NOT USE. -// -// Deprecated: do not use. +// Deprecated: do not use; use unification instead. func Merge(inst ...*Instance) *Instance { v := &adt.Vertex{} diff --git a/vendor/cuelang.org/go/cue/interpreter/embed/embed.go b/vendor/cuelang.org/go/cue/interpreter/embed/embed.go new file mode 100644 index 0000000000..74f5bb4d00 --- /dev/null +++ b/vendor/cuelang.org/go/cue/interpreter/embed/embed.go @@ -0,0 +1,414 @@ +// Copyright 2024 CUE Authors +// +// 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. + +// Package embed provides capabilities to CUE to embed any file that resides +// within a CUE module into CUE either verbatim or decoded. +// +// This package is EXPERIMENTAL and subject to change. +// +// # Overview +// +// To enable file embedding, a file must include the file-level @extern(embed) +// attribute. This allows a quick glance to see if a file embeds any files at +// all. This allows the @embed attribute to be used to load a file within a CUE +// module into a field. +// +// References to files are always relative to directory in which the referring +// file resides. Only files that exist within the CUE module are accessible. +// +// # The @embed attribute +// +// There are two main ways to embed files which are distinguished by the file +// and glob arguments. The @embed attribute supports the following arguments: +// +// file=$filename +// +// The use of the file argument tells embed to load a single file into the +// field. This argument many not be used in conjunction with the glob argument. +// +// glob=$pattern +// +// The use of the glob argument tells embed to load multiple files into the +// field as a map of file paths to the decoded values. The paths are normalized +// to use forward slashes. This argument may not be used in conjunction with the +// file argument. +// +// type=$type +// +// By default, the file type is interpreted based on the file extension. This +// behavior can be overridden by the type argument. See cue help filetypes for +// the list of supported types. This field is required if a file extension is +// unknown, or if a wildcard is used for the file extension in the glob pattern. +// +// allowEmptyGlob +// +// By default, a glob pattern that matches no files results in an error. When +// allowEmptyGlob is present, a glob pattern with no matches will return an +// empty struct instead of an error. This option is only supported with glob patterns. +// +// # Limitations +// +// The embed interpreter currently does not support: +// - stream values, such as .ndjson or YAML streams. +// - schema-based decoding, such as needed for textproto +// +// # Example +// +// @extern(embed) +// +// package foo +// +// // interpreted as JSON +// a: _ @embed(file="file1.json") // the quotes are optional here +// +// // interpreted the same file as JSON schema +// #A: _ @embed(file=file1.json, type=jsonschema) +// +// // interpret a proprietary extension as OpenAPI represented as YAML +// b: _ @embed(file="file2.crd", type=openapi+yaml) +// +// // include all YAML files in the x directory interpreted as YAML +// // The result is a map of file paths to the decoded YAML values. +// files: _ @embed(glob=x/*.yaml) +// +// // include all files in the y directory as a map of file paths to binary +// // data. The entries are unified into the same map as above. +// files: _ @embed(glob=y/*.*, type=binary) +// +// // include all YAML files in the z directory, but allow empty result +// // if no files match (returns empty struct instead of error) +// optionalFiles: _ @embed(glob=z/*.yaml, allowEmptyGlob) +package embed + +import ( + "io/fs" + "os" + "path" + "path/filepath" + "strings" + + "cuelang.org/go/cue" + "cuelang.org/go/cue/build" + "cuelang.org/go/cue/errors" + "cuelang.org/go/cue/token" + "cuelang.org/go/internal" + "cuelang.org/go/internal/core/adt" + "cuelang.org/go/internal/core/runtime" + "cuelang.org/go/internal/encoding" + "cuelang.org/go/internal/filetypes" + "cuelang.org/go/internal/value" + pkgpath "cuelang.org/go/pkg/path" +) + +// TODO: record files in build.Instance + +// interpreter is a [cuecontext.ExternInterpreter] for embedded files. +type interpreter struct{} + +// Note that [cuecontext.ExternInterpreter] is just an alias for [runtime.Interpreter] +// but because the [cuelang.org/go/cue/cuecontext] package depends on embedding +// we cannot refer to that type directly. + +// New returns a new interpreter for embedded files as a +// [cuelang.org/go/cue/cuecontext.ExternInterpreter] suitable for +// passing to [cuelang.org/go/cue/cuecontext.New]. +func New() runtime.Interpreter { + return interpreter{} +} + +func (i interpreter) Kind() string { + return "embed" +} + +// NewCompiler returns a compiler that can decode and embed files that exist +// within a CUE module. +func (i interpreter) NewCompiler(b *build.Instance, r *runtime.Runtime) (runtime.Compiler, errors.Error) { + if b.Module == "" { + return nil, errors.Newf(token.Pos{}, "cannot embed files when not in a module") + } + if b.Root == "" { + return nil, errors.Newf(token.Pos{}, "cannot embed files: no module root found") + } + return &compiler{ + b: b, + runtime: (*cue.Context)(r), + }, nil +} + +// A compiler is a [runtime.Compiler] that allows embedding files into CUE +// values. +type compiler struct { + b *build.Instance + runtime *cue.Context + opCtx *adt.OpContext + + // file system cache + dir string + fs fs.StatFS + pos token.Pos +} + +// Compile interprets an embed attribute to either load a file +// (@embed(file=...)) or a glob of files (@embed(glob=...)). +// and decodes the given files. +func (c *compiler) Compile(funcName string, scope adt.Value, a *internal.Attr) (adt.Expr, errors.Error) { + + file, _, err := a.Lookup(0, "file") + if err != nil { + return nil, errors.Promote(err, "invalid attribute") + } + + glob, _, err := a.Lookup(0, "glob") + if err != nil { + return nil, errors.Promote(err, "invalid attribute") + } + + typ, _, err := a.Lookup(0, "type") + if err != nil { + return nil, errors.Promote(err, "invalid type argument") + } + + allowEmptyGlob, err := a.Flag(0, "allowEmptyGlob") + if err != nil { + return nil, errors.Promote(err, "invalid allowEmptyGlob argument") + } + + c.opCtx = adt.NewContext((*runtime.Runtime)(c.runtime), nil) + + pos := a.Pos + c.pos = pos + + // Jump through some hoops to get file operations to behave the same for + // Windows and Unix. + // TODO: obtain a fs.FS from load or something similar. + dir := filepath.Dir(pos.File().Name()) + if c.dir != dir { + c.fs = os.DirFS(dir).(fs.StatFS) // Documented as implementing fs.StatFS + c.dir = dir + } + + switch { + case file == "" && glob == "": + return nil, errors.Newf(a.Pos, "attribute must have file or glob field") + + case file != "" && glob != "": + return nil, errors.Newf(a.Pos, "attribute cannot have both file and glob field") + case allowEmptyGlob && glob == "": + return nil, errors.Newf(a.Pos, "allowEmptyGlob must be specified with a glob field") + case file != "": + return c.processFile(file, typ, scope) + + default: // glob != "": + return c.processGlob(glob, typ, allowEmptyGlob, scope) + } +} + +func (c *compiler) processFile(file, scope string, schema adt.Value) (adt.Expr, errors.Error) { + file, err := c.clean(file) + if err != nil { + return nil, err + } + for dir := path.Dir(file); dir != "."; dir = path.Dir(dir) { + if _, err := c.fs.Stat(path.Join(dir, "cue.mod")); err == nil { + return nil, errors.Newf(c.pos, "cannot embed file %q: in different module", file) + } + } + + return c.decodeFile(file, scope, schema) +} + +func (c *compiler) processGlob(glob, scope string, allowEmptyGlob bool, schema adt.Value) (adt.Expr, errors.Error) { + glob, ce := c.clean(glob) + if ce != nil { + return nil, ce + } + + // Validate that the glob pattern is valid per [pkgpath.Match]. + // Note that we use Unix match semantics because all embed paths are Unix-like. + if _, err := pkgpath.Match(glob, "", pkgpath.Unix); err != nil { + return nil, errors.Wrapf(err, c.pos, "invalid glob pattern %q", glob) + } + + // If we do not have a type, ensure the extension of the base is fully + // specified, i.e. does not contain any meta characters as specified by + // path.Match. + if scope == "" { + ext := path.Ext(path.Base(glob)) + if ext == "" || strings.ContainsAny(ext, "*?[\\") { + return nil, errors.Newf(c.pos, "extension not fully specified; type argument required") + } + } + + m := &adt.StructLit{} + + matches, err := fsGlob(c.fs, glob) + if err != nil { + return nil, errors.Promote(err, "failed to match glob") + } + if len(matches) == 0 && !allowEmptyGlob { + return nil, errors.Newf(c.pos, "no matches for glob pattern %q", glob) + } + + dirs := make(map[string]string) + for _, f := range matches { + // TODO: lots of stat calls happening in this MVP so another won't hurt. + // We don't support '**' initially, and '*' only matches files, so skip + // any directories. + if fi, err := c.fs.Stat(f); err != nil { + return nil, errors.Newf(c.pos, "failed to stat %s: %v", f, err) + } else if fi.IsDir() { + continue + } + // Add all parents of the embedded file that + // aren't the current directory (if there's a cue.mod + // in the current directory, that's the current module + // not nested). + for dir := path.Dir(f); dir != "."; dir = path.Dir(dir) { + dirs[dir] = f + } + + expr, err := c.decodeFile(f, scope, schema) + if err != nil { + return nil, err + } + + m.Decls = append(m.Decls, &adt.Field{ + Label: c.opCtx.StringLabel(f), + Value: expr, + }) + } + // Check that none of the matches were in a nested module + // directory. + for dir, f := range dirs { + if _, err := c.fs.Stat(path.Join(dir, "cue.mod")); err == nil { + return nil, errors.Newf(c.pos, "cannot embed file %q: in different module", f) + } + } + return m, nil +} + +func (c *compiler) clean(s string) (string, errors.Error) { + file := path.Clean(s) + if file != s { + return file, errors.Newf(c.pos, "path not normalized, use %q instead", file) + } + if path.IsAbs(file) { + return "", errors.Newf(c.pos, "only relative files are allowed") + } + if file == ".." || strings.HasPrefix(file, "../") { + return "", errors.Newf(c.pos, "cannot refer to parent directory") + } + return file, nil +} + +// fsGlob is like [fs.Glob] but only includes dot-prefixed files +// when the dot is explictly present in an element. +// TODO: add option for including dot files? +func fsGlob(fsys fs.FS, pattern string) ([]string, error) { + pattern = path.Clean(pattern) + matches, err := fs.Glob(fsys, pattern) + if err != nil { + return nil, err + } + patElems := strings.Split(pattern, "/") + included := func(m string) bool { + for i, elem := range strings.Split(m, "/") { + // Technically there should never be more elements in m than + // there are in patElems, but be defensive and check bounds just in case. + if strings.HasPrefix(elem, ".") && (i >= len(patElems) || !strings.HasPrefix(patElems[i], ".")) { + return false + } + } + return true + } + + i := 0 + for _, m := range matches { + if included(m) { + matches[i] = m + i++ + } + } + return matches[:i], nil +} + +func (c *compiler) decodeFile(file, scope string, schema adt.Value) (adt.Expr, errors.Error) { + // Do not use the most obvious filetypes.Input in order to disable "auto" + // mode. + f, err := filetypes.ParseFileAndType(file, scope, filetypes.Def) + if err != nil { + return nil, errors.Promote(err, "invalid file type") + } + + // Open and pre-load the file system using fs.FS, instead of relying + r, err := c.fs.Open(file) + if err != nil { + return nil, errors.Newf(c.pos, "open %v: no such file or directory", file) + } + defer r.Close() + + info, err := r.Stat() + if err != nil { + return nil, errors.Promote(err, "failed to decode file") + } + if info.IsDir() { + return nil, errors.Newf(c.pos, "cannot embed directories") + } + f.Source = r + + // TODO: this really should be done at the start of the build process. + // c.b.ExternFiles = append(c.b.ExternFiles, f) + + config := &encoding.Config{ + // TODO: schema is currently the wrong schema, which is a bug in + // internal/core/runtime. There is also an outstanding design choice: + // do we imply the schema from the schema of the current field, or do + // we explicitly enable schema-based encoding with a "schema" argument. + // In the case of YAML it seems to be better to be explicit. In the case + // of textproto it seems to be more convenient to do it implicitly. + // Schema: value.Make(c.opCtx, schema), + } + + d := encoding.NewDecoder(c.runtime, f, config) + if err := d.Err(); err != nil { + return nil, errors.Promote(err, "failed to decode file") + } + + defer d.Close() + + n := d.File() + + if d.Next(); !d.Done() { + // TODO: support streaming values + return nil, errors.Newf(c.pos, "streaming not implemented: found more than one value in file") + } + + // TODO: each of these encodings should probably be supported in the future + switch f.Encoding { + case build.CUE: + return nil, errors.Newf(c.pos, "encoding %q not (yet) supported", f.Encoding) + case build.JSONL: + return nil, errors.Newf(c.pos, "encoding %q not (yet) supported: requires support for streaming", f.Encoding) + case build.BinaryProto, build.TextProto: + return nil, errors.Newf(c.pos, "encoding %q not (yet) supported: requires support for schema-guided decoding", f.Encoding) + } + + val := c.runtime.BuildFile(n) + if err := val.Err(); err != nil { + return nil, errors.Promote(err, "failed to build file") + } + + _, v := value.ToInternal(val) + return v, nil +} diff --git a/vendor/cuelang.org/go/cue/literal/quote.go b/vendor/cuelang.org/go/cue/literal/quote.go index 2208e2cf7f..78cc355825 100644 --- a/vendor/cuelang.org/go/cue/literal/quote.go +++ b/vendor/cuelang.org/go/cue/literal/quote.go @@ -53,7 +53,7 @@ func (f Form) WithTabIndent(n int) Form { return f } -// WithOptionalIndent is like WithTabIndent, but only returns a multiline +// WithOptionalTabIndent is like [Form.WithTabIndent], but only returns a multiline // strings if it doesn't contain any newline characters. func (f Form) WithOptionalTabIndent(tabs int) Form { f.indent = strings.Repeat("\t", tabs) @@ -82,7 +82,7 @@ var ( // TODO: ExactString: quotes to bytes type if the string cannot be // represented without loss of accuracy. - // Label is like String, but optimized for labels. + // Label is like [String], but optimized for labels. Label Form = stringForm // Bytes defines the format of bytes literal. @@ -133,10 +133,11 @@ func (f Form) Append(buf []byte, s string) []byte { buf = append(buf, '#') } if f.multiline { - buf = append(buf, f.quote, f.quote, f.quote, '\n') + buf = append(buf, f.tripleQuote...) + buf = append(buf, '\n') if s == "" { buf = append(buf, f.indent...) - buf = append(buf, f.quote, f.quote, f.quote) + buf = append(buf, f.tripleQuote...) return buf } if len(s) > 0 && s[0] != '\n' { @@ -151,7 +152,7 @@ func (f Form) Append(buf []byte, s string) []byte { if f.multiline { buf = append(buf, '\n') buf = append(buf, f.indent...) - buf = append(buf, f.quote, f.quote, f.quote) + buf = append(buf, f.tripleQuote...) } else { buf = append(buf, f.quote) } @@ -192,7 +193,8 @@ func (f Form) appendEscaped(buf []byte, s string) []byte { r, width = utf8.DecodeRuneInString(s) } if f.exact && width == 1 && r == utf8.RuneError { - buf = append(buf, `\x`...) + buf = f.appendEscape(buf) + buf = append(buf, 'x') buf = append(buf, lowerhex[s[0]>>4]) buf = append(buf, lowerhex[s[0]&0xF]) continue diff --git a/vendor/cuelang.org/go/cue/load/config.go b/vendor/cuelang.org/go/cue/load/config.go index 738b57d083..0ed8052ba1 100644 --- a/vendor/cuelang.org/go/cue/load/config.go +++ b/vendor/cuelang.org/go/cue/load/config.go @@ -18,12 +18,15 @@ import ( "context" "fmt" "io" + "io/fs" "os" "path/filepath" + "runtime" "cuelang.org/go/cue/ast" "cuelang.org/go/cue/build" "cuelang.org/go/cue/errors" + "cuelang.org/go/cue/parser" "cuelang.org/go/cue/token" "cuelang.org/go/internal" "cuelang.org/go/mod/modconfig" @@ -149,6 +152,11 @@ type Config struct { // equal to Module. modFile *modfile.File + // parserConfig holds the configuration that will be passed + // when parsing CUE files. It includes the version from + // the module file. + parserConfig parser.Config + // Package defines the name of the package to be loaded. If this is not set, // the package must be uniquely defined from its context. Special values: // _ load files without a package @@ -160,6 +168,11 @@ type Config struct { // For example, it is used to determine the main module, // and rooted import paths starting with "./" are relative to it. // If Dir is empty, the current directory is used. + // + // When using an Overlay with file entries such as "/foo/bar/baz.cue", + // you can use an absolute path that is a parent of one of the overlaid files, + // such as in this case "/foo" or "/foo/bar", even if these directories + // do not exist in the host filesystem. Dir string // Tags defines boolean tags or key-value pairs to select files to build @@ -266,11 +279,16 @@ type Config struct { // An application may supply a custom implementation of ParseFile to change // the effective file contents or the behavior of the parser, or to modify // the syntax tree. - ParseFile func(name string, src interface{}) (*ast.File, error) + ParseFile func(name string, src interface{}, cfg parser.Config) (*ast.File, error) - // Overlay provides a mapping of absolute file paths to file contents. If - // the file with the given path already exists, the parser will use the - // alternative file contents provided by the map. + // Overlay provides a mapping of absolute file paths to file contents, + // which are overlaid on top of the host operating system when loading files. + // + // If an overlaid file already exists in the host filesystem, + // the overlaid file contents will be used in its place. + // If an overlaid file does not exist in the host filesystem, + // the loader behaves as if the overlaid file exists with its contents, + // and that that all of its parent directories exist too. Overlay map[string]Source // Stdin defines an alternative for os.Stdin for the file "-". When used, @@ -310,7 +328,7 @@ func addImportQualifier(pkg importPath, name string) (importPath, error) { if name == "" { return pkg, nil } - ip := module.ParseImportPath(string(pkg)) + ip := ast.ParseImportPath(string(pkg)) if ip.Qualifier == "_" { return "", fmt.Errorf("invalid import qualifier _ in %q", pkg) } @@ -333,6 +351,8 @@ func addImportQualifier(pkg importPath, name string) (importPath, error) { // It does not initialize c.Context, because that requires the // loader in order to use for build.Loader. func (c Config) complete() (cfg *Config, err error) { + // Ensure [Config.Dir] is a clean and absolute path, + // necessary for matching directory prefixes later. if c.Dir == "" { c.Dir, err = os.Getwd() if err != nil { @@ -350,6 +370,9 @@ func (c Config) complete() (cfg *Config, err error) { } c.fileSystem = fsys + // Ensure [Config.ModuleRoot] is a clean and absolute path, + // necessary for matching directory prefixes later. + // // TODO: determine root on a package basis. Maybe we even need a // pkgname.cue.mod // Look to see if there is a cue.mod. @@ -365,11 +388,13 @@ func (c Config) complete() (cfg *Config, err error) { } } else if !filepath.IsAbs(c.ModuleRoot) { c.ModuleRoot = filepath.Join(c.Dir, c.ModuleRoot) + } else { + c.ModuleRoot = filepath.Clean(c.ModuleRoot) } if c.SkipImports { // We should never use the registry in SkipImports mode - // but nil it out to be sure. - c.Registry = nil + // but make it always return an error just to be sure. + c.Registry = errorRegistry{errors.New("unexpected use of registry in SkipImports mode")} } else if c.Registry == nil { registry, err := modconfig.NewRegistry(&modconfig.Config{ Env: c.Env, @@ -382,12 +407,20 @@ func (c Config) complete() (cfg *Config, err error) { } c.Registry = registry } + c.parserConfig = parser.NewConfig(parser.ParseComments) if err := c.loadModule(); err != nil { return nil, err } return &c, nil } +func (c *Config) languageVersion() string { + if c.modFile == nil || c.modFile.Language == nil { + return "" + } + return c.modFile.Language.Version +} + // loadModule loads the module file, resolves and downloads module // dependencies. It sets c.Module if it's empty or checks it for // consistency with the module file otherwise. @@ -402,6 +435,19 @@ func (c *Config) loadModule() error { if cerr != nil { // If we could not load cue.mod/module.cue, check whether the reason was // a legacy cue.mod file and give the user a clear error message. + // + // Common case: the file does not exist. Avoid an extra stat + // syscall using the error code when we can. + // + // TODO(mvdan): we can remove this in mid 2026, once we can safely assume that + // practically all cue.mod files have vanished. + if errors.Is(cerr, fs.ErrNotExist) && runtime.GOOS != "windows" { + // The file definitely does not exist. On Windows unfortunately due + // to https://github.com/golang/go/issues/46734 + // we can't tell the difference between "does not exist" + // and "is not a directory", hence the special casing. + return nil + } info, cerr2 := c.fileSystem.stat(modDir) if cerr2 == nil && !info.IsDir() { return fmt.Errorf("cue.mod files are no longer supported; use cue.mod/module.cue") @@ -438,6 +484,8 @@ func (c *Config) loadModule() error { return errors.Newf(token.NoPos, "inconsistent modules: got %q, want %q", mf.Module, c.Module) } c.Module = mf.QualifiedModule() + // Set the default version for CUE files without a module. + c.parserConfig = c.parserConfig.Apply(parser.Version(c.modFile.Language.Version)) return nil } @@ -472,6 +520,7 @@ func (c *Config) newErrInstance(err error) *build.Instance { i := c.Context.NewInstance("", nil) i.Root = c.ModuleRoot i.Module = c.Module + i.ModuleFile = c.modFile i.Err = errors.Promote(err, "") return i } diff --git a/vendor/cuelang.org/go/cue/load/errors.go b/vendor/cuelang.org/go/cue/load/errors.go index 02b063ce6e..8faa41ff2a 100644 --- a/vendor/cuelang.org/go/cue/load/errors.go +++ b/vendor/cuelang.org/go/cue/load/errors.go @@ -43,6 +43,7 @@ func (p *PackageError) fillPos(cwd string, positions []token.Pos) { } // TODO(localize) + func (p *PackageError) Error() string { // Import cycles deserve special treatment. if p.IsImportCycle { @@ -73,10 +74,8 @@ func (e *NoFilesError) InputPositions() []token.Pos { return nil } func (e *NoFilesError) Path() []string { return nil } // TODO(localize) -func (e *NoFilesError) Msg() (string, []interface{}) { return e.Error(), nil } -// TODO(localize) -func (e *NoFilesError) Error() string { +func (e *NoFilesError) Msg() (string, []interface{}) { // Count files beginning with _, which we will pretend don't exist at all. dummy := 0 for _, f := range e.Package.IgnoredFiles { @@ -90,19 +89,19 @@ func (e *NoFilesError) Error() string { if len(e.Package.IgnoredFiles) > dummy { b := strings.Builder{} - b.WriteString("build constraints exclude all CUE files in ") - b.WriteString(path) - b.WriteString(":") + var args []any + b.WriteString("build constraints exclude all CUE files in %s:") + args = append(args, token.Position{Filename: path}) // CUE files exist, but they were ignored due to build constraints. for _, f := range e.Package.IgnoredFiles { - b.WriteString("\n ") - b.WriteString(filepath.ToSlash(e.Package.RelPath(f))) + b.WriteString("\n %s") + args = append(args, token.Position{Filename: f.Filename}) if f.ExcludeReason != nil { - b.WriteString(": ") - b.WriteString(f.ExcludeReason.Error()) + b.WriteString(": %v") + args = append(args, f.ExcludeReason) } } - return b.String() + return b.String(), args } // if len(e.Package.TestCUEFiles) > 0 { // // Test CUE files exist, but we're not interested in them. @@ -110,7 +109,12 @@ func (e *NoFilesError) Error() string { // // to appear at the end of error message. // return "no non-test CUE files in " + e.Package.Dir // } - return "no CUE files in " + path + return "no CUE files in %s", []any{path} +} + +func (e *NoFilesError) Error() string { + format, args := e.Msg() + return fmt.Sprintf(format, args...) } // MultiplePackageError describes an attempt to build a package composed of @@ -131,7 +135,9 @@ func (e *MultiplePackageError) Msg() (string, []interface{}) { e.Files[0], e.Packages[1], e.Files[1], - e.Dir, + // To make sure [cue/errors] prints this directory name as relative, + // use a [token.Position] even though it's really only meant for regular source files. + token.Position{Filename: e.Dir}, } } diff --git a/vendor/cuelang.org/go/cue/load/fs.go b/vendor/cuelang.org/go/cue/load/fs.go index 4bc767d85f..411a2f2db4 100644 --- a/vendor/cuelang.org/go/cue/load/fs.go +++ b/vendor/cuelang.org/go/cue/load/fs.go @@ -32,6 +32,7 @@ import ( "cuelang.org/go/cue/build" "cuelang.org/go/cue/cuecontext" "cuelang.org/go/cue/errors" + "cuelang.org/go/cue/parser" "cuelang.org/go/cue/token" "cuelang.org/go/internal/encoding" "cuelang.org/go/mod/module" @@ -86,10 +87,11 @@ func (fs *fileSystem) getDir(dir string, create bool) map[string]*overlayFile { // the resulting source locations back to the filesystem // paths required by most of the `cue/load` package // implementation. -func (fs *fileSystem) ioFS(root string) iofs.FS { +func (fs *fileSystem) ioFS(root string, languageVersion string) iofs.FS { return &ioFS{ - fs: fs, - root: root, + fs: fs, + root: root, + languageVersion: languageVersion, } } @@ -281,8 +283,9 @@ var _ interface { } = (*ioFS)(nil) type ioFS struct { - fs *fileSystem - root string + fs *fileSystem + root string + languageVersion string } func (fs *ioFS) OSRoot() string { @@ -345,14 +348,15 @@ var _ module.ReadCUEFS = (*ioFS)(nil) // reading and updating the syntax file cache, which // is shared with the cache used by the [fileSystem.getCUESyntax] // method. -func (fs *ioFS) ReadCUEFile(path string) (*ast.File, error) { +func (fs *ioFS) ReadCUEFile(path string, cfg parser.Config) (*ast.File, error) { fpath, err := fs.absPathFromFSPath(path) if err != nil { return nil, err } + key := fileCacheKey{cfg, fpath} cache := fs.fs.fileCache cache.mu.Lock() - entry, ok := cache.entries[fpath] + entry, ok := cache.entries[key] cache.mu.Unlock() if ok { return entry.file, entry.err @@ -370,16 +374,19 @@ func (fs *ioFS) ReadCUEFile(path string) (*ast.File, error) { if err != nil { cache.mu.Lock() defer cache.mu.Unlock() - cache.entries[fpath] = fileCacheEntry{nil, err} + cache.entries[key] = fileCacheEntry{nil, err} return nil, err } } + if fs.languageVersion != "" { + cfg = cfg.Apply(parser.Version(fs.languageVersion)) + } return fs.fs.getCUESyntax(&build.File{ Filename: fpath, Encoding: build.CUE, // Form: build.Schema, Source: data, - }) + }, cfg) } // ioFSFile implements [io/fs.File] for the overlay filesystem. @@ -433,26 +440,29 @@ func (f *ioFSFile) ReadDir(n int) ([]iofs.DirEntry, error) { return entries, err } -func (fs *fileSystem) getCUESyntax(bf *build.File) (*ast.File, error) { +func (fs *fileSystem) getCUESyntax(bf *build.File, cfg parser.Config) (*ast.File, error) { fs.fileCache.mu.Lock() defer fs.fileCache.mu.Unlock() if bf.Encoding != build.CUE { panic("getCUESyntax called with non-CUE file encoding") } + key := fileCacheKey{cfg, bf.Filename} // When it's a regular CUE file with no funny stuff going on, we // check and update the syntax cache. useCache := bf.Form == "" && bf.Interpretation == "" if useCache { - if syntax, ok := fs.fileCache.entries[bf.Filename]; ok { + if syntax, ok := fs.fileCache.entries[key]; ok { return syntax.file, syntax.err } } - d := encoding.NewDecoder(fs.fileCache.ctx, bf, &fs.fileCache.config) + encodingCfg := fs.fileCache.config + encodingCfg.ParserConfig = cfg + d := encoding.NewDecoder(fs.fileCache.ctx, bf, &encodingCfg) defer d.Close() // Note: CUE files can never have multiple file parts. f, err := d.File(), d.Err() if useCache { - fs.fileCache.entries[bf.Filename] = fileCacheEntry{f, err} + fs.fileCache.entries[key] = fileCacheEntry{f, err} } return f, err } @@ -465,7 +475,7 @@ func newFileCache(c *Config) *fileCache { ParseFile: c.ParseFile, }, ctx: cuecontext.New(), - entries: make(map[string]fileCacheEntry), + entries: make(map[fileCacheKey]fileCacheEntry), } } @@ -474,7 +484,12 @@ type fileCache struct { config encoding.Config ctx *cue.Context mu sync.Mutex - entries map[string]fileCacheEntry + entries map[fileCacheKey]fileCacheEntry +} + +type fileCacheKey struct { + cfg parser.Config + path string } type fileCacheEntry struct { diff --git a/vendor/cuelang.org/go/cue/load/import.go b/vendor/cuelang.org/go/cue/load/import.go index 1015227bc2..7daa40a16f 100644 --- a/vendor/cuelang.org/go/cue/load/import.go +++ b/vendor/cuelang.org/go/cue/load/import.go @@ -19,11 +19,13 @@ import ( "fmt" "io" "io/fs" + "os" pathpkg "path" "path/filepath" "slices" "strings" + "cuelang.org/go/cue/ast" "cuelang.org/go/cue/build" "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" @@ -62,10 +64,8 @@ func (l *loader) importPkg(pos token.Pos, p *build.Instance) []*build.Instance { return []*build.Instance{p} } - for _, item := range l.stk { - if item == p.ImportPath { - return retErr(&PackageError{Message: errors.NewMessagef("package import cycle not allowed")}) - } + if slices.Contains(l.stk, p.ImportPath) { + return retErr(&PackageError{Message: errors.NewMessagef("package import cycle not allowed")}) } l.stk.Push(p.ImportPath) defer l.stk.Pop() @@ -257,6 +257,16 @@ func setFileSource(cfg *Config, f *build.File) error { return nil } fullPath := f.Filename + + // If the input file is stdin or a non-regular file, + // such as a named pipe or a device file, we can only read it once. + // Given that later on we may consume the source multiple times, + // such as first to only parse the imports and later to parse the whole file, + // read the whole file here upfront and buffer the bytes. + // + // TODO(perf): this causes an upfront "stat" syscall for every input file, + // which is wasteful given that in the majority of cases we deal with regular files. + // Consider doing the buffering the first time we open the file later on. if fullPath == "-" { b, err := io.ReadAll(cfg.stdin()) if err != nil { @@ -265,6 +275,7 @@ func setFileSource(cfg *Config, f *build.File) error { f.Source = b return nil } + if !filepath.IsAbs(fullPath) { fullPath = filepath.Join(cfg.Dir, fullPath) // Ensure that encoding.NewDecoder will work correctly. @@ -276,7 +287,24 @@ func setFileSource(cfg *Config, f *build.File) error { } else { f.Source = fi.contents } + return nil + } + + // Note that we do this after ensuring fullPath is absolute, and after checking + // whether the overlay provides the source. + info, err := os.Stat(fullPath) + if err != nil { + return err + } + if !info.Mode().IsRegular() { + b, err := os.ReadFile(fullPath) + if err != nil { + return err + } + f.Source = b + return nil } + return nil } @@ -310,12 +338,13 @@ func (l *loader) newRelInstance(pos token.Pos, path, pkgName string) *build.Inst panic(fmt.Errorf("non-relative import path %q passed to newRelInstance", path)) } - p := l.cfg.Context.NewInstance(path, l.loadFunc()) + p := l.cfg.Context.NewInstance(path, nil) p.PkgName = pkgName p.DisplayPath = filepath.ToSlash(path) // p.ImportPath = string(dir) // compute unique ID. p.Root = l.cfg.ModuleRoot p.Module = l.cfg.Module + p.ModuleFile = l.cfg.modFile var err errors.Error if path != cleanImport(path) { @@ -351,7 +380,6 @@ func (l *loader) newRelInstance(pos token.Pos, path, pkgName string) *build.Inst p.Err = errors.Append(p.Err, err) p.Incomplete = true } - return p } @@ -360,12 +388,17 @@ func importPathFromAbsDir(c *Config, absDir string, origPath string) (importPath return "", fmt.Errorf("cannot determine import path for %q (root undefined)", origPath) } - dir := filepath.Clean(absDir) - if !strings.HasPrefix(dir, c.ModuleRoot) { + subdir, ok := strings.CutPrefix(filepath.Clean(absDir), c.ModuleRoot) + if !ok { return "", fmt.Errorf("cannot determine import path for %q (dir outside of root)", origPath) } - pkg := filepath.ToSlash(dir[len(c.ModuleRoot):]) + pkg := filepath.ToSlash(subdir) + if pkg != "" && !strings.HasPrefix(pkg, "/") { + // [Config.ModuleRoot] was the root of the filesystem, + // and it had a trailing slash which got removed as a prefix; add it back. + pkg = "/" + pkg + } switch { case strings.HasPrefix(pkg, "/cue.mod/"): pkg = pkg[len("/cue.mod/"):] @@ -376,7 +409,7 @@ func importPathFromAbsDir(c *Config, absDir string, origPath string) (importPath case c.Module == "": return "", fmt.Errorf("cannot determine import path for %q (no module)", origPath) default: - impPath := module.ParseImportPath(c.Module) + impPath := ast.ParseImportPath(c.Module) impPath.Path += pkg impPath.Qualifier = "" pkg = impPath.String() @@ -385,12 +418,11 @@ func importPathFromAbsDir(c *Config, absDir string, origPath string) (importPath } func (l *loader) newInstance(pos token.Pos, p importPath) *build.Instance { - dir, modPath, err := l.absDirFromImportPath(pos, p) - i := l.cfg.Context.NewInstance(dir, l.loadFunc()) + dir, mv, modRoot, err := l.absDirFromImportPath(pos, p) + i := l.cfg.Context.NewInstance(dir, nil) i.Err = errors.Append(i.Err, err) i.Dir = dir - - parts := module.ParseImportPath(string(p)) + parts := ast.ParseImportPath(string(p)) i.PkgName = parts.Qualifier if i.PkgName == "" { i.Err = errors.Append(i.Err, l.errPkgf([]token.Pos{pos}, "cannot determine package name for %q; set it explicitly with ':'", p)) @@ -399,8 +431,21 @@ func (l *loader) newInstance(pos token.Pos, p importPath) *build.Instance { } i.DisplayPath = string(p) i.ImportPath = string(p) - i.Root = l.cfg.ModuleRoot - i.Module = modPath + if mv.Path() == "" { + return i + } + mf, err1 := l.modFileCache.modFile(mv, modRoot) + if err != nil { + i.Err = errors.Append(i.Err, errors.Promote(err1, "")) + } + root, err1 := absPathForSourceLoc(modRoot) + if err != nil { + i.Err = errors.Append(i.Err, errors.Promote(err1, "")) + } else { + i.Root = root + } + i.Module = mv.Path() + i.ModuleFile = mf return i } @@ -409,31 +454,34 @@ func (l *loader) newInstance(pos token.Pos, p importPath) *build.Instance { // and a package name. The root directory must be set. // // The returned directory may not exist. -func (l *loader) absDirFromImportPath(pos token.Pos, p importPath) (dir string, modPath string, _ errors.Error) { - dir, modPath, err := l.absDirFromImportPath1(pos, p) +func (l *loader) absDirFromImportPath(pos token.Pos, p importPath) (dir string, mv module.Version, modRoot module.SourceLoc, _ errors.Error) { + dir, mv, modRoot, err := l.absDirFromImportPath1(pos, p) if err != nil { // Any error trying to determine the package location // is a PackageError. - return "", "", l.errPkgf([]token.Pos{pos}, "%s", err.Error()) + return "", module.Version{}, module.SourceLoc{}, l.errPkgf([]token.Pos{pos}, "%s", err.Error()) } - return dir, modPath, nil + return dir, mv, modRoot, nil } -func (l *loader) absDirFromImportPath1(pos token.Pos, p importPath) (absDir string, modPath string, err error) { +func (l *loader) absDirFromImportPath1(pos token.Pos, p importPath) (absDir string, mv module.Version, modRoot module.SourceLoc, err error) { + failf := func(f string, a ...any) (string, module.Version, module.SourceLoc, error) { + return "", module.Version{}, module.SourceLoc{}, fmt.Errorf(f, a...) + } if p == "" { - return "", "", fmt.Errorf("empty import path") + return failf("empty import path") } if l.cfg.ModuleRoot == "" { - return "", "", fmt.Errorf("cannot import %q (root undefined)", p) + return failf("cannot import %q (root undefined)", p) } if isStdlibPackage(string(p)) { - return "", "", fmt.Errorf("standard library import path %q cannot be imported as a CUE package", p) + return failf("standard library import path %q cannot be imported as a CUE package", p) } if l.pkgs == nil { - return "", "", fmt.Errorf("imports are unavailable because there is no cue.mod/module.cue file") + return failf("imports are unavailable because there is no cue.mod/module.cue file") } // Extract the package name. - parts := module.ParseImportPath(string(p)) + parts := ast.ParseImportPath(string(p)) unqualified := parts.Unqualified().String() // TODO predicate registry-aware lookup on module.cue-declared CUE version? @@ -445,10 +493,10 @@ func (l *loader) absDirFromImportPath1(pos token.Pos, p importPath) (absDir stri // should we not be using either the original path or the canonical path? // The unqualified import path should only be used for filepath.FromSlash further below. if pkg == nil { - return "", "", fmt.Errorf("no dependency found for package %q", unqualified) + return failf("no dependency found for package %q", unqualified) } if err := pkg.Error(); err != nil { - return "", "", fmt.Errorf("cannot find package %q: %v", unqualified, err) + return failf("cannot find package %q: %v", unqualified, err) } if mv := pkg.Mod(); mv.IsLocal() { // It's a local package that's present inside one or both of the gen, usr or pkg @@ -459,18 +507,18 @@ func (l *loader) absDirFromImportPath1(pos token.Pos, p importPath) (absDir stri } else { locs := pkg.Locations() if len(locs) > 1 { - return "", "", fmt.Errorf("package %q unexpectedly found in multiple locations", unqualified) + return failf("package %q unexpectedly found in multiple locations", unqualified) } if len(locs) == 0 { - return "", "", fmt.Errorf("no location found for package %q", unqualified) + return failf("no location found for package %q", unqualified) } var err error absDir, err = absPathForSourceLoc(locs[0]) if err != nil { - return "", "", fmt.Errorf("cannot determine source directory for package %q: %v", unqualified, err) + return failf("cannot determine source directory for package %q: %v", unqualified, err) } } - return absDir, pkg.Mod().Path(), nil + return absDir, pkg.Mod(), pkg.ModRoot(), nil } func absPathForSourceLoc(loc module.SourceLoc) (string, error) { diff --git a/vendor/cuelang.org/go/cue/load/instances.go b/vendor/cuelang.org/go/cue/load/instances.go index 7488549035..635c457c89 100644 --- a/vendor/cuelang.org/go/cue/load/instances.go +++ b/vendor/cuelang.org/go/cue/load/instances.go @@ -18,16 +18,22 @@ import ( "context" "fmt" "io/fs" + "maps" + "path" "slices" "strconv" "strings" "cuelang.org/go/cue/ast" "cuelang.org/go/cue/build" + "cuelang.org/go/cue/parser" "cuelang.org/go/internal/filetypes" "cuelang.org/go/internal/mod/modimports" + "cuelang.org/go/internal/mod/modload" "cuelang.org/go/internal/mod/modpkgload" "cuelang.org/go/internal/mod/modrequirements" + "cuelang.org/go/internal/mod/semver" + "cuelang.org/go/mod/modfile" "cuelang.org/go/mod/module" ) @@ -37,22 +43,20 @@ import ( // instance, but errors that occur loading dependencies are recorded in these // dependencies. func Instances(args []string, c *Config) []*build.Instance { - ctx := context.TODO() - if c == nil { - c = &Config{} - } - newC, err := c.complete() - if err != nil { - return []*build.Instance{c.newErrInstance(err)} - } - c = newC if len(args) == 0 { args = []string{"."} } // TODO: This requires packages to be placed before files. At some point this // could be relaxed. i := 0 + isAbsPkg := false for ; i < len(args) && filetypes.IsPackage(args[i]); i++ { + if isAbsVersionPackage(args[i]) { + if i > 0 { + return []*build.Instance{c.newErrInstance(fmt.Errorf("only a single package with absolute version may be specified"))} + } + isAbsPkg = true + } } pkgArgs := args[:i] otherArgs := args[i:] @@ -60,6 +64,15 @@ func Instances(args []string, c *Config) []*build.Instance { if err != nil { return []*build.Instance{c.newErrInstance(err)} } + ctx := context.TODO() + if c == nil { + c = &Config{} + } + newC, err := c.complete() + if err != nil { + return []*build.Instance{c.newErrInstance(err)} + } + c = newC for _, f := range otherFiles { if err := setFileSource(c, f); err != nil { return []*build.Instance{c.newErrInstance(err)} @@ -75,7 +88,7 @@ func Instances(args []string, c *Config) []*build.Instance { // of those, which don't. pkgArgs1 := make([]string, 0, len(pkgArgs)) for _, p := range pkgArgs { - if ip := module.ParseImportPath(p); !ip.ExplicitQualifier { + if ip := ast.ParseImportPath(p); !ip.ExplicitQualifier { ip.Qualifier = c.Package p = ip.String() } @@ -85,17 +98,24 @@ func Instances(args []string, c *Config) []*build.Instance { } tg := newTagger(c) - // Pass all arguments that look like packages to loadPackages - // so that they'll be available when looking up the packages - // that are specified on the command line. - expandedPaths, err := expandPackageArgs(c, pkgArgs, c.Package, tg) - if err != nil { - return []*build.Instance{c.newErrInstance(err)} - } var pkgs *modpkgload.Packages if !c.SkipImports { - pkgs, err = loadPackages(ctx, c, expandedPaths, otherFiles, tg) + if isAbsPkg { + // Note: replace the absolute package (which isn't actually a valid + // import path and may contain a version query like @latest) + // with the actual resolved import path. + pkgArgs[0], pkgs, err = loadAbsPackage(ctx, c, pkgArgs[0], tg) + } else { + // Pass all arguments that look like packages to loadPackages + // so that they'll be available when looking up the packages + // that are specified on the command line. + expandedPaths, err1 := expandPackageArgs(c, pkgArgs, c.Package, tg) + if err1 != nil { + return []*build.Instance{c.newErrInstance(err1)} + } + pkgs, err = loadPackagesFromArgs(ctx, c, expandedPaths, otherFiles, tg) + } if err != nil { return []*build.Instance{c.newErrInstance(err)} } @@ -164,9 +184,47 @@ func Instances(args []string, c *Config) []*build.Instance { return a } +// loadAbsPackage loads a single $package@$version package +// as the main module and returns its actual import path +// and the packages instance representing its module. +func loadAbsPackage( + ctx context.Context, + cfg *Config, + pkg string, + tg *tagger, +) (string, *modpkgload.Packages, error) { + // First find the module that contains the package. + mv, _, err := modload.ResolveAbsolutePackage(ctx, cfg.Registry, pkg) + if err != nil { + return "", nil, err + } + // ResolveAbsolutePackage should already have fetched the module + // so this should be quick. + loc, err := cfg.Registry.Fetch(ctx, mv) + if err != nil { + return "", nil, err + } + modFilePath := path.Join(loc.Dir, modDir, moduleFile) + modFileData, err := fs.ReadFile(loc.FS, modFilePath) + if err != nil { + return "", nil, err + } + mf, err := modfile.Parse(modFileData, modFilePath) + if err != nil { + return "", nil, err + } + // Make the package path into a regular import path + // with only the major version suffix. + ip := ast.ParseImportPath(pkg) + ip.Version = semver.Major(mv.Version()) + + pkgs := loadPackages(ctx, cfg, mf, loc, []string{ip.String()}, tg) + return ip.String(), pkgs, nil +} + // loadPackages returns packages loaded from the given package list and also // including imports from the given build files. -func loadPackages( +func loadPackagesFromArgs( ctx context.Context, cfg *Config, pkgs []resolvedPackageArg, @@ -176,17 +234,6 @@ func loadPackages( if cfg.modFile == nil || cfg.modFile.Module == "" { return nil, nil } - mainModPath := cfg.modFile.QualifiedModule() - reqs := modrequirements.NewRequirements( - mainModPath, - cfg.Registry, - cfg.modFile.DepVersions(), - cfg.modFile.DefaultMajorVersions(), - ) - mainModLoc := module.SourceLoc{ - FS: cfg.fileSystem.ioFS(cfg.ModuleRoot), - Dir: ".", - } pkgPaths := make(map[string]bool) // Add any packages specified directly on the command line. for _, pkg := range pkgs { @@ -198,34 +245,54 @@ func loadPackages( // not a CUE file; assume it has no imports for now. continue } - syntax, err := cfg.fileSystem.getCUESyntax(f) + // Note: this gets the current module's language version if there is one. + syntax, err := cfg.fileSystem.getCUESyntax(f, cfg.parserConfig.Apply(parser.ImportsOnly)) if err != nil { return nil, fmt.Errorf("cannot get syntax for %q: %w", f.Filename, err) } - for _, imp := range syntax.Imports { + for imp := range syntax.ImportSpecs() { pkgPath, err := strconv.Unquote(imp.Path.Value) if err != nil { // Should never happen. return nil, fmt.Errorf("invalid import path %q in %s", imp.Path.Value, f.Filename) } // Canonicalize the path. - pkgPath = module.ParseImportPath(pkgPath).Canonical().String() + pkgPath = ast.ParseImportPath(pkgPath).Canonical().String() pkgPaths[pkgPath] = true } } - // TODO use maps.Keys when we can. - pkgPathSlice := make([]string, 0, len(pkgPaths)) - for p := range pkgPaths { - pkgPathSlice = append(pkgPathSlice, p) - } - slices.Sort(pkgPathSlice) + return loadPackages(ctx, cfg, cfg.modFile, + module.SourceLoc{ + FS: cfg.fileSystem.ioFS(cfg.ModuleRoot, cfg.modFile.Language.Version), + Dir: ".", + }, + slices.Sorted(maps.Keys(pkgPaths)), + tg, + ), nil +} + +func loadPackages( + ctx context.Context, + cfg *Config, + mainMod *modfile.File, + mainModLoc module.SourceLoc, + pkgPaths []string, + tg *tagger, +) *modpkgload.Packages { + mainModPath := mainMod.QualifiedModule() + reqs := modrequirements.NewRequirements( + mainModPath, + cfg.Registry, + mainMod.DepVersions(), + mainMod.DefaultMajorVersions(), + ) return modpkgload.LoadPackages( ctx, - cfg.Module, + mainModPath, mainModLoc, reqs, cfg.Registry, - pkgPathSlice, + pkgPaths, func(pkgPath string, mod module.Version, fsys fs.FS, mf modimports.ModuleFile) bool { if !cfg.Tools && strings.HasSuffix(mf.FilePath, "_tool.cue") { return false @@ -255,5 +322,18 @@ func loadPackages( } return true }, - ), nil + ) +} + +func isAbsVersionPackage(p string) bool { + ip := ast.ParseImportPath(p) + if ip.Version == "" { + return false + } + if semver.Major(ip.Version) == ip.Version { + return false + } + // Anything other than a simple major version suffix counts + // as an absolute version. + return true } diff --git a/vendor/cuelang.org/go/cue/load/loader.go b/vendor/cuelang.org/go/cue/load/loader.go index b17ccbaa60..d00d225212 100644 --- a/vendor/cuelang.org/go/cue/load/loader.go +++ b/vendor/cuelang.org/go/cue/load/loader.go @@ -24,15 +24,17 @@ import ( "cuelang.org/go/cue/build" "cuelang.org/go/cue/errors" + "cuelang.org/go/cue/parser" "cuelang.org/go/cue/token" "cuelang.org/go/internal/mod/modpkgload" ) type loader struct { - cfg *Config - tagger *tagger - stk importStack - pkgs *modpkgload.Packages + cfg *Config + tagger *tagger + stk importStack + pkgs *modpkgload.Packages + modFileCache *modFileCache // dirCachedBuildFiles caches the work involved when reading a // directory. It is keyed by directory name. When we descend into @@ -52,6 +54,7 @@ func newLoader(c *Config, tg *tagger, pkgs *modpkgload.Packages) *loader { cfg: c, tagger: tg, pkgs: pkgs, + modFileCache: newModFileCache(), dirCachedBuildFiles: make(map[string]cachedDirFiles), } } @@ -76,24 +79,7 @@ func (l *loader) errPkgf(importPos []token.Pos, format string, args ...interface // (typically named on the command line). func (l *loader) cueFilesPackage(files []*build.File) *build.Instance { // ModInit() // TODO: support modules - pkg := l.cfg.Context.NewInstance(l.cfg.Dir, l.loadFunc()) - - for _, bf := range files { - f := bf.Filename - if f == "-" { - continue - } - if !filepath.IsAbs(f) { - f = filepath.Join(l.cfg.Dir, f) - } - fi, err := l.cfg.fileSystem.stat(f) - if err != nil { - return l.cfg.newErrInstance(errors.Wrapf(err, token.NoPos, "could not find file %v", f)) - } - if fi.IsDir() { - return l.cfg.newErrInstance(errors.Newf(token.NoPos, "file is a directory %v", f)) - } - } + pkg := l.cfg.Context.NewInstance(l.cfg.Dir, nil) fp := newFileProcessor(l.cfg, pkg, l.tagger) if l.cfg.Package == "*" { @@ -132,7 +118,11 @@ func (l *loader) cueFilesPackage(files []*build.File) *build.Instance { // addFiles populates p.Files by reading CUE syntax from p.BuildFiles. func (l *loader) addFiles(p *build.Instance) { for _, bf := range p.BuildFiles { - f, err := l.cfg.fileSystem.getCUESyntax(bf) + cfg := l.cfg.parserConfig + if p.ModuleFile != nil { + cfg = cfg.Apply(parser.Version(p.ModuleFile.Language.Version)) + } + f, err := l.cfg.fileSystem.getCUESyntax(bf, cfg) if err != nil { p.ReportError(errors.Promote(err, "load")) } diff --git a/vendor/cuelang.org/go/cue/load/loader_common.go b/vendor/cuelang.org/go/cue/load/loader_common.go index 37af722f95..355b54467a 100644 --- a/vendor/cuelang.org/go/cue/load/loader_common.go +++ b/vendor/cuelang.org/go/cue/load/loader_common.go @@ -16,6 +16,7 @@ package load import ( "cmp" + "maps" pathpkg "path" "path/filepath" "slices" @@ -146,7 +147,7 @@ func (fp *fileProcessor) finalize(p *build.Instance) errors.Error { return fp.err } - p.ImportPaths, _ = cleanImports(fp.imported) + p.ImportPaths = slices.Sorted(maps.Keys(fp.imported)) return nil } @@ -215,7 +216,7 @@ func (fp *fileProcessor) add(root string, file *build.File, mode importMode) { // Note: when path is "-" (stdin), it will already have // been read and file.Source set to the resulting data // by setFileSource. - pf, perr := fp.c.fileSystem.getCUESyntax(file) + pf, perr := fp.c.fileSystem.getCUESyntax(file, fp.c.parserConfig) if perr != nil { badFile(errors.Promote(perr, "add failed")) return @@ -247,6 +248,7 @@ func (fp *fileProcessor) add(root string, file *build.File, mode importMode) { q.ImportPath = p.ImportPath + ":" + pkg q.Root = p.Root q.Module = p.Module + q.ModuleFile = p.ModuleFile fp.pkgs[pkg] = q } p = q @@ -309,7 +311,7 @@ func (fp *fileProcessor) add(root string, file *build.File, mode importMode) { isTest := strings.HasSuffix(base, "_test"+cueSuffix) isTool := strings.HasSuffix(base, "_tool"+cueSuffix) - for _, spec := range pf.Imports { + for spec := range pf.ImportSpecs() { quoted := spec.Path.Value path, err := strconv.Unquote(quoted) if err != nil { @@ -344,15 +346,6 @@ func (fp *fileProcessor) add(root string, file *build.File, mode importMode) { } } -func cleanImports(m map[string][]token.Pos) ([]string, map[string][]token.Pos) { - all := make([]string, 0, len(m)) - for path := range m { - all = append(all, path) - } - slices.Sort(all) - return all, m -} - // isLocalImport reports whether the import path is // a local import path, like ".", "..", "./foo", or "../foo". func isLocalImport(path string) bool { diff --git a/vendor/cuelang.org/go/cue/load/modfilecache.go b/vendor/cuelang.org/go/cue/load/modfilecache.go new file mode 100644 index 0000000000..28f9717d44 --- /dev/null +++ b/vendor/cuelang.org/go/cue/load/modfilecache.go @@ -0,0 +1,57 @@ +// Copyright 2025 The CUE Authors +// +// 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. + +package load + +import ( + "fmt" + "io/fs" + "path" + "sync" + + "cuelang.org/go/mod/modfile" + "cuelang.org/go/mod/module" +) + +type modFileCache struct { + mu sync.Mutex + modfiles map[module.Version]*modfile.File +} + +func newModFileCache() *modFileCache { + return &modFileCache{ + modfiles: make(map[module.Version]*modfile.File), + } +} + +func (mc *modFileCache) modFile(mv module.Version, loc module.SourceLoc) (*modfile.File, error) { + mc.mu.Lock() + defer mc.mu.Unlock() + if loc.FS == nil { + return nil, fmt.Errorf("no location for %v", mv) + } + if f := mc.modfiles[mv]; f != nil { + return f, nil + } + data, err := fs.ReadFile(loc.FS, path.Join(loc.Dir, "cue.mod/module.cue")) + if err != nil { + return nil, err + } + f, err := modfile.Parse(data, "cue.mod/module.cue") + if err != nil { + return nil, fmt.Errorf("%v: %v", mv, err) + } + mc.modfiles[mv] = f + return f, nil +} diff --git a/vendor/cuelang.org/go/cue/load/search.go b/vendor/cuelang.org/go/cue/load/search.go index 3ac4981d35..aa370073a8 100644 --- a/vendor/cuelang.org/go/cue/load/search.go +++ b/vendor/cuelang.org/go/cue/load/search.go @@ -21,6 +21,7 @@ import ( "path/filepath" "strings" + "cuelang.org/go/cue/ast" "cuelang.org/go/cue/build" "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" @@ -143,6 +144,9 @@ func (l *loader) matchPackagesInFS(pattern, pkgName string) *match { // Could be smarter but this one optimization // is enough for now, since ... is usually at the // end of a path. + // + // TODO this logic entirely ignores the pattern that's + // after the "...". See cuelang.org/issue/3212 i := strings.Index(pattern, "...") dir, _ := path.Split(pattern[:i]) @@ -242,15 +246,13 @@ func (l *loader) importPathsQuiet(patterns []string) []*match { orig := a pkgName := l.cfg.Package - switch p := strings.IndexByte(a, ':'); { - case p < 0: - case p == 0: - pkgName = a[1:] - a = "." - default: - pkgName = a[p+1:] - a = a[:p] + ip := ast.ParseImportPath(a) + if ip.ExplicitQualifier { + pkgName = ip.Qualifier } + ip.Qualifier = "" + ip.ExplicitQualifier = false + a = ip.String() if pkgName == "*" { pkgName = "" } @@ -311,7 +313,7 @@ func appendExpandedPackageArg(c *Config, pkgPaths []resolvedPackageArg, p string // in command-line arguments. Handles .\... and so on. p = filepath.ToSlash(p) - ip := module.ParseImportPath(p) + ip := ast.ParseImportPath(p) if ip.Qualifier == "_" { return nil, fmt.Errorf("invalid import path qualifier _ in %q", origp) } @@ -338,7 +340,7 @@ func appendExpandedPackageArg(c *Config, pkgPaths []resolvedPackageArg, p string if err != nil { return nil, err } - ip1 := module.ParseImportPath(string(pkgPath)) + ip1 := ast.ParseImportPath(string(pkgPath)) // Leave ip.Qualifier and ip.ExplicitQualifier intact. ip.Path = ip1.Path ip.Version = ip1.Version @@ -357,7 +359,7 @@ func appendExpandedPackageArg(c *Config, pkgPaths []resolvedPackageArg, p string // there's only one package in the current directory but the last // component of its package path does not match its name. return appendExpandedUnqualifiedPackagePath(pkgPaths, origp, ip, pkgQual, module.SourceLoc{ - FS: c.fileSystem.ioFS(moduleRoot), + FS: c.fileSystem.ioFS(moduleRoot, c.languageVersion()), Dir: ".", }, c.Module, tg) } @@ -370,7 +372,7 @@ func appendExpandedPackageArg(c *Config, pkgPaths []resolvedPackageArg, p string return nil, fmt.Errorf("pattern not allowed in external package path %q", origp) } return appendExpandedWildcardPackagePath(pkgPaths, ip, pkgQual, module.SourceLoc{ - FS: c.fileSystem.ioFS(moduleRoot), + FS: c.fileSystem.ioFS(moduleRoot, c.languageVersion()), Dir: ".", }, c.Module, tg) } @@ -388,7 +390,7 @@ func appendExpandedPackageArg(c *Config, pkgPaths []resolvedPackageArg, p string // 5. if there's more than one package in the directory, it returns a MultiplePackageError. // 6. if there are no package files in the directory, it just appends the import path as is, leaving it // to later logic to produce an error in this case. -func appendExpandedUnqualifiedPackagePath(pkgPaths []resolvedPackageArg, origp string, ip module.ImportPath, pkgQual string, mainModRoot module.SourceLoc, mainModPath string, tg *tagger) (_ []resolvedPackageArg, _err error) { +func appendExpandedUnqualifiedPackagePath(pkgPaths []resolvedPackageArg, origp string, ip ast.ImportPath, pkgQual string, mainModRoot module.SourceLoc, mainModPath string, tg *tagger) ([]resolvedPackageArg, error) { ipRel, ok := cutModulePrefix(ip, mainModPath) if !ok { // Should never happen. @@ -409,53 +411,46 @@ func appendExpandedUnqualifiedPackagePath(pkgPaths []resolvedPackageArg, origp s // 1. if pkgQual is "*", it appends all the packages present in the package directory. if pkgQual == "*" { wasAdded := make(map[string]bool) - iter(func(f modimports.ModuleFile, err error) bool { + for f, err := range iter { if err != nil { - _err = err - return false + return nil, err } if err := shouldBuildFile(f.Syntax, tg.tagIsSet); err != nil { // Later build logic should pick up and report the same error. - return true + continue } pkgName := f.Syntax.PackageName() if wasAdded[pkgName] { - return true + continue } wasAdded[pkgName] = true ip := ip ip.Qualifier = pkgName p := ip.String() pkgPaths = append(pkgPaths, resolvedPackageArg{p, p}) - return true - }) - if _err != nil { - return nil, _err } return pkgPaths, nil } var files []modimports.ModuleFile foundQualifier := false - // TODO(rog): for f, err := range iter { - iter(func(f modimports.ModuleFile, err error) bool { + for f, err := range iter { if err != nil { - _err = err - return false + return nil, err + } + if err := shouldBuildFile(f.Syntax, tg.tagIsSet); err != nil { + // Later build logic should pick up and report the same error. + continue } pkgName := f.Syntax.PackageName() // 2. if pkgQual is "_", it looks for a package file with no package name. // 3. if there's a package named after ip.Qualifier it chooses that if (pkgName != "" && pkgName == ip.Qualifier) || (pkgQual == "_" && pkgName == "") { foundQualifier = true - return false + break } if pkgName != "" { files = append(files, f) } - return true - }) - if _err != nil { - return nil, _err } if foundQualifier { // We found the actual package that was implied by the import path (or pkgQual == "_"). @@ -492,15 +487,23 @@ func appendExpandedUnqualifiedPackagePath(pkgPaths []resolvedPackageArg, origp s // Note: // * We know that pattern contains "..." // * We know that pattern is relative to the module root -func appendExpandedWildcardPackagePath(pkgPaths []resolvedPackageArg, pattern module.ImportPath, pkgQual string, mainModRoot module.SourceLoc, mainModPath string, tg *tagger) (_ []resolvedPackageArg, _err error) { - modIpath := module.ParseImportPath(mainModPath) +// +// Note: this logic matches the logic in [loader.loadImportPathsQuiet]. +// TODO de-duplicate the logic so wildcards are expanded exactly once using a single piece of logic. +func appendExpandedWildcardPackagePath(pkgPaths []resolvedPackageArg, pattern ast.ImportPath, pkgQual string, mainModRoot module.SourceLoc, mainModPath string, tg *tagger) ([]resolvedPackageArg, error) { + modIpath := ast.ParseImportPath(mainModPath) // Find directory to begin the scan. // Could be smarter but this one optimization is enough for now, // since ... is usually at the end of a path. - // TODO: strip package qualifier. + // + // TODO this logic entirely ignores the pattern that's + // after the "...". See cuelang.org/issue/3212 i := strings.Index(pattern.Path, "...") dir, _ := path.Split(pattern.Path[:i]) dir = path.Join(mainModRoot.Dir, dir) + if pattern.ExplicitQualifier { + pkgQual = pattern.Qualifier + } var isSelected func(string) bool switch pkgQual { case "_": @@ -524,24 +527,23 @@ func appendExpandedWildcardPackagePath(pkgPaths []resolvedPackageArg, pattern mo } var prevFile modimports.ModuleFile - var prevImportPath module.ImportPath - iter := modimports.AllModuleFiles(mainModRoot.FS, dir) - iter(func(f modimports.ModuleFile, err error) bool { + var prevImportPath ast.ImportPath + for f, err := range modimports.AllModuleFiles(mainModRoot.FS, dir) { if err != nil { - return false + break } if err := shouldBuildFile(f.Syntax, tg.tagIsSet); err != nil { // Later build logic should pick up and report the same error. - return true + continue } pkgName := f.Syntax.PackageName() if !isSelected(pkgName) { - return true + continue } if pkgName == "" { pkgName = "_" } - ip := module.ImportPath{ + ip := ast.ImportPath{ Path: path.Join(modIpath.Path, path.Dir(f.FilePath)), Qualifier: pkgName, Version: modIpath.Version, @@ -555,7 +557,6 @@ func appendExpandedWildcardPackagePath(pkgPaths []resolvedPackageArg, pattern mo if ip == prevImportPath { // TODO(rog): this isn't sufficient for full deduplication: we can get an alternation of different // package names within the same directory. We'll need to maintain a map. - return true } if pkgQual == "" { // Note: we can look at the previous item only rather than maintaining a map @@ -564,7 +565,7 @@ func appendExpandedWildcardPackagePath(pkgPaths []resolvedPackageArg, pattern mo if prevFile.FilePath != "" && prevImportPath.Path == ip.Path && ip.Qualifier != prevImportPath.Qualifier { // A wildcard isn't currently allowed to match multiple packages // in a single directory. - _err = &MultiplePackageError{ + return nil, &MultiplePackageError{ Dir: path.Dir(f.FilePath), Packages: []string{prevImportPath.Qualifier, ip.Qualifier}, Files: []string{ @@ -572,40 +573,35 @@ func appendExpandedWildcardPackagePath(pkgPaths []resolvedPackageArg, pattern mo path.Base(f.FilePath), }, } - return false } } pkgPaths = append(pkgPaths, resolvedPackageArg{ip.String(), ip.String()}) prevFile, prevImportPath = f, ip - return true - }) - return pkgPaths, _err + } + return pkgPaths, nil } // cutModulePrefix strips the given module path from p and reports whether p is inside mod. // It returns a relative package path within m. // // If p does not contain a major version suffix but otherwise matches mod, it counts as a match. -func cutModulePrefix(p module.ImportPath, mod string) (module.ImportPath, bool) { +func cutModulePrefix(p ast.ImportPath, mod string) (ast.ImportPath, bool) { if mod == "" { return p, true } - modPath, modVers, ok := module.SplitPathVersion(mod) - if !ok { - modPath = mod - } + modPath, modVers, _ := ast.SplitPackageVersion(mod) if !strings.HasPrefix(p.Path, modPath) { - return module.ImportPath{}, false + return ast.ImportPath{}, false } if p.Path == modPath { p.Path = "." return p, true } if p.Path[len(modPath)] != '/' { - return module.ImportPath{}, false + return ast.ImportPath{}, false } if p.Version != "" && modVers != "" && p.Version != modVers { - return module.ImportPath{}, false + return ast.ImportPath{}, false } p.Path = "." + p.Path[len(modPath):] p.Version = "" diff --git a/vendor/cuelang.org/go/cue/load/tags.go b/vendor/cuelang.org/go/cue/load/tags.go index 32e64f15a6..cfd008c9d2 100644 --- a/vendor/cuelang.org/go/cue/load/tags.go +++ b/vendor/cuelang.org/go/cue/load/tags.go @@ -83,14 +83,12 @@ type TagVar struct { Description string } -const rfc3339 = "2006-01-02T15:04:05.999999999Z" - // DefaultTagVars creates a new map with a set of supported injection variables. func DefaultTagVars() map[string]TagVar { return map[string]TagVar{ "now": { Func: func() (ast.Expr, error) { - return ast.NewString(time.Now().UTC().Format(rfc3339)), nil + return ast.NewString(time.Now().UTC().Format(time.RFC3339Nano)), nil }, }, "os": { @@ -125,10 +123,7 @@ func DefaultTagVars() map[string]TagVar { "rand": { Func: func() (ast.Expr, error) { var b [16]byte - _, err := rand.Read(b[:]) - if err != nil { - return nil, err - } + rand.Read(b[:]) var hx [34]byte hx[0] = '0' hx[1] = 'x' @@ -143,8 +138,7 @@ func varToString(s string, err error) (ast.Expr, error) { if err != nil { return nil, err } - x := ast.NewString(s) - return x, nil + return ast.NewString(s), nil } // A tag binds an identifier to a field to allow passing command-line values. @@ -201,7 +195,7 @@ func parseTag(pos token.Pos, body string) (t *tag, err errors.Error) { } if s, ok, _ := a.Lookup(1, "short"); ok { - for _, s := range strings.Split(s, "|") { + for s := range strings.SplitSeq(s, "|") { if !ast.IsValidIdent(t.key) { return t, errors.Newf(pos, "invalid identifier %q", s) } @@ -262,8 +256,7 @@ func findTags(b *build.Instance) (tags []*tag, errs errors.Error) { case *ast.Field: // TODO: allow optional fields? _, _, err := ast.LabelName(x.Label) - _, ok := internal.ConstraintToken(x) - if err != nil || ok { + if err != nil || x.Constraint != token.ILLEGAL { findInvalidTags(n, "@tag not allowed within field constraint") return false } @@ -291,19 +284,19 @@ func findTags(b *build.Instance) (tags []*tag, errs errors.Error) { func (tg *tagger) injectTags(tags []string) errors.Error { // Parses command line args for _, s := range tags { - p := strings.Index(s, "=") + name, val, ok := strings.Cut(s, "=") found := tg.usedTags[s] - if p > 0 { // key-value + if ok { // key-value for _, t := range tg.tags { - if t.key == s[:p] { + if t.key == name { found = true - if err := t.inject(s[p+1:], tg); err != nil { + if err := t.inject(val, tg); err != nil { return err } } } if !found { - return errors.Newf(token.NoPos, "no tag for %q", s[:p]) + return errors.Newf(token.NoPos, "no tag for %q", name) } } else { // shorthand for _, t := range tg.tags { diff --git a/vendor/cuelang.org/go/cue/marshal.go b/vendor/cuelang.org/go/cue/marshal.go index 8c2561d851..19505ed969 100644 --- a/vendor/cuelang.org/go/cue/marshal.go +++ b/vendor/cuelang.org/go/cue/marshal.go @@ -19,10 +19,10 @@ import ( "compress/gzip" "encoding/gob" "path/filepath" + "strconv" "strings" "cuelang.org/go/cue/ast" - "cuelang.org/go/cue/ast/astutil" "cuelang.org/go/cue/build" "cuelang.org/go/cue/errors" "cuelang.org/go/cue/format" @@ -59,7 +59,7 @@ func (b *unmarshaller) load(pos token.Pos, path string) *build.Instance { } func (b *unmarshaller) build(bi *instanceData) *build.Instance { - p := b.ctxt.NewInstance(bi.Path, b.load) + p := b.ctxt.NewInstance(bi.Path, nil) p.ImportPath = bi.Path for _, f := range bi.Files { _ = p.AddFile(f.Name, f.Data) @@ -70,9 +70,9 @@ func (b *unmarshaller) build(bi *instanceData) *build.Instance { func compileInstances(r *Runtime, data []*instanceData) (instances []*Instance, err error) { b := unmarshaller{ - ctxt: build.NewContext(), imports: map[string]*instanceData{}, } + b.ctxt = build.NewContext(build.Loader(b.load)) for _, i := range data { if i.Path == "" { if !i.Root { @@ -143,15 +143,13 @@ func (r *Runtime) Marshal(values ...InstanceOrValue) (b []byte, err error) { // TODO: support exporting instance file, _ := export.Def(r.runtime(), inst.ID(), i.instance().root) imports := []string{} - file.VisitImports(func(i *ast.ImportDecl) { - for _, spec := range i.Specs { - info, _ := astutil.ParseImportSpec(spec) - imports = append(imports, info.ID) - } - }) + for spec := range file.ImportSpecs() { + path, _ := strconv.Unquote(spec.Path.Value) + imports = append(imports, path) + } if inst.PkgName != "" { - if pkg := internal.Package(file); pkg == nil { + if pkg, _ := internal.Package(file); pkg == nil { pkg := &ast.Package{Name: ast.NewIdent(inst.PkgName)} file.Decls = append([]ast.Decl{pkg}, file.Decls...) } else if pkg.Name.Name != inst.PkgName { diff --git a/vendor/cuelang.org/go/cue/op.go b/vendor/cuelang.org/go/cue/op.go index 6f08e4e04a..6e0a46d662 100644 --- a/vendor/cuelang.org/go/cue/op.go +++ b/vendor/cuelang.org/go/cue/op.go @@ -58,4 +58,6 @@ const ( IntModuloOp Op = adt.IntModuloOp InterpolationOp Op = adt.InterpolationOp + + SpreadOp Op = adt.SpreadOp ) diff --git a/vendor/cuelang.org/go/cue/parser/interface.go b/vendor/cuelang.org/go/cue/parser/interface.go index 337f225289..c3a07d18ba 100644 --- a/vendor/cuelang.org/go/cue/parser/interface.go +++ b/vendor/cuelang.org/go/cue/parser/interface.go @@ -17,85 +17,156 @@ package parser import ( + "fmt" + "cuelang.org/go/cue/ast" "cuelang.org/go/cue/ast/astutil" "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" - "cuelang.org/go/internal" + "cuelang.org/go/internal/cueversion" + "cuelang.org/go/internal/mod/semver" "cuelang.org/go/internal/source" ) // Option specifies a parse option. -type Option func(p *parser) +type Option interface { + apply(cfg *Config) +} -var ( - // PackageClauseOnly causes parsing to stop after the package clause. - PackageClauseOnly Option = packageClauseOnly - packageClauseOnly = func(p *parser) { - p.mode |= packageClauseOnlyMode +var _ Option = Config{} + +// Config represents the end result of applying a set of options. +// The zero value is not OK to use: use [NewConfig] to construct +// a Config value before using it. +// +// Config itself implements [Option] by overwriting the +// entire configuration. +// +// Config is comparable. +type Config struct { + // valid is set by NewConfig and is used to check + // that a Config has been created correctly. + valid bool + + // Mode holds a bitmask of boolean parser options. + Mode Mode + + // Version holds the language version to use when + // parsing the CUE syntax. + Version string +} + +// Ensure that Config is comparable. +var _ = Config{} == Config{} + +// apply implements [Option] +func (cfg Config) apply(cfg1 *Config) { + if !cfg.valid { + panic("zero parser.Config value used; use parser.NewConfig!") } + *cfg1 = cfg +} - // ImportsOnly causes parsing to stop parsing after the import declarations. - ImportsOnly Option = importsOnly - importsOnly = func(p *parser) { - p.mode |= importsOnlyMode +// NewConfig returns the configuration containing all default values +// with the given options applied. +func NewConfig(opts ...Option) Config { + return Config{ + valid: true, + Version: cueversion.LanguageVersion(), + }.Apply(opts...) +} + +// Apply applies all the given options to cfg and +// returns the resulting configuration. +func (cfg Config) Apply(opts ...Option) Config { + for _, opt := range opts { + opt.apply(&cfg) } + return cfg +} + +// IsValid reports whether cfg is valid; that +// is, it has been created with [NewConfig]. +func (cfg Config) IsValid() bool { + return cfg.valid +} + +// optionFunc implements [Option] for a function. +type optionFunc func(cfg *Config) + +func (f optionFunc) apply(cfg *Config) { + f(cfg) +} + +// A Mode value is a set of flags (or 0). +// It controls the amount of source code parsed and other optional +// parser functionality. +// +// Mode implements [Option] by or-ing all its bits +// with [Config.Mode]. +type Mode uint + +const ( + // PackageClauseOnly causes parsing to stop after the package clause. + PackageClauseOnly Mode = 1 << iota + + // ImportsOnly causes parsing to stop parsing after the import declarations. + ImportsOnly // ParseComments causes comments to be parsed. - ParseComments Option = parseComments - parseComments = func(p *parser) { - p.mode |= parseCommentsMode - } + ParseComments // ParseFuncs causes function declarations to be parsed. // // This is an experimental function and the API is likely to // change or dissapear. - ParseFuncs Option = parseFuncs - parseFuncs = func(p *parser) { - p.mode |= parseFuncsMode - } + ParseFuncs // Trace causes parsing to print a trace of parsed productions. - Trace Option = traceOpt - traceOpt = func(p *parser) { - p.mode |= traceMode - } + Trace // DeclarationErrors causes parsing to report declaration errors. - DeclarationErrors Option = declarationErrors - declarationErrors = func(p *parser) { - p.mode |= declarationErrorsMode - } + DeclarationErrors // AllErrors causes all errors to be reported (not just the first 10 on different lines). - AllErrors Option = allErrors - allErrors = func(p *parser) { - p.mode |= allErrorsMode - } + AllErrors // AllowPartial allows the parser to be used on a prefix buffer. - AllowPartial Option = allowPartial - allowPartial = func(p *parser) { - p.mode |= partialMode - } + AllowPartial ) +// apply implements [Option]. +func (m Mode) apply(c *Config) { + c.Mode |= m +} + +// Version specifies the language version to use when parsing +// the CUE. The argument must be a valid semantic version, as +// checked by [semver.IsValid]. +// +// The version will be recorded in the [ast.File] returned +// from [ParseFile]. +func Version(v string) Option { + if !semver.IsValid(v) { + panic(fmt.Errorf("invalid language version %q", v)) + } + return optionFunc(func(c *Config) { + c.Version = v + }) +} + // FromVersion specifies until which legacy version the parser should provide // backwards compatibility. +// +// Deprecated: use [Version] instead. func FromVersion(version int) Option { - if version >= 0 { - version++ - } - // Versions: - // <0: major version 0 (counting -1000 + x, where x = 100*m+p in 0.m.p - // >=0: x+1 in 1.x.y - return func(p *parser) { p.version = version } + return optionFunc(func(cfg *Config) {}) } // DeprecationError is a sentinel error to indicate that an error is // related to an unsupported old CUE syntax. type DeprecationError struct { + // Deprecated: version integers have been replaced by language versions as semver strings. Version int } @@ -104,42 +175,20 @@ func (e *DeprecationError) Error() string { } const ( - // Latest specifies the latest version of the parser, effectively setting - // the strictest implementation. - Latest = latest + // Deprecated: see [Version]. + Latest = 0 - latest = -1000 + (100 * internal.MinorCurrent) + 0 - - // FullBackwardCompatibility enables all deprecated features that are - // currently still supported by the parser. - FullBackwardCompatibility = fullCompatibility - - fullCompatibility = -1000 + // Deprecated: see [Version]. + FullBackwardCompatibility = 0 ) // FileOffset specifies the File position info to use. // // Deprecated: this has no effect. func FileOffset(pos int) Option { - return func(p *parser) {} + return optionFunc(func(*Config) {}) } -// A mode value is a set of flags (or 0). -// They control the amount of source code parsed and other optional -// parser functionality. -type mode uint - -const ( - packageClauseOnlyMode mode = 1 << iota // stop parsing after package clause - importsOnlyMode // stop parsing after import declarations - parseCommentsMode // parse comments and add them to AST - parseFuncsMode // parse function declarations (experimental) - partialMode - traceMode // print a trace of parsed productions - declarationErrorsMode // report declaration errors - allErrorsMode // report all errors (not just the first 10 on different lines) -) - // ParseFile parses the source code of a single CUE source file and returns // the corresponding File node. The source code may be provided via // the filename of the source file, or via the src parameter. @@ -228,7 +277,7 @@ func ParseExpr(filename string, src interface{}, mode ...Option) (ast.Expr, erro if p.tok == token.COMMA && p.lit == "\n" { p.next() } - if p.mode&partialMode == 0 { + if p.cfg.Mode&AllowPartial == 0 { p.expect(token.EOF) } @@ -239,10 +288,3 @@ func ParseExpr(filename string, src interface{}, mode ...Option) (ast.Expr, erro return e, p.errors } - -// parseExprString is a convenience function for obtaining the AST of an -// expression x. The position information recorded in the AST is undefined. The -// filename used in error messages is the empty string. -func parseExprString(x string) (ast.Expr, error) { - return ParseExpr("", []byte(x)) -} diff --git a/vendor/cuelang.org/go/cue/parser/parser.go b/vendor/cuelang.org/go/cue/parser/parser.go index cc039cf954..4908c866d9 100644 --- a/vendor/cuelang.org/go/cue/parser/parser.go +++ b/vendor/cuelang.org/go/cue/parser/parser.go @@ -16,6 +16,7 @@ package parser import ( "fmt" + "slices" "strings" "unicode" @@ -25,6 +26,7 @@ import ( "cuelang.org/go/cue/scanner" "cuelang.org/go/cue/token" "cuelang.org/go/internal" + "cuelang.org/go/internal/cueexperiment" ) // The parser structure holds the parser's internal state. @@ -33,21 +35,34 @@ type parser struct { errors errors.Error scanner scanner.Scanner + expList []string // list of experiments to enable + experiments *cueexperiment.File + // Tracing/debugging - mode mode // parsing mode - trace bool // == (mode & Trace != 0) + cfg Config + trace bool // == (cfg.Mode & Trace != 0) panicking bool // set if we are bailing out due to too many errors. indent int // indentation used for tracing output // Comments - leadComment *ast.CommentGroup - comments *commentState + leadComment *ast.CommentGroup + comments *commentState + commentStack []*commentState // to reuse [commentState] allocations - // Next token + // Next token, filled by [parser.next0]. pos token.Pos // token position tok token.Token // one token look-ahead lit string // token literal + // Token after next, filled by [parser.peek]. + peekToken struct { + scanned bool + + pos token.Pos + tok token.Token + lit string + } + // Error recovery // (used to limit the number of calls to sync... functions // w/o making scanning progress - avoids potential endless @@ -59,18 +74,14 @@ type parser struct { exprLev int // < 0: in control clause, >= 0: in expression imports []*ast.ImportSpec // list of imports - - version int } -func (p *parser) init(filename string, src []byte, mode []Option) { - for _, f := range mode { - f(p) - } +func (p *parser) init(filename string, src []byte, opts []Option) { + p.cfg = NewConfig().Apply(opts...) p.file = token.NewFile(filename, -1, len(src)) var m scanner.Mode - if p.mode&parseCommentsMode != 0 { + if p.cfg.Mode&ParseComments != 0 { m = scanner.ScanComments } eh := func(pos token.Pos, msg string, args []interface{}) { @@ -78,7 +89,7 @@ func (p *parser) init(filename string, src []byte, mode []Option) { } p.scanner.Init(p.file, src, eh, m) - p.trace = p.mode&traceMode != 0 // for convenience (p.trace is used frequently) + p.trace = p.cfg.Mode&Trace != 0 // for convenience (p.trace is used frequently) p.comments = &commentState{pos: -1} @@ -98,11 +109,26 @@ type commentState struct { lastPos int8 } +func (p *parser) allocCommentState() *commentState { + if n := len(p.commentStack); n > 0 { + c := p.commentStack[n-1] + p.commentStack = p.commentStack[:n-1] + return c + } + return &commentState{} +} + +func (p *parser) freeCommentState(c *commentState) { + // Ensure no pointers remain, which can hold onto memory. + // We only reuse the groups slice capacity. + *c = commentState{groups: c.groups[:0]} + p.commentStack = append(p.commentStack, c) +} + // openComments reserves the next doc comment for the caller and flushes func (p *parser) openComments() *commentState { - child := &commentState{ - parent: p.comments, - } + child := p.allocCommentState() + child.parent = p.comments if c := p.comments; c != nil && c.isList > 0 { if c.lastChild != nil { var groups []*ast.CommentGroup @@ -119,16 +145,14 @@ func (p *parser) openComments() *commentState { } } ast.SetComments(c.lastChild, groups) - c.groups = nil } else { - c.lastChild = nil // attach before next for _, cg := range c.groups { cg.Position = 0 } - child.groups = c.groups - c.groups = nil + child.groups = append(child.groups, c.groups...) } + c.groups = c.groups[:0] } if p.leadComment != nil { child.groups = append(child.groups, p.leadComment) @@ -145,10 +169,9 @@ func (p *parser) openList() { p.comments.isList++ return } - c := &commentState{ - parent: p.comments, - isList: 1, - } + c := p.allocCommentState() + c.parent = p.comments + c.isList = 1 p.comments = c } @@ -164,7 +187,7 @@ func (p *parser) closeList() { cg.Position = c.lastPos ast.AddComment(c.lastChild, cg) } - c.groups = nil + c.groups = c.groups[:0] } switch c.isList--; { case c.isList < 0: @@ -181,6 +204,7 @@ func (p *parser) closeList() { } parent.pos++ p.comments = parent + p.freeCommentState(c) } } @@ -207,7 +231,7 @@ func (c *commentState) closeNode(p *parser, n ast.Node) ast.Node { } } } - c.groups = nil + p.freeCommentState(c) return n } @@ -269,9 +293,26 @@ func (p *parser) next0() { } } + // We had peeked one token, effectively scanning it early; use it now. + if p.peekToken.scanned { + p.pos, p.tok, p.lit = p.peekToken.pos, p.peekToken.tok, p.peekToken.lit + p.peekToken.scanned = false + return + } + p.pos, p.tok, p.lit = p.scanner.Scan() } +// peek scans one more token as a look-ahead and stores it in [parser.peekToken]. +// Peeking multiple tokens ahead is not supported. +func (p *parser) peek() { + if p.peekToken.scanned { + panic("can only peek one token at a time") + } + p.peekToken.pos, p.peekToken.tok, p.peekToken.lit = p.scanner.Scan() + p.peekToken.scanned = true +} + // Consume a comment and return it and the line on which it ends. func (p *parser) consumeComment() (comment *ast.Comment, endline int) { endline = p.file.Line(p.pos) @@ -374,19 +415,14 @@ func (p *parser) next() { } } -// assertV0 indicates the last version at which a certain feature was -// supported. -func (p *parser) assertV0(pos token.Pos, minor, patch int, name string) { - v := internal.Version(minor, patch) - base := p.version - if base == 0 { - base = internal.APIVersionSupported - } - if base > v { - p.errors = errors.Append(p.errors, - errors.Wrapf(&DeprecationError{v}, pos, - "use of deprecated %s (deprecated as of v0.%d.%d)", name, minor, patch+1)) - } +// errDeprecated causes an error due to the use of a deprecated language feature. +// Note that this is how language features used to get phased out; +// we now use CUE experiments driven by a module's language version, +// the CUE_EXPERIMENT environment variable, and the @experiment file attribute. +// TODO(mvdan): transition out of this entirely. +func (p *parser) errDeprecated(pos token.Pos, version, name string) { + p.errors = errors.Append(p.errors, errors.Wrapf(&DeprecationError{}, pos, + "use of deprecated %s (deprecated as of %s)", name, version)) } func (p *parser) errf(pos token.Pos, msg string, args ...interface{}) { @@ -396,7 +432,7 @@ func (p *parser) errf(pos token.Pos, msg string, args ...interface{}) { // If AllErrors is not set, discard errors reported on the same line // as the last recorded error and stop parsing if there are more than // 10 errors. - if p.mode&allErrorsMode == 0 { + if p.cfg.Mode&AllErrors == 0 { errors := errors.Errors(p.errors) n := len(errors) if n > 0 && errors[n-1].Position().Line() == ePos.Line() { @@ -466,10 +502,8 @@ func (p *parser) atComma(context string, follow ...token.Token) bool { if p.tok == token.COMMA { return true } - for _, t := range follow { - if p.tok == t { - return false - } + if slices.Contains(follow, p.tok) { + return false } // TODO: find a way to detect crossing lines now we don't have a semi. if p.lit == "\n" { @@ -497,7 +531,7 @@ func syncExpr(p *parser) { p.syncCnt++ return } - if p.syncPos.Before(p.pos) { + if p.syncPos.Compare(p.pos) < 0 { p.syncPos = p.pos p.syncCnt = 0 return @@ -551,6 +585,22 @@ func (p *parser) parseIdent() *ast.Ident { return ident } +// checkDeclIdent validates that an identifier is not a reserved +// double-underscore identifier. Use this when an identifier is being declared. +func (p *parser) checkDeclIdent(ident *ast.Ident) { + if strings.HasPrefix(ident.Name, "__") { + p.errf(ident.NamePos, "identifiers starting with '__' are reserved") + } +} + +// parseIdentDecl parses an identifier and validates that it's not a reserved +// double-underscore identifier. Use this for identifier declarations. +func (p *parser) parseIdentDecl() *ast.Ident { + ident := p.parseIdent() + p.checkDeclIdent(ident) + return ident +} + func (p *parser) parseKeyIdent() *ast.Ident { c := p.openComments() pos := p.pos @@ -582,7 +632,7 @@ func (p *parser) parseOperand() (expr ast.Expr) { return p.parseList() case token.FUNC: - if p.mode&parseFuncsMode != 0 { + if p.cfg.Mode&ParseFuncs != 0 { return p.parseFunc() } else { return p.parseKeyIdent() @@ -728,7 +778,7 @@ func (p *parser) parseFieldList() (list []ast.Decl) { for p.tok != token.RBRACE && p.tok != token.EOF { switch p.tok { case token.ATTRIBUTE: - list = append(list, p.parseAttribute()) + list = append(list, p.parseAttribute(false)) p.consumeDeclComma() case token.ELLIPSIS: @@ -767,7 +817,7 @@ func (p *parser) parseLetDecl() (decl ast.Decl, ident *ast.Ident) { } defer func() { c.closeNode(p, decl) }() - ident = p.parseIdent() + ident = p.parseIdentDecl() assign := p.expect(token.BIND) expr := p.parseRHS() @@ -841,7 +891,7 @@ func (p *parser) parseField() (decl ast.Decl) { expr = p.parseRHS() } if a, ok := expr.(*ast.Alias); ok { - p.assertV0(a.Pos(), 1, 3, `old-style alias; use "let X = expr" instead`) + p.errDeprecated(a.Pos(), "v0.1.4", `old-style alias; use "let X = expr" instead`) p.consumeDeclComma() return a } @@ -850,6 +900,9 @@ func (p *parser) parseField() (decl ast.Decl) { return e } + // Parse postfix alias if present + m.Alias = p.parsePostfixAlias() + switch p.tok { case token.OPTION, token.NOT: m.Optional = p.pos @@ -865,13 +918,17 @@ func (p *parser) parseField() (decl ast.Decl) { switch p.tok { case token.COLON: + // Now we know it's being used as a label, validate double-underscore + if ident, ok := label.(*ast.Ident); ok { + p.checkDeclIdent(ident) + } case token.COMMA: p.expectComma() // sync parser. fallthrough case token.RBRACE, token.EOF: if a, ok := expr.(*ast.Alias); ok { - p.assertV0(a.Pos(), 1, 3, `old-style alias; use "let X = expr" instead`) + p.errDeprecated(a.Pos(), "v0.1.4", `old-style alias; use "let X = expr" instead`) return a } switch tok { @@ -901,7 +958,7 @@ func (p *parser) parseField() (decl ast.Decl) { } label, expr, _, ok := p.parseLabel(true) - if !ok || (p.tok != token.COLON && p.tok != token.OPTION && p.tok != token.NOT) { + if !ok || (p.tok != token.COLON && p.tok != token.OPTION && p.tok != token.NOT && p.tok != token.TILDE) { if expr == nil { expr = p.parseRHS() } @@ -912,6 +969,9 @@ func (p *parser) parseField() (decl ast.Decl) { m.Value = &ast.StructLit{Elts: []ast.Decl{field}} m = field + // Parse postfix alias if present + m.Alias = p.parsePostfixAlias() + switch p.tok { case token.OPTION, token.NOT: m.Optional = p.pos @@ -944,15 +1004,22 @@ func (p *parser) parseField() (decl ast.Decl) { func (p *parser) parseAttributes() (attrs []*ast.Attribute) { p.openList() for p.tok == token.ATTRIBUTE { - attrs = append(attrs, p.parseAttribute()) + attrs = append(attrs, p.parseAttribute(false)) } p.closeList() return attrs } -func (p *parser) parseAttribute() *ast.Attribute { +func (p *parser) parseAttribute(inPreamble bool) *ast.Attribute { c := p.openComments() a := &ast.Attribute{At: p.pos, Text: p.lit} + + if inPreamble { + key, body := a.Split() + if key == "experiment" { + p.expList = append(p.expList, body) + } + } p.next() c.closeNode(p, a) return a @@ -1007,10 +1074,6 @@ func (p *parser) parseLabel(rhs bool) (label ast.Label, expr ast.Expr, decl ast. } case *ast.Ident: - if strings.HasPrefix(x.Name, "__") && !rhs { - p.errf(x.NamePos, "identifiers starting with '__' are reserved") - } - expr = p.parseAlias(x) if a, ok := expr.(*ast.Alias); ok { if _, ok = a.Expr.(ast.Label); !ok { @@ -1083,7 +1146,7 @@ func (p *parser) parseComprehensionClauses(first bool) (clauses []ast.Clause, c forPos := p.expect(token.FOR) if first { switch p.tok { - case token.COLON, token.BIND, token.OPTION, + case token.COLON, token.BIND, token.OPTION, token.NOT, token.COMMA, token.EOF: return nil, c } @@ -1091,11 +1154,11 @@ func (p *parser) parseComprehensionClauses(first bool) (clauses []ast.Clause, c var key, value *ast.Ident var colon token.Pos - value = p.parseIdent() + value = p.parseIdentDecl() if p.tok == token.COMMA { colon = p.expect(token.COMMA) key = value - value = p.parseIdent() + value = p.parseIdentDecl() } c.pos = 4 // params := p.parseParams(nil, ARROW) @@ -1116,6 +1179,11 @@ func (p *parser) parseComprehensionClauses(first bool) (clauses []ast.Clause, c case token.COLON, token.BIND, token.OPTION, token.COMMA, token.EOF: return nil, c + case token.NOT: + p.peek() + if p.peekToken.tok == token.COLON { + return nil, c + } } } @@ -1128,7 +1196,7 @@ func (p *parser) parseComprehensionClauses(first bool) (clauses []ast.Clause, c c := p.openComments() letPos := p.expect(token.LET) - ident := p.parseIdent() + ident := p.parseIdentDecl() assign := p.expect(token.BIND) expr := p.parseRHS() @@ -1320,6 +1388,15 @@ func (p *parser) parseAlias(lhs ast.Expr) (expr ast.Expr) { return lhs } pos := p.pos + + // Check if old-style aliases are disallowed + if p.experiments != nil && p.experiments.AliasV2 { + p.errf(pos, "old-style alias syntax (=) is not allowed with @experiment(aliasv2); use postfix syntax (~X or ~(K,V))") + p.next() + expr = p.parseRHS() + return expr + } + p.next() expr = p.parseRHS() if expr == nil { @@ -1327,12 +1404,95 @@ func (p *parser) parseAlias(lhs ast.Expr) (expr ast.Expr) { } switch x := lhs.(type) { case *ast.Ident: + p.checkDeclIdent(x) return &ast.Alias{Ident: x, Equal: pos, Expr: expr} } p.errf(p.pos, "expected identifier for alias") return expr } +// parsePostfixAlias parses the postfix alias syntax: ~X or ~(K,V) +// Returns nil if no alias is present. +func (p *parser) parsePostfixAlias() *ast.PostfixAlias { + if p.tok != token.TILDE { + return nil + } + + pos := p.pos + + // Check if postfix alias syntax requires experiment + if p.experiments == nil || !p.experiments.AliasV2 { + p.errf(pos, "postfix alias syntax requires @experiment(aliasv2)") + } + + p.next() + + switch p.tok { + case token.LPAREN: + // Dual form: ~(K,V) + lparen := p.pos + p.next() + + if p.tok != token.IDENT { + p.errorExpected(p.pos, "identifier for label alias") + return nil + } + k := p.parseIdent() + + comma := p.pos + if p.tok != token.COMMA { + p.errorExpected(p.pos, "','") + // Recovery: treat as simple form with just K + return &ast.PostfixAlias{ + Tilde: pos, + Field: k, + } + } + p.next() + + if p.tok != token.IDENT { + p.errorExpected(p.pos, "identifier for field alias") + // Recovery: return what we have + return &ast.PostfixAlias{ + Tilde: pos, + Lparen: lparen, + Label: k, + Comma: comma, + Field: k, // Use K as field too for recovery + } + } + v := p.parseIdent() + + rparen := p.pos + if p.tok != token.RPAREN { + p.errorExpected(p.pos, "')'") + } else { + p.next() + } + + return &ast.PostfixAlias{ + Tilde: pos, + Lparen: lparen, + Label: k, + Comma: comma, + Field: v, + Rparen: rparen, + } + + case token.IDENT: + // Simple form: ~X + ident := p.parseIdent() + return &ast.PostfixAlias{ + Tilde: pos, + Field: ident, + } + + default: + p.errorExpected(p.pos, "identifier or '('") + return nil + } +} + // checkExpr checks that x is an expression (and not a type). func (p *parser) checkExpr(x ast.Expr) ast.Expr { switch unparen(x).(type) { @@ -1352,6 +1512,7 @@ func (p *parser) checkExpr(x ast.Expr) ast.Expr { case *ast.CallExpr: case *ast.UnaryExpr: case *ast.BinaryExpr: + case *ast.PostfixExpr: default: // all other nodes are not proper expressions p.errorExpected(x.Pos(), "expression") @@ -1428,6 +1589,25 @@ L: x = p.parseIndexOrSlice(p.checkExpr(x)) case token.LPAREN: x = p.parseCallOrConversion(p.checkExpr(x)) + case token.ELLIPSIS: + if p.experiments.ExplicitOpen { + pos := p.pos + c := p.openComments() + p.next() + x = c.closeExpr(p, &ast.PostfixExpr{ + X: p.checkExpr(x), + Op: token.ELLIPSIS, + OpPos: pos, + }) + } else { + // Consume the token and give a clear error + pos := p.pos + p.next() + err := errors.Newf(pos, "postfix ... operator requires @experiment(explicitopen)") + p.errors = errors.Append(p.errors, err) + // Return a BadExpr to continue parsing + x = &ast.BadExpr{From: pos, To: p.pos} + } default: break L } @@ -1443,6 +1623,11 @@ func (p *parser) parseUnaryExpr() ast.Expr { } switch p.tok { + case token.EQL: + if !p.experiments.StructCmp { + break + } + fallthrough case token.ADD, token.SUB, token.NOT, token.MUL, token.LSS, token.LEQ, token.GEQ, token.GTR, token.NEQ, token.MAT, token.NMAT: @@ -1522,7 +1707,9 @@ func (p *parser) parseInterpolation() (expr ast.Expr) { last := &ast.BasicLit{ValuePos: pos, Kind: token.STRING, Value: lit} exprs := []ast.Expr{last} - for p.tok == token.LPAREN { + // Note: we can only tell if the string returned by ResumeInterpolation + // starts a new interpolated expression by whether it ends in a parenthesis. + for strings.HasSuffix(last.Value, "(") { c.pos = 1 p.expect(token.LPAREN) cc.closeExpr(p, last) @@ -1590,7 +1777,10 @@ func (p *parser) parseImportSpec(_ int) *ast.ImportSpec { var ident *ast.Ident if p.tok == token.IDENT { - ident = p.parseIdent() + ident = p.parseIdentDecl() + if internal.IsDef(ident.Name) { + p.errf(p.pos, "cannot import package as definition identifier") + } } pos := p.pos @@ -1672,10 +1862,21 @@ func (p *parser) parseFile() *ast.File { var decls []ast.Decl for p.tok == token.ATTRIBUTE { - decls = append(decls, p.parseAttribute()) + decls = append(decls, p.parseAttribute(true)) p.consumeDeclComma() } + v := p.cfg.Version + exp, err := cueexperiment.NewFile(v, p.expList...) + if err != nil { + e := errors.Wrapf(err, p.pos, "parsing experiments for version %q", v) + p.errors = errors.Append(p.errors, e) + // Do not proceed without setting p.experiments. + return nil + } + p.experiments = exp + p.file.SetExperiments(exp) + // The package clause is not a declaration: it does not appear in any // scope. if p.tok == token.IDENT && p.lit == "package" { @@ -1685,10 +1886,12 @@ func (p *parser) parseFile() *ast.File { var name *ast.Ident p.expect(token.IDENT) name = p.parseIdent() - if name.Name == "_" && p.mode&declarationErrorsMode != 0 { + if name.Name == "_" && p.cfg.Mode&DeclarationErrors != 0 { p.errf(p.pos, "invalid package name _") } - + if internal.IsDef(name.Name) { + p.errf(p.pos, "invalid package name %s", name.Name) + } pkg := &ast.Package{ PackagePos: pos, Name: name, @@ -1699,17 +1902,17 @@ func (p *parser) parseFile() *ast.File { } for p.tok == token.ATTRIBUTE { - decls = append(decls, p.parseAttribute()) + decls = append(decls, p.parseAttribute(false)) p.consumeDeclComma() } - if p.mode&packageClauseOnlyMode == 0 { + if p.cfg.Mode&PackageClauseOnly == 0 { // import decls for p.tok == token.IDENT && p.lit == "import" { decls = append(decls, p.parseImports()) } - if p.mode&importsOnlyMode == 0 { + if p.cfg.Mode&ImportsOnly == 0 { // rest of package decls // TODO: loop and allow multiple expressions. decls = append(decls, p.parseFieldList()...) @@ -1719,8 +1922,9 @@ func (p *parser) parseFile() *ast.File { p.closeList() f := &ast.File{ - Imports: p.imports, - Decls: decls, + Imports: p.imports, + Decls: decls, + LanguageVersion: p.cfg.Version, } c.closeNode(p, f) return f diff --git a/vendor/cuelang.org/go/cue/path.go b/vendor/cuelang.org/go/cue/path.go index 26d174221b..60a4e758f9 100644 --- a/vendor/cuelang.org/go/cue/path.go +++ b/vendor/cuelang.org/go/cue/path.go @@ -25,8 +25,10 @@ import ( "cuelang.org/go/cue/literal" "cuelang.org/go/cue/parser" "cuelang.org/go/cue/token" + "cuelang.org/go/internal" "cuelang.org/go/internal/astinternal" "cuelang.org/go/internal/core/adt" + "cuelang.org/go/internal/core/runtime" "github.com/cockroachdb/apd/v3" ) @@ -138,6 +140,28 @@ func (sel Selector) String() string { return sel.sel.String() } +// ErrNotAPattern is a sentinel error value indicating that a value is not a +// pattern, which may be returned by [Selector.Pattern]. +var ErrNotAPattern = newErrValue( + Value{idx: runtime.New()}, + &adt.Bottom{ + Err: errors.Newf(token.NoPos, "selector is not a pattern"), + Code: adt.EvalError, + }, +) + +// Pattern returns the label pattern for a pattern constraint selector +// returned by an iterator with the [Patterns] option enabled. +// +// For other selectors, it returns [ErrNotAPattern]. +func (sel Selector) Pattern() Value { + switch sel := sel.sel.(type) { + case patternSelector: + return sel.pattern + } + return ErrNotAPattern +} + // Unquoted returns the unquoted value of a string label. // It panics unless [Selector.LabelType] is [StringLabel] and has a concrete name. func (sel Selector) Unquoted() string { @@ -275,6 +299,11 @@ func pathToStrings(p Path) (a []string) { return a } +// Append adds sel as a path component to p. +func (p Path) Append(sel ...Selector) Path { + return Path{path: append(p.path, sel...)} +} + // ParsePath parses a CUE expression into a Path. Any error resulting from // this conversion can be obtained by calling Err on the result. // @@ -463,10 +492,6 @@ func (p Path) Err() error { return errs } -func isHiddenOrDefinition(s string) bool { - return strings.HasPrefix(s, "#") || strings.HasPrefix(s, "_") -} - // Hid returns a selector for a hidden field. It panics if pkg is empty. // Hidden fields are scoped by package, and pkg indicates for which package // the hidden field must apply. For anonymous packages, it must be set to "_". @@ -505,11 +530,11 @@ func (s scopedSelector) feature(r adt.Runtime) adt.Feature { return adt.MakeIdentLabel(r, s.name, s.pkg) } -// A Def marks a string as a definition label. An # will be added if a string is +// Def marks a string as a definition label. An # will be added if a string is // not prefixed with a #. It will panic if s cannot be written as a valid // identifier. func Def(s string) Selector { - if !strings.HasPrefix(s, "#") && !strings.HasPrefix(s, "_#") { + if !internal.IsDef(s) { s = "#" + s } if !ast.IsValidIdent(s) { @@ -531,13 +556,13 @@ func (d definitionSelector) labelType() SelectorType { return DefinitionLabel } -func (s definitionSelector) constraintType() SelectorType { return 0 } +func (d definitionSelector) constraintType() SelectorType { return 0 } func (d definitionSelector) feature(r adt.Runtime) adt.Feature { return adt.MakeIdentLabel(r, string(d), "") } -// A Str is a CUE string label. Definition selectors are defined with Def. +// Str creates a CUE string label. Definition selectors are defined with [Def]. func Str(s string) Selector { return Selector{stringSelector(s)} } @@ -546,7 +571,7 @@ type stringSelector string func (s stringSelector) String() string { str := string(s) - if isHiddenOrDefinition(str) || !ast.IsValidIdent(str) { + if ast.StringLabelNeedsQuoting(str) { return literal.Label.Quote(str) } return str @@ -560,7 +585,7 @@ func (s stringSelector) feature(r adt.Runtime) adt.Feature { return adt.MakeStringLabel(r, string(s)) } -// An Index selects a list element by index. +// Index selects a list element by index. // It returns an invalid selector if the index is out of range. func Index[T interface{ int | int64 }](x T) Selector { f, err := adt.MakeLabel(nil, int64(x), adt.IntLabel) @@ -603,6 +628,20 @@ func (s anySelector) feature(r adt.Runtime) adt.Feature { return adt.Feature(s) } +type patternSelector struct { + pattern Value + _labelType SelectorType +} + +func (s patternSelector) String() string { return fmt.Sprintf("[%#v]", s.pattern) } +func (s patternSelector) isConstraint() bool { return true } +func (s patternSelector) labelType() SelectorType { return s._labelType } +func (s patternSelector) constraintType() SelectorType { return PatternConstraint } +func (s patternSelector) feature(r adt.Runtime) adt.Feature { + // Only called for non-pattern selectors. + panic("unreachable") +} + // TODO: allow import paths to be represented? // // // ImportPath defines a lookup at the root of an instance. It must be the first @@ -611,6 +650,7 @@ func (s anySelector) feature(r adt.Runtime) adt.Feature { // func ImportPath(s string) Selector { // return importSelector(s) // } + type constraintSelector struct { selector constraint SelectorType diff --git a/vendor/cuelang.org/go/cue/query.go b/vendor/cuelang.org/go/cue/query.go index 43b4180c75..698c72f1d2 100644 --- a/vendor/cuelang.org/go/cue/query.go +++ b/vendor/cuelang.org/go/cue/query.go @@ -15,6 +15,8 @@ package cue import ( + "cuelang.org/go/cue/errors" + "cuelang.org/go/cue/token" "cuelang.org/go/internal/core/adt" ) @@ -49,6 +51,15 @@ func (v Value) LookupPath(p Path) Value { outer: for _, sel := range p.path { + if _, ok := sel.sel.(patternSelector); ok { + // It's not possible to look up pattern constraints. + // TODO: could potentially relax that restriction. + err := errors.Newf( + token.NoPos, + "cannot look up pattern constraints other than AnyString or AnyIndex", + ) + return newErrValue(makeValue(v.idx, n, parent), &adt.Bottom{Err: err}) + } f := sel.sel.feature(v.idx) deref := n.DerefValue() for _, a := range deref.Arcs { @@ -56,6 +67,7 @@ outer: if a.IsConstraint() && !sel.sel.isConstraint() { break } + a.Finalize(ctx) parent = linkParent(parent, n, a) n = a continue outer @@ -66,7 +78,7 @@ outer: Parent: n, Label: sel.sel.feature(ctx), } - n.MatchAndInsert(ctx, x) + deref.MatchAndInsert(ctx, x) if x.HasConjuncts() { x.Finalize(ctx) parent = linkParent(parent, n, x) diff --git a/vendor/cuelang.org/go/cue/scanner/scanner.go b/vendor/cuelang.org/go/cue/scanner/scanner.go index ad94b4c4ee..c76c71ddda 100644 --- a/vendor/cuelang.org/go/cue/scanner/scanner.go +++ b/vendor/cuelang.org/go/cue/scanner/scanner.go @@ -605,6 +605,11 @@ func (s *Scanner) popInterpolation() quoteInfo { } // ResumeInterpolation resumes scanning of a string interpolation. +// It should be called when the final parenthesis (RPAREN) of an expression +// inside a string interpolation has been consumed, and returns +// the next literal segment of the interpolation string, including +// the closing parenthesis, and possible the opening parenthesis +// of the next interpolation expression if there is one. func (s *Scanner) ResumeInterpolation() string { quote := s.popInterpolation() _, str := s.scanString(s.offset-1, quote) @@ -620,9 +625,10 @@ func (s *Scanner) Offset() int { // and its literal string if applicable. The source end is indicated by // EOF. // -// If the returned token is a literal (IDENT, INT, FLOAT, -// IMAG, CHAR, STRING) or COMMENT, the literal string -// has the corresponding value. +// If the returned token is a literal (IDENT, INT, FLOAT, IMAG, CHAR, +// STRING, INTERPOLATION) or COMMENT or ATTRIBUTE, the literal +// string has the corresponding value, but see below for more +// information on INTERPOLATION. // // If the returned token is a keyword, the literal string is the keyword. // @@ -646,6 +652,44 @@ func (s *Scanner) Offset() int { // Scan adds line information to the file added to the file // set with Init. Token positions are relative to that file // and thus relative to the file set. +// +// # String Interpolations +// +// The INTERPOLATION token is treated somewhat specially, as the scanner +// does not itself determine the extent of the interpolation +// expressions. +// +// The scanner relies on the caller to read tokens after the literal +// string segments of the interpolation; when the caller has scanned the +// final parenthesis, it must call [Scanner.ResumeInterpolation], which +// returns the next segment of the interpolation, which may or may not +// itself be an interpolation (it's an interpolation iff the final +// character is an open-parenthesis). +// +// Note that the string literal associated with the INTERPOLATION token +// and the string returned by ResumeInterpolation contain the bounding +// parenthesis characters, even though they are also returned from the +// scanner as separate tokens. +// +// For example, scanning the following CUE +// +// #"a\#(foo("c \(d)"))"# +// +// would produce the following tokens and literal values: +// +// INTERPOLATION `#"a\#(` +// LPAREN +// IDENT `b` +// LPAREN +// IDENT `foo` +// LPAREN +// INTERPOLATION `"c \(` +// IDENT `d` +// RPAREN +// ResumeInterpolation -> `)"` +// RPAREN +// RPAREN +// ResumeInterpolation -> `)"#` func (s *Scanner) Scan() (pos token.Pos, tok token.Token, lit string) { scanAgain: s.skipWhitespace(1) @@ -796,6 +840,8 @@ scanAgain: case '?': tok = token.OPTION insertEOL = true + case '~': + tok = token.TILDE case '.': if '0' <= s.ch && s.ch <= '9' { insertEOL = true diff --git a/vendor/cuelang.org/go/cue/stats/stats.go b/vendor/cuelang.org/go/cue/stats/stats.go index d65b0181ac..51f8f55d05 100644 --- a/vendor/cuelang.org/go/cue/stats/stats.go +++ b/vendor/cuelang.org/go/cue/stats/stats.go @@ -54,6 +54,12 @@ type Counts struct { // should allow for near-linear processing. Disjuncts int64 + // Notifications counts how often a Vertex is added to the notification + // queue. This is typically only the case when a Vertex is involved in + // some kind of cycle, so this should be relatively low in practice + // compared to the number of unifications. + Notifications int64 // Number of notifications sent to nodes. + // Conjuncts is an estimate of the number of conjunctions processed during // the calls to Unify. This includes the conjuncts added in the compilation // phase as well as the derivative conjuncts inserted from other nodes @@ -63,6 +69,44 @@ type Counts struct { // algorithmic behavior. Conjuncts int64 + // Typo checking counters + NumCloseIDs int64 // Number of close IDs used + ConjunctInfos int64 // Number of conjunct infos created + MaxConjunctInfos int64 // Maximum number of conjunct infos in a node + MaxReqSets int64 // Maximum number of requirement sets + MaxRedirect int64 // Maximum number of redirects in containsDefID + + // Exception counters + // + // These counters track exceptional conditions that occur during evaluation. + + // GenerationMismatch indicates the number of times a node was unified + // with a different generation than the one it was created in. + GenerationMismatch int64 // Number of exceptional unification cases + + // MisalignedConjunct indicates the number of conjuncts that were dropped + // because they were not aligned with the current generation of the context. + // Generally this happens because a previously finalized vertex is unified + // in as a value, not constraint, in which case it is okay to ignore + // closedness info. If it were included as a schema, top-level conjuncts + // would be unified and mapped to a local tree. + MisalignedConjunct int64 + + // MisalignedConstraint indicates the number of constraints that were not + // aligned. This is more likely to be a bug. + MisalignedConstraint int64 + + // SkippedNotification indicates the number of notifications that were + // skipped because the value was already finalized. This may miss conjuncts + // when it occurs during evaluation, but it may also be triggered during + // dependency analysis, in which case it is benign. + SkippedNotification int64 + + // Dependency resolution counters + + // ResolveDep counts the number calls to markResolver in dep.go. + ResolveDep int64 + // Buffer counters // // Each unification and disjunct operation is associated with an object @@ -99,6 +143,25 @@ func (c *Counts) Add(other Counts) { c.Unifications += other.Unifications c.Conjuncts += other.Conjuncts c.Disjuncts += other.Disjuncts + c.Notifications += other.Notifications + + c.GenerationMismatch += other.GenerationMismatch + c.MisalignedConjunct += other.MisalignedConjunct + c.MisalignedConstraint += other.MisalignedConstraint + c.SkippedNotification += other.SkippedNotification + + c.NumCloseIDs += other.NumCloseIDs + c.ConjunctInfos += other.ConjunctInfos + if other.MaxConjunctInfos > c.MaxConjunctInfos { + c.MaxConjunctInfos = other.MaxConjunctInfos + } + if other.MaxReqSets > c.MaxReqSets { + c.MaxReqSets = other.MaxReqSets + } + if other.MaxRedirect > c.MaxRedirect { + c.MaxRedirect = other.MaxRedirect + } + c.ResolveDep += other.ResolveDep c.Freed += other.Freed c.Retained += other.Retained @@ -110,6 +173,17 @@ func (c Counts) Since(start Counts) Counts { c.Unifications -= start.Unifications c.Conjuncts -= start.Conjuncts c.Disjuncts -= start.Disjuncts + c.Notifications -= start.Notifications + c.GenerationMismatch -= start.GenerationMismatch + c.MisalignedConjunct -= start.MisalignedConjunct + c.MisalignedConstraint -= start.MisalignedConstraint + c.SkippedNotification -= start.SkippedNotification + c.NumCloseIDs -= start.NumCloseIDs + c.ConjunctInfos -= start.ConjunctInfos + c.ResolveDep -= start.ResolveDep + + // For max values, we don't subtract since they represent peaks + // c.MaxConjunctInfos and c.MaxReqSets and c.MaxRedirect remain as-is c.Freed -= start.Freed c.Retained -= start.Retained @@ -139,7 +213,21 @@ Retain: {{.Retained}} Unifications: {{.Unifications}} Conjuncts: {{.Conjuncts}} -Disjuncts: {{.Disjuncts}}`)) +Disjuncts: {{.Disjuncts}}{{if .Notifications}} +Notifications: {{.Notifications}}{{end}}{{if .ResolveDep}} +ResolveDep: {{.ResolveDep}}{{end}}{{if or .GenerationMismatch .MisalignedConjunct .MisalignedConstraint .SkippedNotification}} +{{if .GenerationMismatch}} +GenerationMismatch: {{.GenerationMismatch}}{{end}}{{if .MisalignedConjunct}} +MisalignedConjunct: {{.MisalignedConjunct}}{{end}}{{if .MisalignedConstraint}} +MisalignedConstraint: {{.MisalignedConstraint}}{{end}}{{if .SkippedNotification}} +SkippedNotification: {{.SkippedNotification}}{{end}}{{end}}{{if .NumCloseIDs}} + +NumCloseIDs: {{.NumCloseIDs}}{{end}}{{if or (ge .MaxReqSets 150) (ge .MaxConjunctInfos 8) (ge .MaxRedirect 2)}} + +ConjunctInfos: {{.ConjunctInfos}} +MaxConjunctInfos: {{.MaxConjunctInfos}}{{if .MaxReqSets}} +MaxReqSets: {{.MaxReqSets}}{{end}}{{if .MaxRedirect}} +MaxRedirect: {{.MaxRedirect}}{{end}}{{end}}`)) }) func (s Counts) String() string { diff --git a/vendor/cuelang.org/go/cue/token/position.go b/vendor/cuelang.org/go/cue/token/position.go index 8d194d0511..e6a4e40dd2 100644 --- a/vendor/cuelang.org/go/cue/token/position.go +++ b/vendor/cuelang.org/go/cue/token/position.go @@ -19,13 +19,18 @@ import ( "fmt" "sort" "sync" + + "cuelang.org/go/internal/core/layer" + "cuelang.org/go/internal/cueexperiment" ) // ----------------------------------------------------------------------------- // Positions -// Position describes an arbitrary source position -// including the file, line, and column location. +// Position describes an arbitrary and printable source position within a file, +// including offset, line, and column location, +// which can be rendered in a human-friendly text form. +// // A Position is valid if the line number is > 0. type Position struct { Filename string // filename, if any @@ -38,7 +43,7 @@ type Position struct { // IsValid reports whether the position is valid. func (pos *Position) IsValid() bool { return pos.Line > 0 } -// String returns a string in one of several forms: +// String returns a human-readable form of a position in one of several forms: // // file:line:column valid position with file name // line:column valid position without file name @@ -58,16 +63,18 @@ func (pos Position) String() string { return s } -// Pos is a compact encoding of a source position within a file, as well as -// relative positioning information. It can be converted into a Position for a -// more convenient, but much larger, representation. +// Pos is a compact encoding of a source position. +// When valid, as reported by [Pos.IsValid], this can be either +// a printable file position to obtain via [Pos.Position], +// which can be rendered in a human-friendly text form, +// and/or a relative position to obtain via [Pos.RelPos]. type Pos struct { file *File offset int } -// File returns the file that contains the position p or nil if there is no -// such file (for instance for p == NoPos). +// File returns the file that contains the printable position p +// or nil if there is no such file (for instance for p == [NoPos]). func (p Pos) File() *File { if p.index() == 0 { return nil @@ -75,31 +82,48 @@ func (p Pos) File() *File { return p.file } -// TODO(mvdan): The methods below don't need to build an entire Position -// just to access some of the information. This could matter particularly for -// Compare, as it is called many times when sorting by position. +// hiddenPos allows defining methods in Pos that are hidden from public +// documentation. +type hiddenPos = Pos -func (p Pos) Line() int { - if p.file == nil { - return 0 +func (p hiddenPos) Experiment() (x cueexperiment.File) { + if p.file == nil || p.file.experiments == nil { + return x } + + x = *p.file.experiments + return x +} + +// NOTE: this is an internal API and may change at any time without notice. +func (p hiddenPos) Priority() (pr layer.Priority, ok bool) { + if f := p.file; f != nil { + return f.priority, f.isData + } + return 0, false +} + +// Line returns the position's line number, starting at 1. +func (p Pos) Line() int { return p.Position().Line } +// Column returns the position's column number counting in bytes, +// starting at 1. func (p Pos) Column() int { - if p.file == nil { - return 0 - } return p.Position().Column } +// Filename returns the name of the file that this position belongs to. func (p Pos) Filename() string { + // Avoid calling [Pos.Position] as it also unpacks line and column info. if p.file == nil { return "" } - return p.Position().Filename + return p.file.name } +// Position unpacks the position information into a flat struct. func (p Pos) Position() Position { if p.file == nil { return Position{} @@ -107,6 +131,7 @@ func (p Pos) Position() Position { return p.file.Position(p) } +// String returns a human-readable form of a printable position. func (p Pos) String() string { return p.Position().String() } @@ -121,14 +146,14 @@ func (p Pos) Compare(p2 Pos) int { } else if p2 == NoPos { return -1 } - pos, pos2 := p.Position(), p2.Position() - if c := cmp.Compare(pos.Filename, pos2.Filename); c != 0 { + // Avoid calling [Pos.Position] as it also unpacks line and column info; + // comparing positions only needs filenames and offsets. + if c := cmp.Compare(p.Filename(), p2.Filename()); c != 0 { return c } // Note that CUE doesn't currently use any directives which alter // position information, like Go's //line, so comparing by offset is enough. - return cmp.Compare(pos.Offset, pos2.Offset) - + return cmp.Compare(p.Offset(), p2.Offset()) } // NoPos is the zero value for [Pos]; there is no file and line information @@ -142,7 +167,7 @@ var NoPos = Pos{} // RelPos indicates the relative position of token to the previous token. type RelPos int -//go:generate go run golang.org/x/tools/cmd/stringer -type=RelPos -linecomment +//go:generate go tool stringer -type=RelPos -linecomment const ( // NoRelPos indicates no relative position is specified. @@ -175,16 +200,24 @@ func (p RelPos) Pos() Pos { // HasRelPos reports whether p has a relative position. func (p Pos) HasRelPos() bool { return p.offset&relMask != 0 - } +// Before reports whether p < q, as documented in [Pos.Compare]. +// +// Deprecated: use [Pos.Compare] instead. +// +//go:fix inline func (p Pos) Before(q Pos) bool { - return p.file == q.file && p.Offset() < q.Offset() + return p.Compare(q) < 0 } // Offset reports the byte offset relative to the file. func (p Pos) Offset() int { - return p.Position().Offset + // Avoid calling [Pos.Position] as it also unpacks line and column info. + if p.file == nil { + return 0 + } + return p.file.Offset(p) } // Add creates a new position relative to the p offset by n. @@ -192,7 +225,9 @@ func (p Pos) Add(n int) Pos { return Pos{p.file, p.offset + toPos(index(n))} } -// IsValid reports whether the position is valid. +// IsValid reports whether the position contains any useful information, +// meaning either a printable file position to obtain via [Pos.Position], +// and/or a relative position to obtain via [Pos.RelPos]. func (p Pos) IsValid() bool { return p != NoPos } @@ -237,9 +272,15 @@ type File struct { base index size index // file size as provided to AddFile - // lines and infos are protected by set.mutex - lines []index // lines contains the offset of the first character for each line (the first entry is always 0) - infos []lineInfo + // lines, infos, content, and revision are protected by [File.mutex] + lines []index // lines contains the offset of the first character for each line (the first entry is always 0) + infos []lineInfo + content []byte + revision int32 + + experiments *cueexperiment.File + priority layer.Priority + isData bool } // NewFile returns a new file with the given OS file name. The size provides the @@ -250,7 +291,44 @@ func NewFile(filename string, deprecatedBase, size int) *File { if deprecatedBase < 0 { deprecatedBase = 1 } - return &File{sync.RWMutex{}, filename, index(deprecatedBase), index(size), []index{0}, nil} + return &File{ + name: filename, + base: index(deprecatedBase), + size: index(size), + lines: []index{0}, + } +} + +// fixOffset fixes an out-of-bounds offset such that 0 <= offset <= f.size. +func (f *File) fixOffset(offset index) index { + switch { + case offset < 0: + return 0 + case offset > f.size: + return f.size + default: + return offset + } +} + +// hiddenFile allows defining methods in File that are hidden from public +// documentation. +type hiddenFile = File + +func (f *hiddenFile) SetExperiments(experiments *cueexperiment.File) { + f.experiments = experiments +} + +// NOTE: this is an internal API and may change at any time without notice. +// +// SetLayer sets the layer priority for this file. The priority parameter +// determines the precedence of defaults defined in this file, with higher +// values taking precedence over lower values. The isData parameter indicates +// whether this file should be treated as containing data defaults, which +// have different merging semantics from regular defaults. +func (f *hiddenFile) SetLayer(priority int8, isData bool) { + f.priority = layer.Priority(priority) + f.isData = isData } // Name returns the file name of file f as registered with AddFile. @@ -373,6 +451,40 @@ func (f *File) SetLinesForContent(content []byte) { f.mutex.Unlock() } +// SetContent sets the file's content. The content must not be altered +// after this call. +func (f *hiddenFile) SetContent(content []byte) { + f.mutex.Lock() + f.content = content + f.mutex.Unlock() +} + +// Content retrievs the file's content, which may be nil. The returned +// content must not be altered. +func (f *hiddenFile) Content() []byte { + f.mutex.RLock() + defer f.mutex.RUnlock() + return f.content +} + +// NOTE: this is an internal API and may change at any time without notice. +// +// SetRevision sets the file's version. +func (f *hiddenFile) SetRevision(version int32) { + f.mutex.Lock() + f.revision = version + f.mutex.Unlock() +} + +// NOTE: this is an internal API and may change at any time without notice. +// +// Revision retrieves the file's version. +func (f *hiddenFile) Revision() int32 { + f.mutex.RLock() + defer f.mutex.RUnlock() + return f.revision +} + // A lineInfo object describes alternative file and line number // information (such as provided via a //line comment in a .go // file) for a given file offset. @@ -399,25 +511,31 @@ func (f *File) AddLineInfo(offset int, filename string, line int) { f.mutex.Unlock() } -// Pos returns the Pos value for the given file offset; -// the offset must be <= f.Size(). +// Pos returns the Pos value for the given file offset. +// +// If offset is negative, the result is the file's start +// position; if the offset is too large, the result is +// the file's end position (see also go.dev/issue/57490). +// +// The following invariant, though not true for Pos values +// in general, holds for the result p: // f.Pos(f.Offset(p)) == p. func (f *File) Pos(offset int, rel RelPos) Pos { - if index(offset) > f.size { - panic("illegal file offset") - } - return Pos{f, toPos(1+index(offset)) + int(rel)} + return Pos{f, toPos(1+f.fixOffset(index(offset))) + int(rel)} } -// Offset returns the offset for the given file position p; -// p must be a valid Pos value in that file. -// f.Offset(f.Pos(offset)) == offset. +// Offset returns the offset for the given file position p. +// +// If p is before the file's start position (or if p is NoPos), +// the result is 0; if p is past the file's end position, the +// the result is the file size (see also go.dev/issue/57490). +// +// The following invariant, though not true for offset values +// in general, holds for the result offset: +// f.Offset(f.Pos(offset)) == offset func (f *File) Offset(p Pos) int { x := p.index() - if x < 1 || x > 1+index(f.size) { - panic("illegal Pos value") - } - return int(x - 1) + return int(f.fixOffset(x - 1)) } // Line returns the line number for the given file position p; @@ -436,7 +554,7 @@ func searchLineInfos(a []lineInfo, x int) int { func (f *File) unpack(offset index, adjusted bool) (filename string, line, column int) { filename = f.name if i := searchInts(f.lines, offset); i >= 0 { - line, column = int(i+1), int(offset-f.lines[i]+1) + line, column = i+1, int(offset-f.lines[i]+1) } if adjusted && len(f.infos) > 0 { // almost no files have extra line infos @@ -452,28 +570,26 @@ func (f *File) unpack(offset index, adjusted bool) (filename string, line, colum } func (f *File) position(p Pos, adjusted bool) (pos Position) { - offset := p.index() - 1 - pos.Offset = int(offset) - pos.Filename, pos.Line, pos.Column = f.unpack(offset, adjusted) + offset := f.Offset(p) + pos.Offset = offset + pos.Filename, pos.Line, pos.Column = f.unpack(index(offset), adjusted) return } // PositionFor returns the Position value for the given file position p. +// If p is out of bounds, it is adjusted to match the File.Offset behavior. // If adjusted is set, the position may be adjusted by position-altering // //line comments; otherwise those comments are ignored. // p must be a Pos value in f or NoPos. func (f *File) PositionFor(p Pos, adjusted bool) (pos Position) { - x := p.index() if p != NoPos { - if x < 1 || x > 1+f.size { - panic("illegal Pos value") - } pos = f.position(p, adjusted) } return } // Position returns the Position value for the given file position p. +// If p is out of bounds, it is adjusted to match the File.Offset behavior. // Calling f.Position(p) is equivalent to calling f.PositionFor(p, true). func (f *File) Position(p Pos) (pos Position) { return f.PositionFor(p, true) diff --git a/vendor/cuelang.org/go/cue/token/relpos_string.go b/vendor/cuelang.org/go/cue/token/relpos_string.go index 0129d7bb62..c6bb71e373 100644 --- a/vendor/cuelang.org/go/cue/token/relpos_string.go +++ b/vendor/cuelang.org/go/cue/token/relpos_string.go @@ -21,8 +21,9 @@ const _RelPos_name = "invalidelidednospaceblanknewlinesection" var _RelPos_index = [...]uint8{0, 7, 13, 20, 25, 32, 39} func (i RelPos) String() string { - if i < 0 || i >= RelPos(len(_RelPos_index)-1) { + idx := int(i) - 0 + if i < 0 || idx >= len(_RelPos_index)-1 { return "RelPos(" + strconv.FormatInt(int64(i), 10) + ")" } - return _RelPos_name[_RelPos_index[i]:_RelPos_index[i+1]] + return _RelPos_name[_RelPos_index[idx]:_RelPos_index[idx+1]] } diff --git a/vendor/cuelang.org/go/cue/token/token.go b/vendor/cuelang.org/go/cue/token/token.go index 05579d4049..6f4290bad5 100644 --- a/vendor/cuelang.org/go/cue/token/token.go +++ b/vendor/cuelang.org/go/cue/token/token.go @@ -19,7 +19,7 @@ package token // Token is the set of lexical tokens of the CUE configuration language. type Token int -//go:generate go run golang.org/x/tools/cmd/stringer -type=Token -linecomment +//go:generate go tool stringer -type=Token -linecomment // The list of tokens. const ( @@ -95,6 +95,7 @@ const ( SEMICOLON // ; COLON // : OPTION // ? + TILDE // ~ operatorEnd keywordBeg diff --git a/vendor/cuelang.org/go/cue/token/token_string.go b/vendor/cuelang.org/go/cue/token/token_string.go index e845d9c2c4..54ec30ea23 100644 --- a/vendor/cuelang.org/go/cue/token/token_string.go +++ b/vendor/cuelang.org/go/cue/token/token_string.go @@ -57,26 +57,28 @@ func _() { _ = x[SEMICOLON-46] _ = x[COLON-47] _ = x[OPTION-48] - _ = x[operatorEnd-49] - _ = x[keywordBeg-50] - _ = x[IF-51] - _ = x[FOR-52] - _ = x[IN-53] - _ = x[LET-54] - _ = x[FUNC-55] - _ = x[TRUE-56] - _ = x[FALSE-57] - _ = x[NULL-58] - _ = x[keywordEnd-59] + _ = x[TILDE-49] + _ = x[operatorEnd-50] + _ = x[keywordBeg-51] + _ = x[IF-52] + _ = x[FOR-53] + _ = x[IN-54] + _ = x[LET-55] + _ = x[FUNC-56] + _ = x[TRUE-57] + _ = x[FALSE-58] + _ = x[NULL-59] + _ = x[keywordEnd-60] } -const _Token_name = "ILLEGALEOFCOMMENTATTRIBUTEliteralBegIDENTINTFLOATSTRINGINTERPOLATION_|_literalEndoperatorBeg+-*^/quoremdivmod&|&&||===<>!<-!=<=>==~!~([{,....)]};:?operatorEndkeywordBegifforinletfunctruefalsenullkeywordEnd" +const _Token_name = "ILLEGALEOFCOMMENTATTRIBUTEliteralBegIDENTINTFLOATSTRINGINTERPOLATION_|_literalEndoperatorBeg+-*^/quoremdivmod&|&&||===<>!<-!=<=>==~!~([{,....)]};:?~operatorEndkeywordBegifforinletfunctruefalsenullkeywordEnd" -var _Token_index = [...]uint8{0, 7, 10, 17, 26, 36, 41, 44, 49, 55, 68, 71, 81, 92, 93, 94, 95, 96, 97, 100, 103, 106, 109, 110, 111, 113, 115, 116, 118, 119, 120, 121, 123, 125, 127, 129, 131, 133, 134, 135, 136, 137, 138, 141, 142, 143, 144, 145, 146, 147, 158, 168, 170, 173, 175, 178, 182, 186, 191, 195, 205} +var _Token_index = [...]uint8{0, 7, 10, 17, 26, 36, 41, 44, 49, 55, 68, 71, 81, 92, 93, 94, 95, 96, 97, 100, 103, 106, 109, 110, 111, 113, 115, 116, 118, 119, 120, 121, 123, 125, 127, 129, 131, 133, 134, 135, 136, 137, 138, 141, 142, 143, 144, 145, 146, 147, 148, 159, 169, 171, 174, 176, 179, 183, 187, 192, 196, 206} func (i Token) String() string { - if i < 0 || i >= Token(len(_Token_index)-1) { + idx := int(i) - 0 + if i < 0 || idx >= len(_Token_index)-1 { return "Token(" + strconv.FormatInt(int64(i), 10) + ")" } - return _Token_name[_Token_index[i]:_Token_index[i+1]] + return _Token_name[_Token_index[idx]:_Token_index[idx+1]] } diff --git a/vendor/cuelang.org/go/cue/types.go b/vendor/cuelang.org/go/cue/types.go index 99b7f67082..09343a0f18 100644 --- a/vendor/cuelang.org/go/cue/types.go +++ b/vendor/cuelang.org/go/cue/types.go @@ -21,7 +21,9 @@ import ( "io" "math" "math/big" + "slices" "strings" + "unicode/utf8" "github.com/cockroachdb/apd/v3" @@ -36,8 +38,8 @@ import ( "cuelang.org/go/internal/core/export" "cuelang.org/go/internal/core/runtime" "cuelang.org/go/internal/core/subsume" - "cuelang.org/go/internal/core/validate" internaljson "cuelang.org/go/internal/encoding/json" + "cuelang.org/go/internal/iterutil" "cuelang.org/go/internal/types" ) @@ -88,10 +90,11 @@ const ( // // TODO: remove type structValue struct { - ctx *adt.OpContext - v Value - obj *adt.Vertex - arcs []*adt.Vertex + ctx *adt.OpContext + v Value + obj *adt.Vertex + arcs []*adt.Vertex + patterns []adt.PatternConstraint } type hiddenStructValue = structValue @@ -140,7 +143,7 @@ func (o *hiddenStructValue) Lookup(key string) Value { return newChildValue(o, i) } -// MarshalJSON returns a valid JSON encoding or reports an error if any of the +// appendJSON appends a valid JSON encoding or reports an error if any of the // fields is invalid. func (o *structValue) appendJSON(b []byte) ([]byte, error) { b = append(b, '{') @@ -210,33 +213,52 @@ func unwrapJSONError(err error) errors.Error { // An Iterator iterates over values. type Iterator struct { - val Value - idx *runtime.Runtime - ctx *adt.OpContext - arcs []*adt.Vertex - p int - cur Value - f adt.Feature - arcType adt.ArcType + val Value + idx *runtime.Runtime + ctx *adt.OpContext + arcs []*adt.Vertex + patterns []adt.PatternConstraint + p int + cur Value + f adt.Feature + arcType adt.ArcType + isPattern bool + isList bool } type hiddenIterator = Iterator // Next advances the iterator to the next value and reports whether there was any. // It must be called before the first call to [Iterator.Value] or [Iterator.Selector]. +// +// Note that pattern constraints will be produced by the iterator before +// any other field. func (i *Iterator) Next() bool { - if i.p >= len(i.arcs) { + switch { + case i.p >= len(i.arcs)+len(i.patterns): i.cur = Value{} return false + case i.p < len(i.patterns): + i.isPattern = true + i.arcType = adt.ArcNotPresent + pattern := i.patterns[i.p] + pattern.Constraint.Finalize(i.ctx) + i.cur = makeValue(i.val.idx, pattern.Constraint, + linkParent(i.val.parent_, i.val.v, pattern.Constraint), + ) + i.p++ + return true + + default: + arc := i.arcs[i.p-len(i.patterns)] + arc.Finalize(i.ctx) + i.isPattern = false + i.f = arc.Label + i.arcType = arc.ArcType + i.cur = makeValue(i.val.idx, arc, linkParent(i.val.parent_, i.val.v, arc)) + i.p++ + return true } - arc := i.arcs[i.p] - arc.Finalize(i.ctx) - p := linkParent(i.val.parent_, i.val.v, arc) - i.f = arc.Label - i.arcType = arc.ArcType - i.cur = makeValue(i.val.idx, arc, p) - i.p++ - return true } // Value returns the current value in the list. @@ -247,12 +269,33 @@ func (i *Iterator) Value() Value { // Selector reports the field label of this iteration. func (i *Iterator) Selector() Selector { - sel := featureToSel(i.f, i.idx) - // Only call wrapConstraint if there is any constraint type to wrap with. - if ctype := fromArcType(i.arcType); ctype != 0 { - sel = wrapConstraint(sel, ctype) + if !i.isPattern { + sel := featureToSel(i.f, i.idx) + // Only call wrapConstraint if there is any constraint type to wrap with. + if ctype := fromArcType(i.arcType); ctype != 0 { + sel = wrapConstraint(sel, ctype) + } + return sel + } + pattern := exprToVertex(i.patterns[i.p-1].Pattern) + pattern.Finalize(i.ctx) + + return Selector{ + patternSelector{ + pattern: makeValue(i.val.idx, pattern, + linkParent(i.val.parent_, i.val.v, pattern), + ), + _labelType: i.patternSelectorType().LabelType(), + }, } - return sel +} + +func (i *Iterator) patternSelectorType() SelectorType { + if i.isList { + // Pattern constraints in lists are always indexes. + return IndexLabel | PatternConstraint + } + return StringLabel | PatternConstraint } // Label reports the label of the value if i iterates over struct fields and "" @@ -276,10 +319,13 @@ func (i *Iterator) IsOptional() bool { // FieldType reports the type of the field. func (i *Iterator) FieldType() SelectorType { + if i.isPattern { + return i.patternSelectorType() + } return featureToSelType(i.f, i.arcType) } -// marshalJSON iterates over the list and generates JSON output. HasNext +// listAppendJSON iterates over the list and generates JSON output. HasNext // will return false after this operation. func listAppendJSON(b []byte, l *Iterator) ([]byte, error) { b = append(b, '[') @@ -490,6 +536,24 @@ func init() { } } +// Float returns a big.Float nearest to x. It reports an error if v is +// not a number. If a non-nil *Float argument f is provided, Float stores the result in f +// instead of allocating a new Float. +func (v Value) Float(f *big.Float) (*big.Float, error) { + var err error + + n, err := v.getNum(adt.NumberKind) + if err != nil { + return nil, err + } + if f == nil { + f = &big.Float{} + } + + f, _, err = f.Parse(n.X.String(), 0) + return f, err +} + // Float64 returns the float64 value nearest to x. It reports an error if v is // not a number. If x is too small to be represented by a float64 (|x| < // math.SmallestNonzeroFloat64), the result is (0, ErrBelow) or (-0, ErrAbove), @@ -594,17 +658,20 @@ func newVertexRoot(idx *runtime.Runtime, ctx *adt.OpContext, x *adt.Vertex) Valu } func newValueRoot(idx *runtime.Runtime, ctx *adt.OpContext, x adt.Expr) Value { + return newVertexRoot(idx, ctx, exprToVertex(x)) +} + +func exprToVertex(x adt.Expr) *adt.Vertex { if n, ok := x.(*adt.Vertex); ok { - return newVertexRoot(idx, ctx, n) + return n } - node := &adt.Vertex{} - node.AddConjunct(adt.MakeRootConjunct(nil, x)) - return newVertexRoot(idx, ctx, node) + n := &adt.Vertex{} + n.AddConjunct(adt.MakeRootConjunct(nil, x)) + return n } func newChildValue(o *structValue, i int) Value { arc := o.at(i) - // TODO: fix linkage to parent. return makeValue(o.v.idx, arc, linkParent(o.v.parent_, o.v.v, arc)) } @@ -715,11 +782,13 @@ func (v Value) Default() (Value, bool) { return v, false } - d := v.v.Default() + x := v.v.DerefValue() + d := x.Default() + isDefault := d != x if d == v.v { return v, false } - return makeValue(v.idx, d, v.parent_), true + return makeValue(v.idx, d, v.parent_), isDefault } // Label reports he label used to obtain this value from the enclosing struct. @@ -830,16 +899,17 @@ func (v Value) Syntax(opts ...Option) ast.Node { o := getOptions(opts) p := export.Profile{ - Simplify: !o.raw, - TakeDefaults: o.final, - ShowOptional: !o.omitOptional && !o.concrete, - ShowDefinitions: !o.omitDefinitions && !o.concrete, - ShowHidden: !o.omitHidden && !o.concrete, - ShowAttributes: !o.omitAttrs, - ShowDocs: o.docs, - ShowErrors: o.showErrors, - InlineImports: o.inlineImports, - Fragment: o.raw, + Simplify: !o.raw, + TakeDefaults: o.final, + ShowOptional: !o.omitOptional && !o.concrete, + ShowDefinitions: !o.omitDefinitions && !o.concrete, + ShowHidden: !o.omitHidden && !o.concrete, + ShowAttributes: !o.omitAttrs, + ShowDocs: o.docs, + ShowErrors: o.showErrors, + InlineImports: o.inlineImports, + Fragment: o.raw, + ExpandReferences: o.concrete, } pkgID := v.instance().ID() @@ -859,7 +929,7 @@ You could file a bug with the above information at: ` cg := &ast.CommentGroup{Doc: true} msg := fmt.Sprintf(format, name, err, p, v) - for _, line := range strings.Split(msg, "\n") { + for line := range strings.SplitSeq(msg, "\n") { cg.List = append(cg.List, &ast.Comment{Text: "// " + line}) } x := &ast.BadExpr{} @@ -870,7 +940,7 @@ You could file a bug with the above information at: // var expr ast.Expr var err error var f *ast.File - if o.concrete || o.final || o.resolveReferences { + if o.concrete || o.final { f, err = p.Vertex(v.idx, pkgID, v.v) if err != nil { return bad(`"cuelang.org/go/internal/core/export".Vertex`, err) @@ -930,21 +1000,19 @@ func (v Value) Source() ast.Node { if v.v == nil { return nil } - count := 0 + c, count := v.v.SingleConjunct() var src ast.Node - v.v.VisitLeafConjuncts(func(c adt.Conjunct) bool { + if count == 1 { src = c.Source() - count++ - return true - }) - if count > 1 || src == nil { + } + if src == nil { src = v.v.Value().Source() } return src } -// If v exactly represents a package, BuildInstance returns -// the build instance corresponding to the value; otherwise it returns nil. +// BuildInstance returns the build instance corresponding to the value +// if v exactly represents a package; otherwise it returns nil. // // The value returned by [Value.ReferencePath] will commonly represent a package. func (v Value) BuildInstance() *build.Instance { @@ -977,19 +1045,15 @@ func (v Value) Pos() token.Pos { } // Pick the most-concrete field. var p token.Pos - v.v.VisitLeafConjuncts(func(c adt.Conjunct) bool { + for c := range v.v.LeafConjuncts() { x := c.Elem() pp := pos(x) if pp == token.NoPos { - return true + continue } p = pp - // Prefer struct conjuncts with actual fields. - if s, ok := x.(*adt.StructLit); ok && len(s.Fields) > 0 { - return false - } - return true - }) + // TODO: Prefer struct conjuncts with actual fields. + } return p } @@ -1003,11 +1067,57 @@ func (v Value) Allows(sel Selector) bool { if v.v.HasEllipsis { return true } + if _, ok := sel.sel.(patternSelector); ok { + // We can always add a pattern constraint. + return true + } c := v.ctx() f := sel.sel.feature(c) return v.v.Accept(c, f) } +// IsClosed reports whether the value has been closed at the top level, either +// with the close function or by being referenced as a definition. +func (v Value) IsClosed() bool { + if v.v == nil { + return false + } + // Use the non-forwarded node to get the actual closed state + x := v.v + isClosed := x.ClosedNonRecursive || x.ClosedRecursive + for !isClosed { + if v, ok := x.BaseValue.(*adt.Vertex); ok { + isClosed = isClosed || v.ClosedNonRecursive || v.ClosedRecursive + x = v + continue + } + break + } + return isClosed +} + +// IsClosedRecursively reports whether the value has been closed by virtue of +// being referenced as a definition. +func (v Value) IsClosedRecursively() bool { + if v.v == nil { + return false + } + // Use the non-forwarded node to get the actual closed state + x := v.v + isClosed := x.ClosedRecursive + // This loop doesn't seem necessary for ClosedRecursive, but we will keep + // it as a safety net. + for !isClosed { + if v, ok := x.BaseValue.(*adt.Vertex); ok { + isClosed = isClosed || v.ClosedRecursive + x = v + continue + } + break + } + return isClosed +} + // IsConcrete reports whether the current value is a concrete scalar value // (not relying on default values), a terminal error, a list, or a struct. // It does not verify that values of lists or structs are concrete themselves. @@ -1026,14 +1136,6 @@ func (v Value) IsConcrete() bool { return true } -// // Deprecated: IsIncomplete -// // -// // It indicates that the value cannot be fully evaluated due to -// // insufficient information. -// func (v Value) IsIncomplete() bool { -// panic("deprecated") -// } - // Exists reports whether this value existed in the configuration. func (v Value) Exists() bool { if v.v == nil { @@ -1094,7 +1196,7 @@ func (v Value) checkKind(ctx *adt.OpContext, want adt.Kind) *adt.Bottom { func makeInt(v Value, x int64) Value { n := &adt.Num{K: adt.IntKind} - n.X.SetInt64(int64(x)) + n.X.SetInt64(x) return remakeFinal(v, n) } @@ -1107,7 +1209,7 @@ func (v Value) Len() Value { case *adt.Vertex: if x.IsList() { n := &adt.Num{K: adt.IntKind} - n.X.SetInt64(int64(len(x.Elems()))) + n.X.SetInt64(int64(iterutil.Count(x.Elems()))) if x.IsClosedList() { return remakeFinal(v, n) } @@ -1125,7 +1227,7 @@ func (v Value) Len() Value { case *adt.Bytes: return makeInt(v, int64(len(x.B))) case *adt.String: - return makeInt(v, int64(len([]rune(x.Str)))) + return makeInt(v, int64(utf8.RuneCountInString(x.Str))) } } const msg = "len not supported for type %v" @@ -1159,13 +1261,7 @@ func (v Value) List() (Iterator, error) { // mustList is like [Value.List], but reusing ctx and leaving it to the caller // to apply defaults and check the kind. func (v Value) mustList(ctx *adt.OpContext) Iterator { - arcs := []*adt.Vertex{} - for _, a := range v.v.Elems() { - if a.Label.IsInt() { - arcs = append(arcs, a) - } - } - return Iterator{idx: v.idx, ctx: ctx, val: v, arcs: arcs} + return Iterator{idx: v.idx, ctx: ctx, val: v, arcs: slices.Collect(v.v.Elems())} } // Null reports an error if v is not null. @@ -1246,6 +1342,7 @@ func (v Value) structValData(ctx *adt.OpContext) (structValue, *adt.Bottom) { // structVal returns an structVal or an error if v is not a struct. func (v Value) structValOpts(ctx *adt.OpContext, o options) (s structValue, err *adt.Bottom) { + orig := v v, _ = v.Default() obj := v.v @@ -1253,8 +1350,8 @@ func (v Value) structValOpts(ctx *adt.OpContext, o options) (s structValue, err switch b := v.v.Bottom(); { case b != nil && b.IsIncomplete() && !o.concrete && !o.final: - // Allow scalar values if hidden or definition fields are requested. - case !o.omitHidden, !o.omitDefinitions: + // Allow scalar values if hidden or definition fields or patterns are requested. + case !o.omitHidden, !o.omitDefinitions, o.includePatterns: default: if err := v.checkKind(ctx, adt.StructKind); err != nil && !err.ChildError { return structValue{}, err @@ -1302,7 +1399,11 @@ func (v Value) structValOpts(ctx *adt.OpContext, o options) (s structValue, err } arcs = append(arcs, arc) } - return structValue{ctx, v, obj, arcs}, nil + var patterns []adt.PatternConstraint + if o.includePatterns && obj.PatternConstraints != nil { + patterns = obj.PatternConstraints.Pairs + } + return structValue{ctx, orig, obj, arcs, patterns}, nil } // Struct returns the underlying struct of a value or an error if the value @@ -1382,7 +1483,11 @@ func (s *hiddenStruct) Fields(opts ...Option) *Iterator { // Fields creates an iterator over v's fields if v is a struct or an error // otherwise. func (v Value) Fields(opts ...Option) (*Iterator, error) { - o := options{omitDefinitions: true, omitHidden: true, omitOptional: true} + o := options{ + omitDefinitions: true, + omitHidden: true, + omitOptional: true, + } o.updateOptions(opts) ctx := v.ctx() obj, err := v.structValOpts(ctx, o) @@ -1390,7 +1495,14 @@ func (v Value) Fields(opts ...Option) (*Iterator, error) { return &Iterator{idx: v.idx, ctx: ctx}, v.toErr(err) } - return &Iterator{idx: v.idx, ctx: ctx, val: v, arcs: obj.arcs}, nil + return &Iterator{ + idx: v.idx, + ctx: ctx, + val: v, + arcs: obj.arcs, + patterns: obj.patterns, + isList: v.Kind() == ListKind, + }, nil } // Lookup reports the value at a path starting from v. The empty path returns v @@ -1579,9 +1691,16 @@ func (v Value) FillPath(p Path, x interface{}) Value { default: expr = convert.GoValueToValue(ctx, x, true) } - for i := len(p.path) - 1; i >= 0; i-- { - switch sel := p.path[i]; sel.Type() { + for _, sel := range slices.Backward(p.path) { + switch sel.Type() { case StringLabel | PatternConstraint: + if _, ok := sel.sel.(patternSelector); ok { + // TODO consider relaxing this restriction, in which case we'd really + // want a constructor for pattern selectors too. + return newErrValue(v, + mkErr(nil, 0, "cannot use pattern selector in FillPath"), + ) + } expr = &adt.StructLit{Decls: []adt.Decl{ &adt.BulkOptionalField{ Filter: &adt.BasicType{K: adt.StringKind}, @@ -1641,12 +1760,9 @@ func (v hiddenValue) Template() func(label string) Value { return nil } - // Implementation for the old evaluator. - types := v.v.OptionalTypes() - switch { - case types&(adt.HasAdditional|adt.HasPattern) != 0: - case v.v.PatternConstraints != nil: - default: + // Simplified after removing OptionalTypes. + // Check if there are pattern constraints. + if v.v.PatternConstraints == nil { return nil } @@ -1689,7 +1805,7 @@ func (v Value) Subsume(w Value, opts ...Option) error { // TODO: this is likely not correct for V3. There are some cases where this is // still used for V3. Transition away from those. func allowed(ctx *adt.OpContext, parent, n *adt.Vertex) *adt.Bottom { - if !parent.IsClosedList() && !parent.IsClosedStruct() { + if !parent.IsClosedList() && parent.IsOpenStruct() { return nil } @@ -1704,21 +1820,6 @@ func allowed(ctx *adt.OpContext, parent, n *adt.Vertex) *adt.Bottom { return nil } -func addConjuncts(ctx *adt.OpContext, dst, src *adt.Vertex) { - c := adt.MakeRootConjunct(nil, src) - c.CloseInfo.GroupUnify = true - - if src.ClosedRecursive { - if ctx.Version == internal.EvalV2 { - var root adt.CloseInfo - c.CloseInfo = root.SpawnRef(src, src.ClosedRecursive, nil) - } else { - c.CloseInfo.FromDef = true - } - } - dst.AddConjunct(c) -} - // Unify reports the greatest lower bound of v and w. // // Value v and w must be obtained from the same build. @@ -1732,20 +1833,14 @@ func (v Value) Unify(w Value) Value { } ctx := v.ctx() - n := &adt.Vertex{} - addConjuncts(ctx, n, v.v) - addConjuncts(ctx, n, w.v) - - n.Finalize(ctx) + defer ctx.PopArc(ctx.PushArc(v.v)) - n.Parent = v.v.Parent - n.Label = v.v.Label - n.ClosedRecursive = v.v.ClosedRecursive || w.v.ClosedRecursive + n := adt.Unify(ctx, v.v, w.v) - if err := n.Err(ctx); err != nil { - return makeValue(v.idx, n, v.parent_) - } if ctx.Version == internal.EvalV2 { + if err := n.Err(ctx); err != nil { + return makeValue(v.idx, n, v.parent_) + } if err := allowed(ctx, v.v, n); err != nil { return newErrValue(w, err) } @@ -1776,34 +1871,28 @@ func (v Value) UnifyAccept(w Value, accept Value) Value { n := &adt.Vertex{} ctx := v.ctx() - cv := adt.MakeRootConjunct(nil, v.v) - cw := adt.MakeRootConjunct(nil, w.v) - switch ctx.Version { case internal.EvalV2: + cv := adt.MakeRootConjunct(nil, v.v) + cw := adt.MakeRootConjunct(nil, w.v) + n.AddConjunct(cv) n.AddConjunct(cw) - n.Finalize(ctx) - - n.Parent = v.v.Parent - n.Label = v.v.Label + case internal.EvalV3: + n.AddOpenConjunct(ctx, v.v) + n.AddOpenConjunct(ctx, w.v) + } + n.Finalize(ctx) - if err := n.Err(ctx); err != nil { - return makeValue(v.idx, n, v.parent_) - } - if err := allowed(ctx, accept.v, n); err != nil { - return newErrValue(accept, err) - } + n.Parent = v.v.Parent + n.Label = v.v.Label - case internal.EvalV3: - cv.CloseInfo.FromEmbed = true - cw.CloseInfo.FromEmbed = true - n.AddConjunct(cv) - n.AddConjunct(cw) - ca := adt.MakeRootConjunct(nil, accept.v) - n.AddConjunct(ca) - n.Finalize(ctx) + if err := n.Err(ctx); err != nil { + return makeValue(v.idx, n, v.parent_) + } + if err := allowed(ctx, accept.v, n); err != nil { + return newErrValue(accept, err) } return makeValue(v.idx, n, v.parent_) @@ -1917,6 +2006,7 @@ func reference(rt *runtime.Runtime, c *adt.OpContext, env *adt.Environment, r ad if inst == nil { return nil, nil } + inst.Finalize(c) return inst, path } @@ -1930,20 +2020,20 @@ func mkPath(r *runtime.Runtime, a []Selector, v *adt.Vertex) (root *adt.Vertex, } type options struct { - concrete bool // enforce that values are concrete - raw bool // show original values - hasHidden bool - omitHidden bool - omitDefinitions bool - omitOptional bool - omitAttrs bool - inlineImports bool - resolveReferences bool - showErrors bool - final bool - ignoreClosedness bool // used for comparing APIs - docs bool - disallowCycles bool // implied by concrete + concrete bool // enforce that values are concrete + raw bool // show original values + hasHidden bool + omitHidden bool + omitDefinitions bool + omitOptional bool + omitAttrs bool + includePatterns bool + inlineImports bool + showErrors bool + final bool + ignoreClosedness bool // used for comparing APIs + docs bool + disallowCycles bool // implied by concrete } // An Option defines modes of evaluation. @@ -1971,7 +2061,7 @@ func Schema() Option { // Concrete ensures that all values are concrete. // -// For [Validate] this means it returns an error if this is not the case. +// For [Value.Validate] this means it returns an error if this is not the case. // In other cases a non-concrete value will be replaced with an error. func Concrete(concrete bool) Option { return func(p *options) { @@ -1998,29 +2088,6 @@ func DisallowCycles(disallow bool) Option { return func(p *options) { p.disallowCycles = disallow } } -// ResolveReferences forces the evaluation of references when outputting. -// -// Deprecated: [Value.Syntax] will now always attempt to resolve dangling references and -// make the output self-contained. When [Final] or [Concrete] are used, -// it will already attempt to resolve all references. -// See also [InlineImports]. -func ResolveReferences(resolve bool) Option { - return func(p *options) { - p.resolveReferences = resolve - - // ResolveReferences is implemented as a Value printer, rather than - // a definition printer, even though it should be more like the latter. - // To reflect this we convert incomplete errors to their original - // expression. - // - // TODO: ShowErrors mostly shows incomplete errors, even though this is - // just an approximation. There seems to be some inconsistencies as to - // when child errors are marked as such, making the conversion somewhat - // inconsistent. This option is conservative, though. - p.showErrors = true - } -} - // ErrorsAsValues treats errors as a regular value, including them at the // location in the tree where they occur, instead of interpreting them as a // configuration-wide failure that is returned instead of root value. @@ -2067,6 +2134,21 @@ func Definitions(include bool) Option { } } +// Patterns indicates whether pattern constraints should be included +// when iterating over struct fields. This includes universal pattern +// constraints such as `[_]: int` or `[=~"^a"]: string` but +// not the ellipsis pattern as selected by [AnyString]: that +// can be found with [Value.LookupPath](cue.MakePath(cue.AnyString)). +func Patterns(include bool) Option { + // TODO we can include patterns, but there's no way + // of iterating over patterns _only_ which might be + // useful in some cases. Perhaps we could add: + // func Regular(include bool) Option + return func(p *options) { + p.includePatterns = include + } +} + // Hidden indicates that definitions and hidden fields should be included. func Hidden(include bool) Option { return func(p *options) { @@ -2108,14 +2190,14 @@ func (v Value) Validate(opts ...Option) error { o := options{} o.updateOptions(opts) - cfg := &validate.Config{ + cfg := &adt.ValidateConfig{ Concrete: o.concrete, Final: o.final, DisallowCycles: o.disallowCycles, AllErrors: true, } - b := validate.Validate(v.ctx(), v.v, cfg) + b := adt.Validate(v.ctx(), v.v, cfg) if b != nil { return v.toErr(b) } @@ -2214,7 +2296,7 @@ func (v Value) Expr() (Op, []Value) { default: a := []Value{} ctx := v.ctx() - v.v.VisitLeafConjuncts(func(c adt.Conjunct) bool { + for c := range v.v.LeafConjuncts() { // Keep parent here. TODO: do we need remove the requirement // from other conjuncts? n := &adt.Vertex{ @@ -2224,9 +2306,7 @@ func (v Value) Expr() (Op, []Value) { n.AddConjunct(c) n.Finalize(ctx) a = append(a, makeValue(v.idx, n, v.parent_)) - return true - }) - + } return adt.AndOp, a } @@ -2243,6 +2323,9 @@ process: case *adt.UnaryExpr: a = append(a, remakeValue(v, env, x.X)) op = x.Op + case *adt.OpenExpr: + a = append(a, remakeValue(v, env, x.X)) + op = adt.SpreadOp case *adt.BoundExpr: a = append(a, remakeValue(v, env, x.Expr)) op = x.Op diff --git a/vendor/cuelang.org/go/encoding/json/json.go b/vendor/cuelang.org/go/encoding/json/json.go index 2ef43739b5..a63fb06721 100644 --- a/vendor/cuelang.org/go/encoding/json/json.go +++ b/vendor/cuelang.org/go/encoding/json/json.go @@ -12,7 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package json converts JSON to and from CUE. +// Package json converts JSON to CUE. +// To convert CUE to JSON, use [encoding/json.Marshal] on a [cue.Value]. package json import ( @@ -20,7 +21,6 @@ import ( "encoding/json" "fmt" "io" - "strings" "cuelang.org/go/cue" "cuelang.org/go/cue/ast" @@ -237,7 +237,7 @@ func patchExpr(n ast.Node, patchPos func(n ast.Node)) { // TODO(legacy): remove checking for '_' prefix once hidden // fields are removed. - if !ast.IsValidIdent(u) || strings.HasPrefix(u, "_") { + if ast.StringLabelNeedsQuoting(u) { break // keep string } diff --git a/vendor/cuelang.org/go/encoding/json/pointer.go b/vendor/cuelang.org/go/encoding/json/pointer.go new file mode 100644 index 0000000000..e041d25140 --- /dev/null +++ b/vendor/cuelang.org/go/encoding/json/pointer.go @@ -0,0 +1,98 @@ +// Copyright 2025 CUE Authors +// +// 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. + +package json + +import ( + "fmt" + "iter" + "strconv" + "strings" + + "cuelang.org/go/cue" +) + +var ( + jsonPtrEsc = strings.NewReplacer("~", "~0", "/", "~1") + jsonPtrUnesc = strings.NewReplacer("~0", "~", "~1", "/") +) + +// Pointer represents a JSON Pointer as defined by RFC 6901. +// It is a slash-separated list of tokens that reference a specific location +// within a JSON document. +// TODO(go1.26) alias this to [encoding/json/jsontext.Pointer] +type Pointer string + +// PointerFromTokens returns a JSON Pointer formed from +// the unquoted tokens in the given sequence. Any +// slash (/) or tilde (~) characters will be escaped appropriately. +func PointerFromTokens(tokens iter.Seq[string]) Pointer { + var buf strings.Builder + for tok := range tokens { + buf.WriteByte('/') + buf.WriteString(jsonPtrEsc.Replace(tok)) + } + return Pointer(buf.String()) +} + +// Tokens returns a sequence of all the +// unquoted path elements (tokens) of the JSON Pointer. +func (p Pointer) Tokens() iter.Seq[string] { + s := string(p) + return func(yield func(string) bool) { + needUnesc := strings.IndexByte(s, '~') >= 0 + for len(s) > 0 { + s = strings.TrimPrefix(s, "/") + i := min(uint(strings.IndexByte(s, '/')), uint(len(s))) + tok := s[:i] + if needUnesc { + tok = jsonPtrUnesc.Replace(tok) + } + if !yield(tok) { + return + } + s = s[i:] + } + } +} + +// PointerFromCUEPath returns a JSON Pointer equivalent to the +// given CUE path. It returns an error if the path contains an element +// that cannot be represented as a JSON Pointer. +func PointerFromCUEPath(p cue.Path) (Pointer, error) { + var err error + ptr := PointerFromTokens(func(yield func(s string) bool) { + for _, sel := range p.Selectors() { + var token string + switch sel.Type() { + case cue.StringLabel: + token = sel.Unquoted() + case cue.IndexLabel: + token = strconv.Itoa(sel.Index()) + default: + if err == nil { + err = fmt.Errorf("cannot convert selector %v to JSON pointer", sel) + continue + } + } + if !yield(token) { + return + } + } + }) + if err != nil { + return "", err + } + return ptr, nil +} diff --git a/vendor/cuelang.org/go/encoding/jsonschema/constraints.go b/vendor/cuelang.org/go/encoding/jsonschema/constraints.go index ceb1b3a0e3..811572e151 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/constraints.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/constraints.go @@ -67,66 +67,76 @@ var constraints = []*constraint{ p1("$id", constraintID, vfrom(VersionDraft6)), px("$recursiveAnchor", constraintTODO, vbetween(VersionDraft2019_09, VersionDraft2020_12)), px("$recursiveRef", constraintTODO, vbetween(VersionDraft2019_09, VersionDraft2020_12)), - p2("$ref", constraintRef, allVersions|openAPI), + p2("$ref", constraintRef, allVersions|openAPI|k8sAPI), p0("$schema", constraintSchema, allVersions), px("$vocabulary", constraintTODO, vfrom(VersionDraft2019_09)), p4("additionalItems", constraintAdditionalItems, vto(VersionDraft2019_09)), - p4("additionalProperties", constraintAdditionalProperties, allVersions|openAPI), - p3("allOf", constraintAllOf, allVersions|openAPI), - p3("anyOf", constraintAnyOf, allVersions|openAPI), + p4("additionalProperties", constraintAdditionalProperties, allVersions|openAPILike), + p3("allOf", constraintAllOf, allVersions|openAPILike), + p3("anyOf", constraintAnyOf, allVersions|openAPILike), p2("const", constraintConst, vfrom(VersionDraft6)), p2("contains", constraintContains, vfrom(VersionDraft6)), p2("contentEncoding", constraintContentEncoding, vfrom(VersionDraft7)), p2("contentMediaType", constraintContentMediaType, vfrom(VersionDraft7)), px("contentSchema", constraintTODO, vfrom(VersionDraft2019_09)), - p2("default", constraintDefault, allVersions|openAPI), + p2("default", constraintDefault, allVersions|openAPILike), p2("definitions", constraintAddDefinitions, allVersions), p2("dependencies", constraintDependencies, allVersions), - px("dependentRequired", constraintTODO, vfrom(VersionDraft2019_09)), - px("dependentSchemas", constraintTODO, vfrom(VersionDraft2019_09)), + px("dependentRequired", constraintDependencies, vfrom(VersionDraft2019_09)), + px("dependentSchemas", constraintDependencies, vfrom(VersionDraft2019_09)), p2("deprecated", constraintDeprecated, vfrom(VersionDraft2019_09)|openAPI), - p2("description", constraintDescription, allVersions|openAPI), + p2("description", constraintDescription, allVersions|openAPILike), px("discriminator", constraintTODO, openAPI), p1("else", constraintElse, vfrom(VersionDraft7)), - p2("enum", constraintEnum, allVersions|openAPI), - px("example", constraintTODO, openAPI), + p2("enum", constraintEnum, allVersions|openAPILike), + px("example", constraintTODO, openAPILike), p2("examples", constraintExamples, vfrom(VersionDraft6)), - p2("exclusiveMaximum", constraintExclusiveMaximum, allVersions|openAPI), - p2("exclusiveMinimum", constraintExclusiveMinimum, allVersions|openAPI), - px("externalDocs", constraintTODO, openAPI), - p1("format", constraintFormat, allVersions|openAPI), + p2("exclusiveMaximum", constraintExclusiveMaximum, allVersions|openAPILike), + p2("exclusiveMinimum", constraintExclusiveMinimum, allVersions|openAPILike), + px("externalDocs", constraintTODO, openAPILike), + p1("format", constraintFormat, allVersions|openAPILike), p1("id", constraintID, vto(VersionDraft4)), p1("if", constraintIf, vfrom(VersionDraft7)), - p2("items", constraintItems, allVersions|openAPI), + p2("items", constraintItems, allVersions|openAPILike), p1("maxContains", constraintMaxContains, vfrom(VersionDraft2019_09)), - p2("maxItems", constraintMaxItems, allVersions|openAPI), - p2("maxLength", constraintMaxLength, allVersions|openAPI), - p2("maxProperties", constraintMaxProperties, allVersions|openAPI), - p3("maximum", constraintMaximum, allVersions|openAPI), + p2("maxItems", constraintMaxItems, allVersions|openAPILike), + p2("maxLength", constraintMaxLength, allVersions|openAPILike), + p2("maxProperties", constraintMaxProperties, allVersions|openAPILike), + p3("maximum", constraintMaximum, allVersions|openAPILike), p1("minContains", constraintMinContains, vfrom(VersionDraft2019_09)), - p2("minItems", constraintMinItems, allVersions|openAPI), - p2("minLength", constraintMinLength, allVersions|openAPI), - p1("minProperties", constraintMinProperties, allVersions|openAPI), - p3("minimum", constraintMinimum, allVersions|openAPI), - p2("multipleOf", constraintMultipleOf, allVersions|openAPI), - p3("not", constraintNot, allVersions|openAPI), - p2("nullable", constraintNullable, openAPI), - p3("oneOf", constraintOneOf, allVersions|openAPI), - p2("pattern", constraintPattern, allVersions|openAPI), + p2("minItems", constraintMinItems, allVersions|openAPILike), + p2("minLength", constraintMinLength, allVersions|openAPILike), + p1("minProperties", constraintMinProperties, allVersions|openAPILike), + p3("minimum", constraintMinimum, allVersions|openAPILike), + p2("multipleOf", constraintMultipleOf, allVersions|openAPILike), + p3("not", constraintNot, allVersions|openAPILike), + p2("nullable", constraintNullable, openAPILike), + p3("oneOf", constraintOneOf, allVersions|openAPILike), + p2("pattern", constraintPattern, allVersions|openAPILike), p3("patternProperties", constraintPatternProperties, allVersions), p2("prefixItems", constraintPrefixItems, vfrom(VersionDraft2020_12)), - p2("properties", constraintProperties, allVersions|openAPI), + p2("properties", constraintProperties, allVersions|openAPILike), p2("propertyNames", constraintPropertyNames, vfrom(VersionDraft6)), px("readOnly", constraintTODO, vfrom(VersionDraft7)|openAPI), - p3("required", constraintRequired, allVersions|openAPI), + p3("required", constraintRequired, allVersions|openAPILike), p1("then", constraintThen, vfrom(VersionDraft7)), - p2("title", constraintTitle, allVersions|openAPI), - p2("type", constraintType, allVersions|openAPI), + p2("title", constraintTitle, allVersions|openAPILike), + p2("type", constraintType, allVersions|openAPILike), px("unevaluatedItems", constraintTODO, vfrom(VersionDraft2019_09)), px("unevaluatedProperties", constraintTODO, vfrom(VersionDraft2019_09)), - p2("uniqueItems", constraintUniqueItems, allVersions|openAPI), + p2("uniqueItems", constraintUniqueItems, allVersions|openAPILike), px("writeOnly", constraintTODO, vfrom(VersionDraft7)|openAPI), px("xml", constraintTODO, openAPI), + p1("x-kubernetes-embedded-resource", constraintEmbeddedResource, k8s), + p1("x-kubernetes-group-version-kind", constraintGroupVersionKind, k8sAPI), + p2("x-kubernetes-int-or-string", constraintIntOrString, k8s), + px("x-kubernetes-list-map-keys", constraintIgnore, k8s), + px("x-kubernetes-list-type", constraintIgnore, k8s), + px("x-kubernetes-map-type", constraintIgnore, k8s), + px("x-kubernetes-patch-merge-key", constraintIgnore, k8s), + px("x-kubernetes-patch-strategy", constraintIgnore, k8s), + p2("x-kubernetes-preserve-unknown-fields", constraintPreserveUnknownFields, k8s), + px("x-kubernetes-validations", constraintTODO, k8s), } // px represents a TODO constraint that we haven't decided on a phase for yet. diff --git a/vendor/cuelang.org/go/encoding/jsonschema/constraints_array.go b/vendor/cuelang.org/go/encoding/jsonschema/constraints_array.go index 785adbc2a7..0131c93d5f 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/constraints_array.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/constraints_array.go @@ -45,7 +45,7 @@ func constraintAdditionalItems(key string, n cue.Value, s *state) { panic("no elements in list") } last := s.list.Elts[len(s.list.Elts)-1].(*ast.Ellipsis) - if isBottom(elem) { + if isErrorCall(elem) { // No additional elements allowed. Remove the ellipsis. s.list.Elts = s.list.Elts[:len(s.list.Elts)-1] return @@ -106,9 +106,10 @@ func constraintItems(key string, n cue.Value, s *state) { elem := s.schema(n) ast.SetRelPos(elem, token.NoRelPos) s.add(n, arrayType, ast.NewList(&ast.Ellipsis{Type: elem})) + s.hasItems = true case cue.ListKind: - if !vto(VersionDraft2019_09).contains(s.schemaVersion) { + if !s.schemaVersion.is(vto(VersionDraft2019_09)) { // The list form is only supported up to 2019-09 s.errf(n, `from version %v onwards, the value of "items" must be an object or a boolean`, VersionDraft2020_12) return @@ -157,6 +158,10 @@ func constraintMinItems(key string, n cue.Value, s *state) { func constraintUniqueItems(key string, n cue.Value, s *state) { if s.boolValue(n) { + if s.schemaVersion.is(k8s) { + s.errf(n, "cannot set uniqueItems to true in a Kubernetes schema") + return + } list := s.addImport(n, "list") s.add(n, arrayType, ast.NewCall(ast.NewSel(list, "UniqueItems"))) } diff --git a/vendor/cuelang.org/go/encoding/jsonschema/constraints_combinator.go b/vendor/cuelang.org/go/encoding/jsonschema/constraints_combinator.go index 07ece912ab..087ac6b789 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/constraints_combinator.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/constraints_combinator.go @@ -33,7 +33,7 @@ func constraintAllOf(key string, n cue.Value, s *state) { } a := make([]ast.Expr, 0, len(items)) for _, v := range items { - x, sub := s.schemaState(v, s.allowedTypes) + x, sub := s.schemaState(v, s.allowedTypes, nil) s.allowedTypes &= sub.allowedTypes if sub.hasConstraints { // This might seem a little odd, since the actual @@ -79,7 +79,7 @@ func constraintAnyOf(key string, n cue.Value, s *state) { } a := make([]ast.Expr, 0, len(items)) for _, v := range items { - x, sub := s.schemaState(v, s.allowedTypes) + x, sub := s.schemaState(v, s.allowedTypes, nil) if sub.allowedTypes == 0 { // Nothing is allowed; omit. continue @@ -123,7 +123,7 @@ func constraintOneOf(key string, n cue.Value, s *state) { } a := make([]ast.Expr, 0, len(items)) for _, v := range items { - x, sub := s.schemaState(v, s.allowedTypes) + x, sub := s.schemaState(v, s.allowedTypes, nil) if sub.allowedTypes == 0 { // Nothing is allowed; omit continue @@ -198,14 +198,14 @@ func constraintIfThenElse(s *state) { return } var ifExpr, thenExpr, elseExpr ast.Expr - ifExpr, ifSub := s.schemaState(s.ifConstraint, s.allowedTypes) + ifExpr, ifSub := s.schemaState(s.ifConstraint, s.allowedTypes, nil) if hasThen { // The allowed types of the "then" constraint are constrained both // by the current constraints and the "if" constraint. - thenExpr, _ = s.schemaState(s.thenConstraint, s.allowedTypes&ifSub.allowedTypes) + thenExpr, _ = s.schemaState(s.thenConstraint, s.allowedTypes&ifSub.allowedTypes, nil) } if hasElse { - elseExpr, _ = s.schemaState(s.elseConstraint, s.allowedTypes) + elseExpr, _ = s.schemaState(s.elseConstraint, s.allowedTypes, nil) } if thenExpr == nil { thenExpr = top() diff --git a/vendor/cuelang.org/go/encoding/jsonschema/constraints_format.go b/vendor/cuelang.org/go/encoding/jsonschema/constraints_format.go index c6c578c9ab..22728b0a29 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/constraints_format.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/constraints_format.go @@ -26,37 +26,57 @@ type formatFuncInfo struct { f func(n cue.Value, s *state) } +// For reference, the Kubernetes-related format strings +// are defined here: +// https://github.com/kubernetes/apiextensions-apiserver/blob/aca9073a80bee92a0b77741b9c7ad444c49fe6be/pkg/apis/apiextensions/v1beta1/types_jsonschema.go#L73 + var formatFuncs = sync.OnceValue(func() map[string]formatFuncInfo { return map[string]formatFuncInfo{ "binary": {openAPI, formatTODO}, - "byte": {openAPI, formatTODO}, + "bsonobjectid": {k8s, formatTODO}, + "byte": {openAPI | k8s, formatTODO}, + "cidr": {k8s, formatTODO}, + "creditcard": {k8s, formatTODO}, "data": {openAPI, formatTODO}, - "date": {vfrom(VersionDraft7) | openAPI, formatDate}, - "date-time": {allVersions | openAPI, formatDateTime}, - "double": {openAPI, formatTODO}, - "duration": {vfrom(VersionDraft2019_09), formatTODO}, - "email": {allVersions | openAPI, formatTODO}, - "float": {openAPI, formatTODO}, - "hostname": {allVersions | openAPI, formatTODO}, + "date": {vfrom(VersionDraft7) | openAPI | k8s, formatDate}, + "date-time": {allVersions | openAPI | k8s, formatDateTime}, + "datetime": {k8s, formatDateTime}, + "double": {openAPI | k8s, formatTODO}, + "duration": {vfrom(VersionDraft2019_09) | k8s, formatTODO}, + "email": {allVersions | openAPI | k8s, formatTODO}, + "float": {openAPI | k8s, formatTODO}, + "hexcolor": {k8s, formatTODO}, + "hostname": {allVersions | openAPI | k8s, formatTODO}, "idn-email": {vfrom(VersionDraft7), formatTODO}, "idn-hostname": {vfrom(VersionDraft7), formatTODO}, - "int32": {openAPI, formatInt32}, - "int64": {openAPI, formatInt64}, - "ipv4": {allVersions | openAPI, formatTODO}, - "ipv6": {allVersions | openAPI, formatTODO}, + "int32": {openAPI | k8s, formatInt32}, + "int64": {openAPI | k8s, formatInt64}, + "ipv4": {allVersions | openAPI | k8s, formatTODO}, + "ipv6": {allVersions | openAPI | k8s, formatTODO}, "iri": {vfrom(VersionDraft7), formatURI}, "iri-reference": {vfrom(VersionDraft7), formatURIReference}, + "isbn": {k8s, formatTODO}, + "isbn10": {k8s, formatTODO}, + "isbn13": {k8s, formatTODO}, "json-pointer": {vfrom(VersionDraft6), formatTODO}, - "password": {openAPI, formatTODO}, + "mac": {k8s, formatTODO}, + "password": {openAPI | k8s, formatTODO}, "regex": {vfrom(VersionDraft7), formatRegex}, "relative-json-pointer": {vfrom(VersionDraft7), formatTODO}, + "rgbcolor": {k8s, formatTODO}, + "ssn": {k8s, formatTODO}, "time": {vfrom(VersionDraft7), formatTODO}, + "uint32": {k8s, formatUint32}, + "uint64": {k8s, formatUint64}, // TODO we should probably disallow non-ASCII URIs (IRIs) but // this is good enough for now. - "uri": {allVersions | openAPI, formatURI}, + "uri": {allVersions | openAPI | k8s, formatURI}, "uri-reference": {vfrom(VersionDraft6), formatURIReference}, "uri-template": {vfrom(VersionDraft6), formatTODO}, - "uuid": {vfrom(VersionDraft2019_09), formatTODO}, + "uuid": {vfrom(VersionDraft2019_09) | k8s, formatTODO}, + "uuid3": {k8s, formatTODO}, + "uuid4": {k8s, formatTODO}, + "uuid5": {k8s, formatTODO}, } }) @@ -77,13 +97,13 @@ func constraintFormat(key string, n cue.Value, s *state) { // we want unknown formats to be ignored even when StrictFeatures // is enabled, and StrictKeywords is closest to what we want. // Perhaps we should have a "lint" mode? - if s.cfg.StrictKeywords && s.schemaVersion != VersionOpenAPI { + if s.cfg.StrictKeywords && !s.schemaVersion.is(openAPILike) { s.errf(n, "unknown format %q", formatStr) } return } - if !finfo.versions.contains(s.schemaVersion) { - if s.cfg.StrictKeywords && s.schemaVersion != VersionOpenAPI { + if !s.schemaVersion.is(finfo.versions) { + if s.cfg.StrictKeywords && !s.schemaVersion.is(openAPILike) { s.errf(n, "format %q is not recognized in schema version %v", formatStr, s.schemaVersion) } return @@ -126,4 +146,12 @@ func formatInt64(n cue.Value, s *state) { s.add(n, numType, ast.NewIdent("int64")) } +func formatUint32(n cue.Value, s *state) { + s.add(n, numType, ast.NewIdent("uint32")) +} + +func formatUint64(n cue.Value, s *state) { + s.add(n, numType, ast.NewIdent("uint64")) +} + func formatTODO(n cue.Value, s *state) {} diff --git a/vendor/cuelang.org/go/encoding/jsonschema/constraints_generic.go b/vendor/cuelang.org/go/encoding/jsonschema/constraints_generic.go index e220c81f24..f7f5852cb0 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/constraints_generic.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/constraints_generic.go @@ -169,6 +169,15 @@ func constraintTitle(key string, n cue.Value, s *state) { s.title, _ = s.strValue(n) } +func constraintIntOrString(key string, n cue.Value, s *state) { + // See x-kubernetes-int-or-string in + // https://kubernetes.io/docs/reference/kubernetes-api/extend-resources/custom-resource-definition-v1/#JSONSchemaProps. + s.setTypeUsed(n, stringType) + s.setTypeUsed(n, numType) + s.add(n, numType, ast.NewIdent("int")) + s.allowedTypes &= cue.StringKind | cue.IntKind +} + func constraintType(key string, n cue.Value, s *state) { var types cue.Kind set := func(n cue.Value) { @@ -197,6 +206,9 @@ func constraintType(key string, n cue.Value, s *state) { case "array": types |= cue.ListKind s.setTypeUsed(n, arrayType) + // For OpenAPI, specifically keep track of whether type is array + // so we can mandate the "items" keyword. + s.isArray = true case "object": types |= cue.StructKind s.setTypeUsed(n, objectType) @@ -210,6 +222,12 @@ func constraintType(key string, n cue.Value, s *state) { case cue.StringKind: set(n) case cue.ListKind: + if openAPILike.contains(s.schemaVersion) { + // From https://spec.openapis.org/oas/v3.0.3.html#properties: + // "Value MUST be a string. Multiple types via an array are not supported." + s.errf(n, `value of "type" must be a string in %v`, s.schemaVersion) + return + } for i, _ := n.List(); i.Next(); { set(i.Value()) } diff --git a/vendor/cuelang.org/go/encoding/jsonschema/constraints_meta.go b/vendor/cuelang.org/go/encoding/jsonschema/constraints_meta.go index fdc7d4ff39..87c1ae98c1 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/constraints_meta.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/constraints_meta.go @@ -49,7 +49,7 @@ func constraintID(key string, n cue.Value, s *state) { // constraintSchema implements $schema, which // identifies this as a JSON schema and specifies its version. func constraintSchema(key string, n cue.Value, s *state) { - if !s.isRoot && !vfrom(VersionDraft2019_09).contains(s.schemaVersion) { + if !s.isRoot && !s.schemaVersion.is(vfrom(VersionDraft2019_09)) { // Before 2019-09, the $schema keyword was not allowed // to appear anywhere but the root. s.errf(n, "$schema can only appear at the root in JSON Schema version %v", s.schemaVersion) @@ -74,3 +74,10 @@ func constraintTODO(key string, n cue.Value, s *state) { s.errf(n, `keyword %q not yet implemented`, key) } } + +// constraintIgnore represents a constraint that we're deliberately +// ignoring, by contrast with [constraintTODO] that represents +// a constraint that we're definitely intending to implement +// at some point. +func constraintIgnore(key string, b cue.Value, s *state) { +} diff --git a/vendor/cuelang.org/go/encoding/jsonschema/constraints_object.go b/vendor/cuelang.org/go/encoding/jsonschema/constraints_object.go index c5a692129d..764aeda0a5 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/constraints_object.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/constraints_object.go @@ -15,54 +15,280 @@ package jsonschema import ( + "fmt" + "strings" + "cuelang.org/go/cue" "cuelang.org/go/cue/ast" + "cuelang.org/go/cue/ast/astutil" "cuelang.org/go/cue/token" - "cuelang.org/go/internal" ) // Object constraints +func constraintPreserveUnknownFields(key string, n cue.Value, s *state) { + // x-kubernetes-preserve-unknown-fields stops the API server decoding + // step from pruning fields which are not specified in the validation + // schema. This affects fields recursively, but switches back to normal + // pruning behaviour if nested properties or additionalProperties are + // specified in the schema. This can either be true or undefined. False + // is forbidden. + // Note: by experimentation, "nested properties" means "within a schema + // within a nested property" not "within a schema that has the properties keyword". + if !s.boolValue(n) { + s.errf(n, "x-kubernetes-preserve-unknown-fields value may not be false") + return + } + // TODO check that it's specified on an object type. This requires + // either setting a bool (hasPreserveUnknownFields?) and checking + // later or making a new phase and placing this after "type" but + // before "allOf", because it's important that this value be + // passed down recursively to allOf and friends. + s.preserveUnknownFields = true +} + +func constraintGroupVersionKind(key string, n cue.Value, s *state) { + // x-kubernetes-group-version-kind is used by Kubernetes schemas + // to indicate the required values of the apiVersion and kind fields. + items := s.listItems(key, n, false) + if len(items) != 1 { + // When there's more than one item, we _could_ generate + // a disjunction over apiVersion and kind but for now, we'll + // just ignore it. + // TODO implement support for multiple items + return + } + var group, version string + s.processMap(items[0], func(key string, n cue.Value) { + if strings.HasPrefix(key, "x-") { + // TODO are x- extension properties actually allowed in this context? + return + } + switch key { + case "group": + group, _ = s.strValue(n) + case "kind": + s.k8sResourceKind, _ = s.strValue(n) + case "version": + version, _ = s.strValue(n) + default: + s.errf(n, "unknown field %q in x-kubernetes-group-version-kind item", key) + } + }) + if s.k8sResourceKind == "" || version == "" { + s.errf(n, "x-kubernetes-group-version-kind needs both kind and version fields") + } + if group == "" { + s.k8sAPIVersion = version + } else { + s.k8sAPIVersion = group + "/" + version + } +} + func constraintAdditionalProperties(key string, n cue.Value, s *state) { switch n.Kind() { case cue.BoolKind: - s.closeStruct = !s.boolValue(n) + if s.boolValue(n) { + s.openness = explicitlyOpen + } else { + if s.schemaVersion == VersionKubernetesCRD { + s.errf(n, "additionalProperties may not be set to false in a CRD schema") + return + } + s.openness = explicitlyClosed + } _ = s.object(n) case cue.StructKind: - s.closeStruct = true obj := s.object(n) if len(obj.Elts) == 0 { obj.Elts = append(obj.Elts, &ast.Field{ Label: ast.NewList(ast.NewIdent("string")), Value: s.schema(n), }) + s.openness = allFieldsCovered return } // [!~(properties|patternProperties)]: schema existing := append(s.patterns, excludeFields(obj.Elts)...) - f := internal.EmbedStruct(ast.NewStruct(&ast.Field{ + expr, _ := s.schemaState(n, allTypes, func(s *state) { + s.preserveUnknownFields = false + }) + f := embedStruct(ast.NewStruct(&ast.Field{ Label: ast.NewList(ast.NewBinExpr(token.AND, existing...)), - Value: s.schema(n), + Value: expr, })) obj.Elts = append(obj.Elts, f) + s.openness = allFieldsCovered default: s.errf(n, `value of "additionalProperties" must be an object or boolean`) + return } + s.hasAdditionalProperties = true } +func embedStruct(s *ast.StructLit) *ast.EmbedDecl { + e := &ast.EmbedDecl{Expr: s} + if len(s.Elts) == 1 { + d := s.Elts[0] + astutil.CopyPosition(e, d) + ast.SetRelPos(d, token.NoSpace) + astutil.CopyComments(e, d) + ast.SetComments(d, nil) + if f, ok := d.(*ast.Field); ok { + ast.SetRelPos(f.Label, token.NoSpace) + } + } + s.Lbrace = token.Newline.Pos() + s.Rbrace = token.NoSpace.Pos() + return e +} + +// constraintDependencies is used to implement all of the dependencies, +// dependentSchemas and dependentRequired keywords. func constraintDependencies(key string, n cue.Value, s *state) { - // Schema and property dependencies. - // TODO: the easiest implementation is with comprehensions. - // The nicer implementation is with disjunctions. This has to be done - // at the very end, replacing properties. - /* - *{ property?: _|_ } | { - property: _ - schema - } - */ + allowSchemas := false + allowRequired := false + switch key { + case "dependencies": + allowSchemas = true + allowRequired = true + case "dependentSchemas": + allowSchemas = true + case "dependentRequired": + allowRequired = true + } + + if n.Kind() != cue.StructKind { + s.errf(n, `"%q expected an object, found %v`, key, n.Kind()) + return + } + // Our approach here is to make an outer-level struct which contains + // all the fields we wish to test for as optional fields; then we add + // a comprehension for each dependencies entry that tests for presence + // and adds an appropriate constraint. + // + // e.g. + // "dependencies": { + // "x": ["a", "b"], + // "y": {"maxProperties": 4} + // } + // + // is translated to: + // + // { + // x?: _ + // if x != _|_ { + // a!: _ + // b!: _ + // } + // y?: _ + // if y != _|_ { + // struct.MaxFields(4) + // } + // } + + obj := s.object(n) + count := 0 + s.processMap(n, func(key string, n cue.Value) { + var ident *ast.Ident + // TODO we could potentially avoid declaring the field + // by checking whether there's a field already in + // scope with the correct name. + var label ast.Label + if ast.IsValidIdent(key) { + // TODO if the inner schema contains a reference to some + // outer-level entity that has the same identifier then this + // will stop that from working correctly. It would be nice + // if astutil.Sanitize was clever enough to deal with this + // kind of alias issue. + // Possible workaround: + // - always make a local alias + // - always make a local alias when the value is a schema but not when + // it's a list + // - when the value is a schema, generate it and then inspect the + // resulting syntax to check for references. + // - fix astutil.Sanitize + ident = ast.NewIdent(key) + label = ident + } else { + ident = ast.NewIdent(fmt.Sprintf("_t%d", count)) + count++ + label = &ast.Alias{ + Ident: ident, + Expr: ast.NewString(key), + } + } + // TODO this is not quite right, because by adding this optional + // field, we allow the field to exist, and that's not to-spec. + // In particular, see the "additionalProperties doesn't consider dependentSchemas" + // test in testdata/external/tests/draft2019-09/additionalProperties.json + // which this approach causes to succeed inappropriately. + // Given that people are unlikely to be checking for the existence of a field + // without that field being a possibility, this is probably OK for now. + // A better approach would involve "self" or otherwise obtaining a reference + // to the current struct value. + obj.Elts = append(obj.Elts, &ast.Field{ + Label: label, + Constraint: token.OPTION, + Value: ast.NewIdent("_"), + }) + var consequence *ast.StructLit + switch n.Kind() { + case cue.ListKind: + if !allowRequired { + s.errf(n, "expected schema but got %v", n.Kind()) + return + } + required := &ast.StructLit{} + for i, _ := n.List(); i.Next(); { + f, ok := s.strValue(i.Value()) + if !ok { + return + } + required.Elts = append(required.Elts, &ast.Field{ + Label: ast.NewString(f), + Constraint: token.NOT, + Value: ast.NewIdent("_"), + }) + } + consequence = required + + case cue.StructKind, cue.BoolKind: + if !allowSchemas { + s.errf(n, "expected schema but got %v", n.Kind()) + return + } + switch s := s.schema(n).(type) { + case *ast.StructLit: + consequence = s + default: + consequence = &ast.StructLit{ + Elts: []ast.Decl{ + &ast.EmbedDecl{ + Expr: s, + }, + }, + } + } + default: + s.errf(n, "dependency value must be array or schema. found %v", n.Kind()) + return + } + obj.Elts = append(obj.Elts, &ast.Comprehension{ + Clauses: []ast.Clause{ + &ast.IfClause{ + Condition: ast.NewBinExpr(token.NEQ, ident, &ast.BottomLit{}), + }, + }, + Value: consequence, + }) + }) + // Note: include an empty struct literal so that the comprehension + // does cause the struct to disallow non-struct values. + // See https://cuelang.org/issue/3994 + obj.Elts = append(obj.Elts, &ast.StructLit{}) } func constraintMaxProperties(key string, n cue.Value, s *state) { @@ -82,7 +308,6 @@ func constraintPatternProperties(key string, n cue.Value, s *state) { s.errf(n, `value of "patternProperties" must be an object, found %v`, n.Kind()) } obj := s.object(n) - existing := excludeFields(s.obj.Elts) s.processMap(n, func(key string, n cue.Value) { if !s.checkRegexp(n, key) { return @@ -95,12 +320,9 @@ func constraintPatternProperties(key string, n cue.Value, s *state) { &ast.UnaryExpr{Op: token.NMAT, X: ast.NewString(key)}) // We'll make a pattern constraint of the form: - // [pattern & !~(properties)]: schema - f := internal.EmbedStruct(ast.NewStruct(&ast.Field{ - Label: ast.NewList(ast.NewBinExpr( - token.AND, - append([]ast.Expr{&ast.UnaryExpr{Op: token.MAT, X: ast.NewString(key)}}, existing...)..., - )), + // [pattern]: schema + f := embedStruct(ast.NewStruct(&ast.Field{ + Label: ast.NewList(&ast.UnaryExpr{Op: token.MAT, X: ast.NewString(key)}), Value: s.schema(n), })) ast.SetRelPos(f, token.NewSection) @@ -108,22 +330,68 @@ func constraintPatternProperties(key string, n cue.Value, s *state) { }) } +func constraintEmbeddedResource(key string, n cue.Value, s *state) { + // TODO: + // - should fail if type has not been specified as "object" + // - should fail if neither x-kubernetes-preserve-unknown-fields or properties have been specified + + // Note: this runs in a phase before the properties keyword so + // that the embedded expression always comes first in the struct + // literal. + resourceDefinitionPath := cue.MakePath(cue.Hid("_embeddedResource", "_")) + obj := s.object(n) + + // Generate a reference to a shared schema that all embedded resources + // can share. If it already exists, that's fine. + // TODO add an attribute to make it clear what's going on here + // when encoding a CRD from CUE? + s.builder.put(resourceDefinitionPath, ast.NewStruct( + "apiVersion", token.NOT, ast.NewIdent("string"), + "kind", token.NOT, ast.NewIdent("string"), + "metadata", token.OPTION, ast.NewStruct(&ast.Ellipsis{}), + ), nil) + refExpr, err := s.builder.getRef(resourceDefinitionPath) + if err != nil { + s.errf(n, `cannot get reference to embedded resource definition: %v`, err) + } else { + obj.Elts = append(obj.Elts, &ast.EmbedDecl{ + Expr: refExpr, + }) + } + s.allowedTypes &= cue.StructKind +} + func constraintProperties(key string, n cue.Value, s *state) { obj := s.object(n) if n.Kind() != cue.StructKind { s.errf(n, `"properties" expected an object, found %v`, n.Kind()) } - + hasKind := false + hasAPIVersion := false s.processMap(n, func(key string, n cue.Value) { // property?: value name := ast.NewString(key) - expr, state := s.schemaState(n, allTypes) + expr, state := s.schemaState(n, allTypes, func(s *state) { + s.preserveUnknownFields = false + }) f := &ast.Field{Label: name, Value: expr} if doc := state.comment(); doc != nil { ast.SetComments(f, []*ast.CommentGroup{doc}) } - f.Optional = token.Blank.Pos() + f.Constraint = token.OPTION + if s.k8sResourceKind != "" && key == "kind" { + // Define a regular field with the specified kind value. + f.Constraint = token.ILLEGAL + f.Value = ast.NewString(s.k8sResourceKind) + hasKind = true + } + if s.k8sAPIVersion != "" && key == "apiVersion" { + // Define a regular field with the specified value. + f.Constraint = token.ILLEGAL + f.Value = ast.NewString(s.k8sAPIVersion) + hasAPIVersion = true + } if len(obj.Elts) > 0 && len(f.Comments()) > 0 { // TODO: change formatter such that either a NewSection on the // field or doc comment will cause a new section. @@ -134,16 +402,32 @@ func constraintProperties(key string, n cue.Value, s *state) { case *ast.StructLit: obj.Elts = append(obj.Elts, addTag(name, "deprecated", "")) default: - f.Attrs = append(f.Attrs, internal.NewAttr("deprecated", "")) + f.Attrs = append(f.Attrs, &ast.Attribute{Text: "@deprecated()"}) } } obj.Elts = append(obj.Elts, f) }) + // It's not entirely clear whether it's OK to have an x-kubernetes-group-version-kind + // keyword without the kind and apiVersion properties but be defensive + // and add them anyway even if they're not there already. + if s.k8sAPIVersion != "" && !hasAPIVersion { + obj.Elts = append(obj.Elts, &ast.Field{ + Label: ast.NewString("apiVersion"), + Value: ast.NewString(s.k8sAPIVersion), + }) + } + if s.k8sResourceKind != "" && !hasKind { + obj.Elts = append(obj.Elts, &ast.Field{ + Label: ast.NewString("kind"), + Value: ast.NewString(s.k8sResourceKind), + }) + } + s.hasProperties = true } func constraintPropertyNames(key string, n cue.Value, s *state) { // [=~pattern]: _ - if names, _ := s.schemaState(n, cue.StringKind); !isTop(names) { + if names, _ := s.schemaState(n, cue.StringKind, nil); !isTop(names) { x := ast.NewStruct(ast.NewList(names), top()) s.add(n, objectType, x) } @@ -183,10 +467,9 @@ func constraintRequired(key string, n cue.Value, s *state) { obj.Elts = append(obj.Elts, f) continue } - if f.Optional == token.NoPos { + if f.Constraint == token.NOT { s.errf(n, "duplicate required field %q", str) } f.Constraint = token.NOT - f.Optional = token.NoPos } } diff --git a/vendor/cuelang.org/go/encoding/jsonschema/crd.cue b/vendor/cuelang.org/go/encoding/jsonschema/crd.cue new file mode 100644 index 0000000000..1d66ee96f1 --- /dev/null +++ b/vendor/cuelang.org/go/encoding/jsonschema/crd.cue @@ -0,0 +1,61 @@ +package jsonschema + +// input holds the parsed YAML document, which may contain multiple +// Kubernetes resources, in which case it will be an array. +input!: _ + +// specs holds the resulting CRD specs: when there was only +// a single resource in the input, we'll get an array with one +// element. +// TODO(rog) replace comparisons to bottom with whatever the +// correct replacement will be. +specs: { + [...] + if (input & [...]) != _|_ { + // It's an array: include only elements that look like CRDs. + [ + for doc in input + if (doc & {#crdlike, ...}) != _|_ { + // Note: don't check for unification with #CRDSpec above because + // we want it to fail if it doesn't unify with the entirety of #CRDSpec, + // not just exclude the document. + doc + #CRDSpec + }, + ] + } + if (input & [...]) == _|_ { + // It's a single document. Include it if it looks like a CRD. + if (input & {#crdlike, ...}) != _|_ { + [{input, #CRDSpec}] + } + } +} + +#crdlike: { + apiVersion!: "apiextensions.k8s.io/v1" + kind!: "CustomResourceDefinition" +} @go(crdLike) + +// CRDSpec defines a subset of the CRD schema, suitable for filtering +// CRDs based on common criteria like group and name. +#CRDSpec: { + #crdlike + apiVersion!: "apiextensions.k8s.io/v1" + kind!: "CustomResourceDefinition" + spec!: { + group!: string + names!: { + kind!: string + plural!: string + singular!: string + } + scope!: "Namespaced" | "Cluster" + versions!: [... { + name!: string + schema!: { + openAPIV3Schema!: _ @go(,type="cuelang.org/go/cue".Value) + } + }] + } +} diff --git a/vendor/cuelang.org/go/encoding/jsonschema/crd.go b/vendor/cuelang.org/go/encoding/jsonschema/crd.go new file mode 100644 index 0000000000..7788a81e8b --- /dev/null +++ b/vendor/cuelang.org/go/encoding/jsonschema/crd.go @@ -0,0 +1,155 @@ +package jsonschema + +import ( + _ "embed" + "fmt" + + "cuelang.org/go/cue" + "cuelang.org/go/cue/ast" + "cuelang.org/go/cue/token" +) + +//go:generate go tool cue exp gengotypes . + +//go:embed crd.cue +var crdCUE []byte + +// CRDConfig holds configuration for [ExtractCRDs]. +// Although this empty currently, it allows configuration +// to be added in the future without breaking the API. +type CRDConfig struct{} + +// ExtractedCRD holds an extracted Kubernetes CRD and the data it was derived from. +type ExtractedCRD struct { + // Versions holds the CUE schemas extracted from the CRD: one per + // version. + Versions map[string]*ast.File + + // VersionToPath maps each version to the path + // within Source containing the schema for that version. + VersionToPath map[string]cue.Path + + // Data holds chosen fields extracted from the source CRD document. + Data *CRDSpec + + // Source holds the raw CRD document from which Data is derived. + Source cue.Value +} + +// ExtractCRDs extracts Kubernetes custom resource definitions +// (CRDs) from the given data. If data holds an array, each element +// of the array might itself be a Kubernetes resource. +// +// While the data must hold Kubernetes resources, those resources +// need not all be CRDs: resources with a kind that's not "CustomResourceDefinition" +// will be ignored. +// +// If cfg is nil, it's equivalent to passing a pointer to the zero-valued [CRDConfig]. +func ExtractCRDs(data cue.Value, cfg *CRDConfig) ([]*ExtractedCRD, error) { + crdInfos, crdValues, err := decodeCRDSpecs(data) + if err != nil { + return nil, fmt.Errorf("cannot decode CRD: %v", err) + } + crds := make([]*ExtractedCRD, len(crdInfos)) + for crdIndex, crd := range crdInfos { + versions := make(map[string]*ast.File) + versionToPath := make(map[string]cue.Path) + for i, version := range crd.Spec.Versions { + rootPath := cue.MakePath( + cue.Str("spec"), + cue.Str("versions"), + cue.Index(i), + cue.Str("schema"), + cue.Str("openAPIV3Schema"), + ) + versionToPath[version.Name] = rootPath + f, err := Extract(crdValues[crdIndex], &Config{ + PkgName: version.Name, + // There are several kubernetes-related keywords that aren't implemented yet + StrictFeatures: false, + StrictKeywords: true, + Root: "#" + mustCUEPathToJSONPointer(rootPath), + SingleRoot: true, + DefaultVersion: VersionKubernetesCRD, + }) + if err != nil { + return nil, err + } + namespaceConstraint := token.OPTION + if crd.Spec.Scope == "Namespaced" { + namespaceConstraint = token.NOT + } + // TODO provide a way to let this refer to a shared definition + // in another package as the canonical definition for the schema. + f.Decls = append(f.Decls, + &ast.Field{ + Label: ast.NewIdent("apiVersion"), + Value: ast.NewString(crd.Spec.Group + "/" + version.Name), + }, + &ast.Field{ + Label: ast.NewIdent("kind"), + Value: ast.NewString(crd.Spec.Names.Kind), + }, + &ast.Field{ + Label: ast.NewIdent("metadata"), + Constraint: token.NOT, + Value: ast.NewStruct( + "name", token.NOT, ast.NewIdent("string"), + "namespace", namespaceConstraint, ast.NewIdent("string"), + // TODO inline struct lit + "labels", token.OPTION, ast.NewStruct( + ast.NewList(ast.NewIdent("string")), ast.NewIdent("string"), + ), + "annotations", token.OPTION, ast.NewStruct( + ast.NewList(ast.NewIdent("string")), ast.NewIdent("string"), + ), + // The above fields aren't exhaustive. + // TODO it would be nicer to refer to the actual #ObjectMeta + // definition instead (and for that to be the case for embedded + // resources in general) but that needs a deeper fix inside + // encoding/jsonschema. + &ast.Ellipsis{}, + ), + }, + ) + versions[version.Name] = f + } + crds[crdIndex] = &ExtractedCRD{ + Versions: versions, + VersionToPath: versionToPath, + Data: crdInfos[crdIndex], + Source: crdValues[crdIndex], + } + } + return crds, nil +} + +// decodeCRDSpecs decodes the CRD(s) held in the given value. +// It returns both the (partially) decoded CRDs and the values +// they were decoded from. +func decodeCRDSpecs(v cue.Value) ([]*CRDSpec, []cue.Value, error) { + ctx := v.Context() + + // Check against the CUE version of the schema which can + // do more detailed checks, including checking required fields, + // before decoding into the Go struct. + + // TODO it would be nice to avoid compiling crdCUE every time, but + // that's not possible given the restrictions on combining cue.Values + // derived from different contexts. + crdSchema := ctx.CompileBytes(crdCUE) + crdSchema = crdSchema.FillPath(cue.MakePath(cue.Str("input")), v) + specsv := crdSchema.LookupPath(cue.MakePath(cue.Str("specs"))) + if err := specsv.Err(); err != nil { + return nil, nil, err + } + var specs []*CRDSpec + var specsValues []cue.Value + if err := specsv.Decode(&specs); err != nil { + return nil, nil, err + } + if err := specsv.Decode(&specsValues); err != nil { + return nil, nil, err + } + return specs, specsValues, nil +} diff --git a/vendor/cuelang.org/go/encoding/jsonschema/cue_types_gen.go b/vendor/cuelang.org/go/encoding/jsonschema/cue_types_gen.go new file mode 100644 index 0000000000..ea97b2108a --- /dev/null +++ b/vendor/cuelang.org/go/encoding/jsonschema/cue_types_gen.go @@ -0,0 +1,43 @@ +// Code generated by "cue exp gengotypes"; DO NOT EDIT. + +package jsonschema + +import ( + "cuelang.org/go/cue" +) + +type crdLike struct { + ApiVersion string `json:"apiVersion"` + + Kind string `json:"kind"` +} + +// CRDSpec defines a subset of the CRD schema, suitable for filtering +// CRDs based on common criteria like group and name. +type CRDSpec struct { + ApiVersion string `json:"apiVersion"` + + Kind string `json:"kind"` + + Spec struct { + Group string `json:"group"` + + Names struct { + Kind string `json:"kind"` + + Plural string `json:"plural"` + + Singular string `json:"singular"` + } `json:"names"` + + Scope string `json:"scope"` + + Versions []struct { + Name string `json:"name"` + + Schema struct { + OpenAPIV3Schema cue.Value `json:"openAPIV3Schema"` + } `json:"schema"` + } `json:"versions"` + } `json:"spec"` +} diff --git a/vendor/cuelang.org/go/encoding/jsonschema/decode.go b/vendor/cuelang.org/go/encoding/jsonschema/decode.go index 1a8a0eb3e9..7c671017c3 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/decode.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/decode.go @@ -24,7 +24,7 @@ import ( "net/url" "regexp" "regexp/syntax" - "sort" + "slices" "strconv" "strings" @@ -34,7 +34,6 @@ import ( "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" "cuelang.org/go/internal" - "cuelang.org/go/mod/module" ) const ( @@ -102,6 +101,9 @@ type definedSchema struct { // schema holds the actual syntax for the schema. This // is nil if the entry was created by a reference only. schema ast.Expr + + // comment holds any doc comment associated with the above schema. + comment *ast.CommentGroup } // addImport registers @@ -120,19 +122,33 @@ func (d *decoder) addImport(n cue.Value, pkg string) *ast.Ident { func (d *decoder) decode(v cue.Value) *ast.File { var defsRoot cue.Value + // docRoot represents the root of the actual data, by contrast + // with the "root" value as specified in [Config.Root] which + // represents the root of the schemas to be decoded. + docRoot := v if d.cfg.Root != "" { - defsPath, err := parseRootRef(d.cfg.Root) + rootPath, err := parseRootRef(d.cfg.Root) if err != nil { d.errf(cue.Value{}, "invalid Config.Root value %q: %v", d.cfg.Root, err) return nil } - defsRoot = v.LookupPath(defsPath) - if !defsRoot.Exists() && d.cfg.AllowNonExistentRoot { - defsRoot = v.Context().CompileString("{}") - } else if defsRoot.Kind() != cue.StructKind { - d.errf(defsRoot, "value at path %v must be struct containing definitions but is actually %v", d.cfg.Root, defsRoot) + root := v.LookupPath(rootPath) + if !root.Exists() && !d.cfg.AllowNonExistentRoot { + d.errf(v, "root value at path %v does not exist", d.cfg.Root) return nil } + if d.cfg.SingleRoot { + v = root + } else { + if !root.Exists() { + root = v.Context().CompileString("{}") + } + if root.Kind() != cue.StructKind { + d.errf(root, "value at path %v must be struct containing definitions but is actually %v", d.cfg.Root, root) + return nil + } + defsRoot = root + } } var rootInfo schemaInfo @@ -158,7 +174,7 @@ func (d *decoder) decode(v cue.Value) *ast.File { id: d.rootID, }, isRoot: true, - pos: v, + pos: docRoot, } if defsRoot.Exists() { @@ -166,7 +182,11 @@ func (d *decoder) decode(v cue.Value) *ast.File { // containing a field for each definition. constraintAddDefinitions("schemas", defsRoot, root) } else { - expr, state := root.schemaState(v, allTypes) + expr, state := root.schemaState(v, allTypes, func(s *state) { + // We want the top level state to be treated as root even + // though it's some levels below the actual document top level. + s.isRoot = true + }) if state.allowedTypes == 0 { root.errf(v, "constraints are not possible to satisfy") return nil @@ -216,7 +236,7 @@ func (d *decoder) decode(v cue.Value) *ast.File { // have been mapped to an external location. for _, def := range d.defs { if def.schema != nil && def.importPath != "" { - d.cfg.DefineSchema(def.importPath, def.path, def.schema) + d.cfg.DefineSchema(def.importPath, def.path, def.schema, def.comment) } } } @@ -374,7 +394,7 @@ var coreToCUE = []cue.Kind{ objectType: cue.StructKind, } -func kindToAST(k cue.Kind) ast.Expr { +func kindToAST(k cue.Kind, explicitOpen bool) ast.Expr { switch k { case cue.NullKind: // TODO: handle OpenAPI restrictions. @@ -392,6 +412,9 @@ func kindToAST(k cue.Kind) ast.Expr { case cue.ListKind: return ast.NewList(&ast.Ellipsis{}) case cue.StructKind: + if explicitOpen { + return ast.NewStruct() + } return ast.NewStruct(&ast.Ellipsis{}) } panic(fmt.Errorf("unexpected kind %v", k)) @@ -413,8 +436,8 @@ type constraintInfo struct { constraints []ast.Expr } -func (c *constraintInfo) setTypeUsed(n cue.Value, t coreType) { - c.typ = kindToAST(coreToCUE[t]) +func (c *constraintInfo) setTypeUsed(n cue.Value, t coreType, explicitOpen bool) { + c.typ = kindToAST(coreToCUE[t], explicitOpen) setPos(c.typ, n) ast.SetRelPos(c.typ, token.NoRelPos) } @@ -435,7 +458,7 @@ func (s *state) setTypeUsed(n cue.Value, t coreType) { if int(t) >= len(s.types) { panic(fmt.Errorf("type out of range %v/%v", int(t), len(s.types))) } - s.types[t].setTypeUsed(n, t) + s.types[t].setTypeUsed(n, t, s.cfg.OpenOnlyWhenExplicit) } type state struct { @@ -454,11 +477,6 @@ type state struct { exclusiveMin bool // For OpenAPI and legacy support. exclusiveMax bool // For OpenAPI and legacy support. - // Keep track of whether a $ref keyword is present, - // because pre-2019-09 schemas ignore sibling keywords - // to $ref. - hasRefKeyword bool - // isRoot holds whether this state is at the root // of the schema. isRoot bool @@ -476,8 +494,7 @@ type state struct { obj *ast.StructLit objN cue.Value // used for adding obj to constraints - closeStruct bool - patterns []ast.Expr + patterns []ast.Expr list *ast.ListLit @@ -491,8 +508,48 @@ type state struct { // // "items": [] listItemsIsArray bool + + // The following fields are used when the version is + // [VersionKubernetesCRD] to check that "properties" and + // "additionalProperties" may not be specified together. + hasProperties bool + hasAdditionalProperties bool + + // Keep track of whether "items" and "type": "array" have been specified, because + // in OpenAPI it's mandatory when "type" is "array". + hasItems bool + isArray bool + + // Keep track of whether a $ref keyword is present, + // because pre-2019-09 schemas ignore sibling keywords + // to $ref. + hasRefKeyword bool + + // Keep track of whether we're preserving existing fields, + // which is preserved recursively by default, and is + // reset within properties or additionalProperties. + preserveUnknownFields bool + + // k8sResourceKind and k8sAPIVersion record values from the + // x-kubernetes-group-version-kind keyword + // for the kind and apiVersion properties respectively. + k8sResourceKind string + k8sAPIVersion string + + // Keep track of whether the object has been explicitly + // closed or opened (see [Config.OpenOnlyWhenExplicit]). + openness openness } +type openness int + +const ( + implicitlyOpen openness = iota + explicitlyOpen // explicitly opened, e.g. additionalProperties: true + explicitlyClosed // explicitly closed, e.g. additionalProperties: false + allFieldsCovered // complete pattern present, e.g. additionalProperties: type: string +) + // schemaInfo holds information about a schema // after it has been created. type schemaInfo struct { @@ -528,27 +585,35 @@ func (s *state) object(n cue.Value) *ast.StructLit { if s.obj == nil { s.obj = &ast.StructLit{} s.objN = n - - if s.id != nil { - s.obj.Elts = append(s.obj.Elts, s.idTag()) - } } return s.obj } func (s *state) finalizeObject() { + if s.obj == nil && s.schemaVersion == VersionKubernetesCRD && (s.allowedTypes&cue.StructKind) != 0 && s.preserveUnknownFields { + // When x-kubernetes-preserve-unknown-fields is set, we need + // an explicit ellipsis even though kindToAST won't have added + // one, so make sure there's an object. + _ = s.object(s.pos) + } if s.obj == nil { return } - - var e ast.Expr - if s.closeStruct { + if s.preserveUnknownFields { + s.openness = explicitlyOpen + } + var e ast.Expr = s.obj + if s.cfg.OpenOnlyWhenExplicit && s.openness == implicitlyOpen { + // Nothing to do: the struct is implicitly open but + // we've been directed to leave it like that. + } else if s.openness == allFieldsCovered { + // Nothing to do: there is a pattern constraint that covers all + // possible fields. + } else if s.openness == explicitlyClosed { e = ast.NewCall(ast.NewIdent("close"), s.obj) } else { s.obj.Elts = append(s.obj.Elts, &ast.Ellipsis{}) - e = s.obj } - s.add(s.objN, objectType, e) } @@ -581,7 +646,7 @@ func (s *state) finalize() (e ast.Expr) { if s.allowedTypes == 0 { // Nothing is possible. This isn't a necessarily a problem, as // we might be inside an allOf or oneOf with other valid constraints. - return bottom() + return errorDisallowed() } s.finalizeObject() @@ -590,13 +655,17 @@ func (s *state) finalize() (e ast.Expr) { disjuncts := []ast.Expr{} // Sort literal structs and list last for nicer formatting. - sort.SliceStable(s.types[arrayType].constraints, func(i, j int) bool { - _, ok := s.types[arrayType].constraints[i].(*ast.ListLit) - return !ok + // Use a stable sort so that the relative order of constraints + // is otherwise kept as-is, for the sake of deterministic output. + slices.SortStableFunc(s.types[arrayType].constraints, func(a, b ast.Expr) int { + _, aList := a.(*ast.ListLit) + _, bList := b.(*ast.ListLit) + return cmpBool(aList, bList) }) - sort.SliceStable(s.types[objectType].constraints, func(i, j int) bool { - _, ok := s.types[objectType].constraints[i].(*ast.StructLit) - return !ok + slices.SortStableFunc(s.types[objectType].constraints, func(a, b ast.Expr) int { + _, aStruct := a.(*ast.StructLit) + _, bStruct := b.(*ast.StructLit) + return cmpBool(aStruct, bStruct) }) type excludeInfo struct { @@ -639,7 +708,7 @@ func (s *state) finalize() (e ast.Expr) { case allowed: npossible++ if s.knownTypes&k != 0 { - disjuncts = append(disjuncts, kindToAST(k)) + disjuncts = append(disjuncts, kindToAST(k, s.cfg.OpenOnlyWhenExplicit)) } } } @@ -691,8 +760,8 @@ func (s *state) finalize() (e ast.Expr) { } } - // If an "$id" exists and has not been included in any object constraints - if s.id != nil && s.obj == nil { + // If an "$id" exists, make sure it's present in the output. + if s.id != nil { if st, ok := e.(*ast.StructLit); ok { st.Elts = append([]ast.Decl{s.idTag()}, st.Elts...) } else { @@ -707,6 +776,24 @@ func (s *state) finalize() (e ast.Expr) { return e } +// cmpBool returns +// +// -1 if x is less than y, +// 0 if x equals y, +// +1 if x is greater than y, +// +// where false is ordered before true. +func cmpBool(x, y bool) int { + switch { + case !x && y: + return -1 + case x && !y: + return +1 + default: + return 0 + } +} + func (s schemaInfo) comment() *ast.CommentGroup { // Create documentation. doc := strings.TrimSpace(s.title) @@ -725,14 +812,17 @@ func (s schemaInfo) comment() *ast.CommentGroup { } func (s *state) schema(n cue.Value) ast.Expr { - expr, _ := s.schemaState(n, allTypes) + expr, _ := s.schemaState(n, allTypes, nil) return expr } // schemaState returns a new state value derived from s. // n holds the JSONSchema node to translate to a schema. // types holds the set of possible types that the value can hold. -func (s0 *state) schemaState(n cue.Value, types cue.Kind) (expr ast.Expr, ingo schemaInfo) { +// +// If init is not nil, it is called on the newly created state value +// before doing anything else. +func (s0 *state) schemaState(n cue.Value, types cue.Kind, init func(*state)) (expr ast.Expr, info schemaInfo) { s := &state{ up: s0, schemaInfo: schemaInfo{ @@ -740,16 +830,20 @@ func (s0 *state) schemaState(n cue.Value, types cue.Kind) (expr ast.Expr, ingo s allowedTypes: types, knownTypes: allTypes, }, - decoder: s0.decoder, - pos: n, - isRoot: s0.isRoot && n == s0.pos, + decoder: s0.decoder, + pos: n, + isRoot: s0.isRoot && n == s0.pos, + preserveUnknownFields: s0.preserveUnknownFields, + } + if init != nil { + init(s) } defer func() { // Perhaps replace the schema expression with a reference. - expr = s.maybeDefine(expr) + expr = s.maybeDefine(expr, info) }() if n.Kind() == cue.BoolKind { - if vfrom(VersionDraft6).contains(s.schemaVersion) { + if s.schemaVersion.is(vfrom(VersionDraft6)) { // From draft6 onwards, boolean values signify a schema that always passes or fails. // TODO if false, set s.allowedTypes and s.knownTypes to zero? return boolSchema(s.boolValue(n)), s.schemaInfo @@ -770,32 +864,30 @@ func (s0 *state) schemaState(n cue.Value, types cue.Kind) (expr ast.Expr, ingo s // is >=2019-19 because $schema could be used to change the version. s.hasRefKeyword = true } - if strings.HasPrefix(key, "x-") { - // A keyword starting with a leading x- is clearly - // not intended to be a valid keyword, and is explicitly - // allowed by OpenAPI. It seems reasonable that - // this is not an error even with StrictKeywords enabled. - return - } // Convert each constraint into a either a value or a functor. c := constraintMap[key] if c == nil { + if strings.HasPrefix(key, "x-") { + // A keyword starting with a leading x- is clearly + // not intended to be a valid keyword, and is explicitly + // allowed by OpenAPI. It seems reasonable that + // this is not an error even with StrictKeywords enabled. + return + } if pass == 0 && s.cfg.StrictKeywords { // TODO: value is not the correct position, albeit close. Fix this. - s.warnf(value.Pos(), "unknown keyword %q", key) + s.warnUnrecognizedKeyword(key, value, "unknown keyword %q", key) } return } if c.phase != pass { return } - if !c.versions.contains(s.schemaVersion) { - if s.cfg.StrictKeywords { - s.warnf(value.Pos(), "keyword %q is not supported in JSON schema version %v", key, s.schemaVersion) - } + if !s.schemaVersion.is(c.versions) { + s.warnUnrecognizedKeyword(key, value, "keyword %q is not supported in JSON schema version %v", key, s.schemaVersion) return } - if pass > 0 && !vfrom(VersionDraft2019_09).contains(s.schemaVersion) && s.hasRefKeyword && key != "$ref" { + if pass > 0 && !s.schemaVersion.is(vfrom(VersionDraft2019_09)) && s.hasRefKeyword && key != "$ref" { // We're using a schema version that ignores keywords alongside $ref. // // Note that we specifically exclude pass 0 (the pass in which $schema is checked) @@ -804,25 +896,62 @@ func (s0 *state) schemaState(n cue.Value, types cue.Kind) (expr ast.Expr, ingo s // ignore keywords alongside $ref, but $ref says we should ignore the $schema // keyword itself). We could make that situation an explicit error, but other // implementations don't, and it would require an entire extra pass just to do so. - if s.cfg.StrictKeywords { - s.warnf(value.Pos(), "ignoring keyword %q alongside $ref", key) - } + s.warnUnrecognizedKeyword(key, value, "ignoring keyword %q alongside $ref", key) return } c.fn(key, value, s) }) + if s.schemaVersion == VersionKubernetesCRD && s.isRoot { + // The root of a CRD is always a resource, so treat it as if it contained + // the x-kubernetes-embedded-resource keyword + // TODO remove this behavior now that we have an explicit + // ExtractCRDs function which does a better job at doing this. + c := constraintMap["x-kubernetes-embedded-resource"] + if c.phase != pass { + continue + } + // Note: there is no field value for the embedded-resource keyword, + // but it's not actually used except for its position so passing + // the parent object should work fine. + c.fn("x-kubernetes-embedded-resource", n, s) + } } if s.id != nil { // If there's an ID, it can be referred to. s.ensureDefinition(s.pos) } constraintIfThenElse(s) + if s.schemaVersion == VersionKubernetesCRD { + if s.hasProperties && s.hasAdditionalProperties { + s.errf(n, "additionalProperties may not be combined with properties in %v", s.schemaVersion) + } + } + if s.schemaVersion.is(openAPILike) { + if s.isArray && !s.hasItems { + // From https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/3.0.0.md#schema-object + // "`items` MUST be present if the `type` is `array`." + s.errf(n, `"items" must be present when the "type" is "array" in %v`, s.schemaVersion) + } + } schemaExpr := s.finalize() s.schemaInfo.hasConstraints = s.hasConstraints() return schemaExpr, s.schemaInfo } +func (s *state) warnUnrecognizedKeyword(key string, n cue.Value, msg string, args ...any) { + if !s.cfg.StrictKeywords { + return + } + if s.schemaVersion.is(openAPILike) && strings.HasPrefix(key, "x-") { + // Unimplemented x- keywords are allowed even with strict keywords + // under OpenAPI-like versions, because those versions enable + // strict keywords by default. + return + } + s.errf(n, msg, args...) +} + // maybeDefine checks whether we might need a definition // for n given its actual schema syntax expression. If // it does, it creates the definition as appropriate and returns @@ -830,12 +959,13 @@ func (s0 *state) schemaState(n cue.Value, types cue.Kind) (expr ast.Expr, ingo s // it just returns expr itself. // TODO also report whether the schema has been defined at a place // where it can be unified with something else? -func (s *state) maybeDefine(expr ast.Expr) ast.Expr { +func (s *state) maybeDefine(expr ast.Expr, info schemaInfo) ast.Expr { def := s.definedSchemaForNode(s.pos) if def == nil || len(def.path.Selectors()) == 0 { return expr } def.schema = expr + def.comment = info.comment() if def.importPath == "" { // It's a local definition that's not at the root. if !s.builder.put(def.path, expr, s.comment()) { @@ -878,7 +1008,7 @@ func (s *state) addDefinition(n cue.Value) *definedSchema { var loc SchemaLoc schemaRoot := s.schemaRoot() loc.ID = ref(*schemaRoot.id) - loc.ID.Fragment = cuePathToJSONPointer(relPath(n, schemaRoot.pos)) + loc.ID.Fragment = mustCUEPathToJSONPointer(relPath(n, schemaRoot.pos)) idStr := loc.ID.String() def, ok := s.defs[idStr] if ok { @@ -916,7 +1046,7 @@ func (s *state) refExpr(n cue.Value, importPath string, path cue.Path) ast.Expr return expr } // External reference - ip := module.ParseImportPath(importPath) + ip := ast.ParseImportPath(importPath) if ip.Qualifier == "" { // TODO choose an arbitrary name here. s.errf(n, "cannot determine package name from import path %q", importPath) @@ -960,34 +1090,6 @@ func (s *state) constValue(n cue.Value) ast.Expr { } } -func (s *state) value(n cue.Value) ast.Expr { - k := n.Kind() - switch k { - case cue.ListKind: - a := []ast.Expr{} - for i, _ := n.List(); i.Next(); { - a = append(a, s.value(i.Value())) - } - return setPos(ast.NewList(a...), n) - - case cue.StructKind: - a := []ast.Decl{} - s.processMap(n, func(key string, n cue.Value) { - a = append(a, &ast.Field{ - Label: ast.NewString(key), - Value: s.value(n), - }) - }) - return setPos(&ast.StructLit{Elts: a}, n) - - default: - if !n.IsConcrete() { - s.errf(n, "invalid non-concrete value") - } - return n.Syntax(cue.Final()).(ast.Expr) - } -} - // processMap processes a yaml node, expanding merges. // // TODO: in some cases we can translate merges into CUE embeddings. @@ -1054,8 +1156,20 @@ func excludeFields(decls []ast.Decl) []ast.Expr { } } -func bottom() ast.Expr { - return &ast.BottomLit{} +func errorDisallowed() ast.Expr { + return ast.NewCall(ast.NewIdent("error"), ast.NewString("disallowed")) +} + +func isErrorCall(e ast.Expr) bool { + call, ok := e.(*ast.CallExpr) + if !ok { + return false + } + target, ok := call.Fun.(*ast.Ident) + if !ok { + return false + } + return target.Name == "error" } func top() ast.Expr { @@ -1066,7 +1180,7 @@ func boolSchema(ok bool) ast.Expr { if ok { return top() } - return bottom() + return errorDisallowed() } func isTop(s ast.Expr) bool { @@ -1074,11 +1188,6 @@ func isTop(s ast.Expr) bool { return ok && i.Name == "_" } -func isBottom(e ast.Expr) bool { - _, ok := e.(*ast.BottomLit) - return ok -} - func addTag(field ast.Label, tag, value string) *ast.Field { return &ast.Field{ Label: field, diff --git a/vendor/cuelang.org/go/encoding/jsonschema/external_teststats.txt b/vendor/cuelang.org/go/encoding/jsonschema/external_teststats.txt index 665015de1f..34f62d2d48 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/external_teststats.txt +++ b/vendor/cuelang.org/go/encoding/jsonschema/external_teststats.txt @@ -1,22 +1,25 @@ # Generated by CUE_UPDATE=1 go test. DO NOT EDIT -v2: - schema extract (pass / total): 1054 / 1363 = 77.3% - tests (pass / total): 3793 / 4803 = 79.0% - tests on extracted schemas (pass / total): 3793 / 3955 = 95.9% + +Core tests: v3: - schema extract (pass / total): 1054 / 1363 = 77.3% - tests (pass / total): 3793 / 4803 = 79.0% - tests on extracted schemas (pass / total): 3793 / 3955 = 95.9% + schema extract (pass / total): 1072 / 1363 = 78.7% + tests (pass / total): 3913 / 4803 = 81.5% + tests on extracted schemas (pass / total): 3913 / 4041 = 96.8% -Optional tests +v3-roundtrip: + schema extract (pass / total): 233 / 1363 = 17.1% + tests (pass / total): 830 / 4803 = 17.3% + tests on extracted schemas (pass / total): 830 / 900 = 92.2% -v2: - schema extract (pass / total): 235 / 274 = 85.8% - tests (pass / total): 1635 / 2372 = 68.9% - tests on extracted schemas (pass / total): 1635 / 2262 = 72.3% +Optional tests: v3: - schema extract (pass / total): 235 / 274 = 85.8% - tests (pass / total): 1635 / 2372 = 68.9% - tests on extracted schemas (pass / total): 1635 / 2262 = 72.3% + schema extract (pass / total): 255 / 274 = 93.1% + tests (pass / total): 1733 / 2372 = 73.1% + tests on extracted schemas (pass / total): 1733 / 2332 = 74.3% + +v3-roundtrip: + schema extract (pass / total): 59 / 274 = 21.5% + tests (pass / total): 419 / 2372 = 17.7% + tests on extracted schemas (pass / total): 419 / 616 = 68.0% diff --git a/vendor/cuelang.org/go/encoding/jsonschema/generate.go b/vendor/cuelang.org/go/encoding/jsonschema/generate.go new file mode 100644 index 0000000000..b8f7874467 --- /dev/null +++ b/vendor/cuelang.org/go/encoding/jsonschema/generate.go @@ -0,0 +1,1253 @@ +// Copyright 2025 CUE Authors +// +// 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. + +package jsonschema + +import ( + "fmt" + "iter" + "maps" + "regexp" + "slices" + "strings" + "time" + + "cuelang.org/go/cue" + "cuelang.org/go/cue/ast" + "cuelang.org/go/cue/errors" + "cuelang.org/go/cue/token" +) + +// GenerateConfig configures JSON Schema generation from CUE values. +type GenerateConfig struct { + // Version specifies the version of JSON Schema to generate. + // Currently only [VersionDraft2020_12] is supported. + Version Version + + // NameFunc is used to determine how references map to + // JSON Schema definition names. It is passed the + // root value (usually a package) and the path to that value + // within it, as returned by [cue.Value.ReferencePath]. + // + // If this is nil, [DefaultNameFunc] will be used. + NameFunc func(root cue.Value, path cue.Path) string + + // ExplicitOpen, when true, will never close a schema with `additionalProperties: false` + // (but _will_ explicitly open a schema with `additionalProperties: true` + // when there is an explicit `...` or universal pattern in a struct). + // + // By default (when ExplicitOpen is false), all structs that are closed will + // have an `additionalProperties: false` added. + ExplicitOpen bool +} + +type closedMode byte + +const ( + open = closedMode(iota) + closed + closedRecursively +) + +// descend returns the closed mode that applies to m when +// descending one level of struct field. +func (m closedMode) descend() closedMode { + if m == closedRecursively { + return m + } + return open +} + +// Generate generates a JSON Schema for the given CUE value, +// with the returned AST representing the generated JSON result. +func Generate(v cue.Value, cfg *GenerateConfig) (ast.Expr, error) { + if err := v.Validate(); err != nil { + return nil, err + } + if cfg == nil { + cfg = &GenerateConfig{} + } else { + // Prevent mutation of the argument. + cfg = *ref(cfg) + } + if cfg.NameFunc == nil { + cfg.NameFunc = DefaultNameFunc + } + if cfg.Version == VersionUnknown { + cfg.Version = VersionDraft2020_12 + } + if cfg.Version != VersionDraft2020_12 { + return nil, fmt.Errorf("only version %v is supported for generating JSON Schema for now", VersionDraft2020_12) + } + + g := &generator{ + cfg: cfg, + defs: make(map[string]internItem), + unique: newUniqueItems(), + } + mode := open + switch { + case v.IsClosed(): + mode = closed + case v.IsClosedRecursively(): + mode = closedRecursively + } + item := optimize(g.makeItem(v, mode), g.unique) + expr := item.Value().generate(g) + + // Check if the result is a boolean literal + if lit, ok := expr.(*ast.BasicLit); ok && (lit.Kind == token.TRUE || lit.Kind == token.FALSE) { + if lit.Kind == token.FALSE { + // There should already be an error; if not, create one + if g.err == nil { + g.addError(v, fmt.Errorf("schema cannot be satisfied")) + } + return nil, g.err + } + // true means empty struct + expr = &ast.StructLit{} + } + + // The result should be a struct literal + st, ok := expr.(*ast.StructLit) + if !ok { + return nil, fmt.Errorf("expected struct literal from generate, got %T", expr) + } + + // Add schema version metadata and definitions. + fields := []ast.Decl{makeField("$schema", ast.NewString(cfg.Version.String()))} + if len(g.defs) != 0 { + defFields := make([]ast.Decl, 0, len(g.defs)) + for _, name := range slices.Sorted(maps.Keys(g.defs)) { + def := optimize(g.defs[name], g.unique) + defFields = append(defFields, makeField(name, def.Value().generate(g))) + } + fields = append(fields, makeField("$defs", &ast.StructLit{Elts: defFields})) + } + fields = append(fields, st.Elts...) + + if g.err != nil { + return nil, g.err + } + return makeSchemaStructLit(fields...), nil +} + +func optimize(it internItem, u *uniqueItems) internItem { + it = mergeAllOf(it, u) + return enumFromConst(it, u) +} + +// mergeAllOf returns the item with adjacent itemAllOf nodes +// all merged into a single itemAllOf node with all +// the conjuncts in. +func mergeAllOf(it internItem, u *uniqueItems) internItem { + switch it1 := it.Value().(type) { + case *itemAllOf: + it2 := &itemAllOf{ + elems: make([]internItem, 0, len(it1.elems)), + } + for e := range siblings(it1) { + // Remove elements that are entirely redundant. + // TODO we could unify itemType elements here, for example: + // allOf(itemType(number), itemType(integer)) -> itemType(integer) + if !slices.Contains(it2.elems, e) { + it2.elems = append(it2.elems, mergeAllOf(e, u)) + } + } + if len(it2.elems) == 1 { + return it2.elems[0] + } + return u.intern(it2) + default: + return u.apply(it, mergeAllOf) + } +} + +func itemConjuncts(it internItem) iter.Seq[internItem] { + return func(yield func(internItem) bool) { + it1, ok := it.Value().(*itemAllOf) + if !ok { + yield(it) + return + } + yieldSiblings(it1, yield) + } +} + +type elementsItem interface { + elements() []internItem +} + +func siblings[T elementsItem](it T) iter.Seq[internItem] { + return func(yield func(internItem) bool) { + yieldSiblings(it, yield) + } +} + +func yieldSiblings[T elementsItem](it T, yield func(internItem) bool) bool { + for _, e := range it.elements() { + if ae, ok := e.Value().(T); ok { + if !yieldSiblings(ae, yield) { + return false + } + } else { + if !yield(e) { + return false + } + } + } + return true +} + +// enumFromConst returns the item with disjunctive +// constants replaced by itemEnum. +// For example: +// +// anyOf(const("a"), const("b"), const("c")) +// -> +// enum("a", "b", "c") +func enumFromConst(it0 internItem, u *uniqueItems) internItem { + switch it := it0.Value().(type) { + case *itemAnyOf: + if slices.ContainsFunc(it.elems, func(it internItem) bool { + _, ok := it.Value().(*itemConst) + return !ok + }) { + // They're not all consts, so return as-is. + return it0 + } + // All items are const. We can make an enum from this. + // TODO this doesn't cover cases where there are some + // const values and some noncrete values. + it1 := &itemEnum{ + values: make([]ast.Expr, 0, len(it.elems)), + } + for _, e := range it.elems { + it1.values = append(it1.values, e.Value().(*itemConst).value) + } + return u.intern(it1) + default: + return u.apply(it0, enumFromConst) + } +} + +type generator struct { + cfg *GenerateConfig + + // err holds any errors accumulated during translation. + err errors.Error + + // defs holds any definitions made during the course of generation, + // indexed by the entry name within the `$defs` field. + defs map[string]internItem + + // unique ensures that all items are comparable with + // simple equality. + unique *uniqueItems +} + +func (g *generator) addError(pos cue.Value, err error) { + // TODO pos + g.err = errors.Append(g.err, errors.Promote(err, "")) +} + +// isDefinition reports whether the given path represents a definition. +// A definition is indicated by a selector with DefinitionLabel type. +func isDefinition(path cue.Path) bool { + for _, sel := range path.Selectors() { + if sel.LabelType() == cue.DefinitionLabel { + return true + } + } + return false +} + +func (g *generator) addErrorf(pos cue.Value, f string, a ...any) { + g.addError(pos, fmt.Errorf(f, a...)) +} + +// makeItem returns an item representing the JSON Schema +// for v in naive form. +func (g *generator) makeItem(v cue.Value, mode closedMode) internItem { + return g.unique.intern(g.makeItem0(v, mode)) +} + +func (g *generator) makeItem0(v cue.Value, mode closedMode) item { + op, args := v.Expr() + switch op { + case cue.NoOp, cue.SelectorOp: + pkg, path := v.ReferencePath() + if !pkg.Exists() { + break + } + // It's a reference: generate a definition for it. + // TODO Not all references need or should have a definition. + if name := g.cfg.NameFunc(pkg, path); name != "" { + // Lookup path directly rather than following v + // so that we get to see the reference in isolation + // and can follow its value even if it's a reference itself. + v1 := pkg.LookupPath(path) + if !v1.Exists() { + g.addErrorf(v, "reference %v not found", path) + } + v = v1 + ref := &itemRef{ + defName: name, + } + if _, ok := g.defs[name]; ok { + // Already defined. + return ref + } + g.defs[name] = internItem{} // Prevent infinite loops on cycles. + defMode := open + if isDefinition(path) { + defMode = closedRecursively + } + g.defs[name] = g.makeItem(v, defMode) + return ref + } + case cue.AndOp: + if v.Kind() == cue.StructKind { + // It's a conjunction of structs: we want to see all the + // top level fields in one coherent view because JSON + // Schema requires `additionalProperties` to be at the + // same level as `properties`. + return &itemAllOf{ + elems: []internItem{ + g.unique.intern(g.makeStructItem(v, mode)), + g.unique.intern(&itemType{kinds: []string{"object"}}), + }, + } + } + return &itemAllOf{ + elems: mapSlice(args, func(v cue.Value) internItem { return g.makeItem(v, open) }), + } + case cue.OrOp: + return &itemAnyOf{ + elems: mapSlice(args, func(v cue.Value) internItem { return g.makeItem(v, open) }), + } + case cue.RegexMatchOp, + cue.NotRegexMatchOp: + re, err := args[0].String() + if err != nil { + g.addError(args[0], err) + return &itemFalse{} + } + m := g.unique.intern(&itemPattern{ + regexp: re, + }) + if op == cue.NotRegexMatchOp { + m = g.unique.intern(&itemNot{ + elem: m, + }) + } + return &itemAllOf{ + elems: []internItem{ + g.unique.intern(&itemType{ + kinds: []string{"string"}, + }), + m, + }, + } + case cue.EqualOp, + cue.NotEqualOp: + if len(args) > 1 { + // Binary operations can't be expressed in JSON Schema. + break + } + if !args[0].IsConcrete() { + // If it's not concrete, we can't represent it in JSON Schema + // so accept anything. + return &itemTrue{} + } + syntax := args[0].Syntax() + expr, ok := syntax.(ast.Expr) + if !ok { + g.addError(args[0], fmt.Errorf("expected expression from Syntax, got %T", syntax)) + return &itemFalse{} + } + it := g.unique.intern(&itemConst{ + value: expr, + }) + if op == cue.EqualOp { + return it.Value() + } + return &itemNot{ + elem: it, + } + case cue.LessThanOp, + cue.LessThanEqualOp, + cue.GreaterThanOp, + cue.GreaterThanEqualOp: + if len(args) > 1 { + // Binary operations can't be expressed in JSON Schema. + break + } + switch kind := args[0].Kind(); kind { + case cue.FloatKind, cue.IntKind: + n, err := args[0].Float64() + if err != nil { + // Probably non-concrete. + return &itemTrue{} + } + return &itemAllOf{ + elems: []internItem{ + g.unique.intern(&itemBounds{ + constraint: op, + n: n, + }), + g.unique.intern(&itemType{ + kinds: []string{"number"}, + }), + }, + } + case cue.StringKind: + // Can't express bounds on strings in JSON Schema + return &itemType{ + kinds: cueKindToJSONSchemaTypes(kind), + } + default: + g.addError(args[0], fmt.Errorf("bad argument to unary comparison")) + return &itemFalse{} + } + case cue.CallOp: + return g.makeCallItem(v, args, mode) + } + if !v.IsNull() { + // We want to encode null as {type: "null"} not {const: null} + // so then there's a possibility of collapsing it together in + // the same type keyword. + if e, ok := g.constExpr(v, mode); ok { + return &itemConst{ + value: e, + } + } + } + kind := v.IncompleteKind() + if kind == cue.TopKind { + return &itemTrue{} + } + var it item // additional constraints for some known types. + switch kind { + case cue.StructKind: + it = g.makeStructItem(v, mode) + case cue.ListKind: + it = g.makeListItem(v, mode) + } + var elems []internItem + if kinds := cueKindToJSONSchemaTypes(kind); len(kinds) > 0 { + elems = append(elems, g.unique.intern(&itemType{ + kinds: kinds, + })) + } + if it != nil { + elems = append(elems, g.unique.intern(it)) + } + switch len(elems) { + case 0: + return &itemTrue{} + case 1: + return elems[0].Value() + } + return &itemAllOf{ + elems: elems, + } +} + +// constExpr returns the "constant" value of a given +// cue value. There are a few possible ways to represent +// a JSON Schema const in CUE; some examples: +// +// true +// ==true +// close({a!: true}) // Note: this is the representation Extract uses +// [==true] +// [true] +// +// There's some overlap here with the unary == treatment +// in [generator.makeItem] but in that case we know that +// the argument must be constant, and this case we don't. +func (g *generator) constExpr(v cue.Value, mode closedMode) (ast.Expr, bool) { + // Check for unary == operator (e.g., ==1, ==true) + op, args := v.Expr() + if op == cue.EqualOp && len(args) == 1 { + // It's a unary equals: the argument must be concrete and + // there's no need to use [constExpr] any more. + syntax := args[0].Syntax() + expr, ok := syntax.(ast.Expr) + return expr, ok + } + + switch kind := v.Kind(); kind { + case cue.BottomKind: + return nil, false + case cue.StructKind: + if mode == open { + // Open struct is not const. + return nil, false + } + // Closed struct: all fields must be required (no optional fields) + // and we need to recursively check all field values are const + iter, err := v.Fields(cue.Optional(true), cue.Patterns(true)) + if err != nil { + return nil, false + } + var fields []ast.Decl + for iter.Next() { + sel := iter.Selector() + // All fields must be required for the struct to be const + if sel.ConstraintType() != cue.RequiredConstraint { + return nil, false + } + // Recursively check if the field value is const + fieldExpr, ok := g.constExpr(iter.Value(), mode) + if !ok { + return nil, false + } + // Create a regular field (not required marker) + fields = append(fields, makeField(sel.Unquoted(), fieldExpr)) + } + return &ast.StructLit{Elts: fields}, true + case cue.ListKind: + if v.LookupPath(cue.MakePath(cue.AnyIndex)).Exists() { + // Open list is not const. + return nil, false + } + // Closed list: recursively check all elements are const + iter, err := v.List() + if err != nil { + return nil, false + } + var elems []ast.Expr + for iter.Next() { + elemExpr, ok := g.constExpr(iter.Value(), mode) + if !ok { + return nil, false + } + elems = append(elems, elemExpr) + } + return &ast.ListLit{Elts: elems}, true + } + // For other kinds (atoms), if it's concrete, return its syntax + if !v.IsConcrete() { + return nil, false + } + expr, ok := v.Syntax().(ast.Expr) + return expr, ok +} + +func (g *generator) makeCallItem(v cue.Value, args []cue.Value, mode closedMode) item { + if len(args) < 1 { + // Invalid call - not enough arguments + g.addError(v, fmt.Errorf("call operation with no function")) + return &itemFalse{} + } + + // Get the function name from the first argument. + // TODO this might need rethinking if/when functions become more of + // a first class thing within CUE. + funcName := fmt.Sprint(args[0]) + switch funcName { + case "error()", "error": + // Explicit error: don't add an error to g but map it to a `false` schema. + // See https://github.com/cue-lang/cue/issues/4133 for why + // we include "error()" as well as "error" + return &itemFalse{} + case "close": + if mode == open { + mode = closed + } + return g.makeItem(args[1], mode).Value() + case "strings.MinRunes": + if len(args) != 2 { + g.addError(v, fmt.Errorf("strings.MinRunes expects 1 argument, got %d", len(args)-1)) + return &itemFalse{} + } + n, err := args[1].Int64() + if err != nil { + g.addError(args[1], err) + return &itemFalse{} + } + return &itemAllOf{ + elems: []internItem{ + g.unique.intern(&itemType{kinds: []string{"string"}}), + g.unique.intern(&itemLengthBounds{constraint: cue.GreaterThanEqualOp, n: int(n)}), + }, + } + + case "strings.MaxRunes": + if len(args) != 2 { + g.addError(v, fmt.Errorf("strings.MaxRunes expects 1 argument, got %d", len(args)-1)) + return &itemFalse{} + } + n, err := args[1].Int64() + if err != nil { + g.addError(args[1], err) + return &itemFalse{} + } + return &itemAllOf{ + elems: []internItem{ + g.unique.intern(&itemType{kinds: []string{"string"}}), + g.unique.intern(&itemLengthBounds{constraint: cue.LessThanEqualOp, n: int(n)}), + }, + } + + case "math.MultipleOf": + if len(args) != 2 { + g.addError(v, fmt.Errorf("math.MultipleOf expects 1 argument, got %d", len(args)-1)) + return &itemFalse{} + } + n, err := args[1].Float64() + if err != nil { + g.addError(args[1], err) + return &itemFalse{} + } + return &itemAllOf{ + elems: []internItem{ + g.unique.intern(&itemType{kinds: []string{"number"}}), + g.unique.intern(&itemMultipleOf{n: n}), + }, + } + + case "time.Format": + if len(args) != 2 { + g.addError(v, fmt.Errorf("time.Format expects 1 argument, got %d", len(args)-1)) + return &itemFalse{} + } + layout, err := args[1].String() + if err != nil { + // TODO should we just fall back to type=string if we + // can't determine the concrete format? + g.addError(args[1], err) + return &itemFalse{} + } + // Convert CUE time layout to JSON Schema format + var format string + switch layout { + case time.RFC3339, time.RFC3339Nano: + format = "date-time" + case time.DateOnly: + format = "date" + case time.TimeOnly: + format = "time" + default: + // For other layouts, we can't express them in JSON Schema + // but at least we know it's a string. + return &itemType{kinds: []string{"string"}} + } + return &itemAllOf{ + elems: []internItem{ + g.unique.intern(&itemType{kinds: []string{"string"}}), + g.unique.intern(&itemFormat{format: format}), + }, + } + case "list.MinItems", "list.MaxItems": + if len(args) != 2 { + g.addError(v, fmt.Errorf("%s expects 1 argument, got %d", funcName, len(args)-1)) + return &itemFalse{} + } + n, err := args[1].Int64() + if err != nil { + g.addError(args[1], err) + return &itemFalse{} + } + var constraint cue.Op + if funcName == "list.MinItems" { + constraint = cue.GreaterThanEqualOp + } else { + constraint = cue.LessThanEqualOp + } + return &itemAllOf{ + elems: []internItem{ + g.unique.intern(&itemType{kinds: []string{"array"}}), + g.unique.intern(&itemItemsBounds{constraint: constraint, n: int(n)}), + }, + } + + case "list.MatchN": + // list.MatchN is generated by Extract for the contains keyword. + // - list.MatchN(>=N, schema) represents contains with minContains: N + // - list.MatchN(>=N & <=M, schema) represents contains with minContains: N and maxContains: M + if len(args) != 3 { + // Unrecognized form, accept anything + return &itemTrue{} + } + + // Parse the constraint from the first argument + constraintVal := args[1] + var minVal, maxVal *int64 + + op, opArgs := constraintVal.Expr() + switch op { + case cue.NoOp: + // It's a simple expression, could be a literal or something more complex + // Try to parse as an int literal for the minimum + n, err := constraintVal.Int64() + if err == nil { + minVal = ref(n) + } else { + // Not a simple integer, accept anything + return &itemTrue{} + } + case cue.GreaterThanEqualOp: + // >=N constraint for minimum + if len(opArgs) != 1 { + return &itemTrue{} + } + n, err := opArgs[0].Int64() + if err != nil { + return &itemTrue{} + } + minVal = ref(n) + case cue.AndOp: + // Could be >=N & <=M + if len(opArgs) != 2 { + return &itemTrue{} + } + // First operand should be >=N + op1, op1Args := opArgs[0].Expr() + if op1 != cue.GreaterThanEqualOp || len(op1Args) != 1 { + return &itemTrue{} + } + n, err := op1Args[0].Int64() + if err != nil { + return &itemTrue{} + } + minVal = ref(n) + + // Second operand should be <=M + op2, op2Args := opArgs[1].Expr() + if op2 != cue.LessThanEqualOp || len(op2Args) != 1 { + return &itemTrue{} + } + n, err = op2Args[0].Int64() + if err != nil { + return &itemTrue{} + } + maxVal = ref(n) + default: + // Unknown constraint pattern, accept anything + return &itemTrue{} + } + + // Get the schema element from the second argument + // Check if it's bottom first (which represents "contains: false") + // to avoid adding errors to the generator. + var elem internItem + elemVal := args[2] + if err := elemVal.Err(); err != nil { + // Bottom value - represents "contains: false" + elem = g.unique.intern(&itemFalse{}) + } else { + elem = g.makeItem(elemVal, open) + } + + return &itemAllOf{ + elems: []internItem{ + g.unique.intern(&itemType{kinds: []string{"array"}}), + g.unique.intern(&itemContains{elem: elem, min: minVal, max: maxVal}), + }, + } + + case "matchN": + // matchN is generated by Extract for oneOf, anyOf, allOf, and not. + // - matchN(1, [a, b, c, ...]) represents oneOf + // - matchN(0, [x]) represents not + // - matchN(>=1, [a, b, c, ...]) represents anyOf + // - matchN(N, [a, b, c, ...]) where N == len(list) represents allOf + if len(args) != 3 { + // Unrecognized form, accept anything + return &itemTrue{} + } + + constraintVal, listVal := args[1], args[2] + + var items []internItem + for i := 0; ; i++ { + // Unfortunately https://github.com/cue-lang/cue/issues/4132 means + // that we cannot iterate over elements of the list with listVal.List + // when there are error elements (which there could be, as [Extract] + // can generate explicit errors, but we _can_ use [Value.LookupPath] + // to look up explicit indexes. + v := listVal.LookupPath(cue.MakePath(cue.Index(i))) + if !v.Exists() { + break + } + items = append(items, g.makeItem(v, open)) + } + // Extract the list of items from the second argument. + + // Determine which combinator to use based on the constraint + // It can be a literal int (0, 1, N) or a unary expression (>=1). + op, opArgs := constraintVal.Expr() + switch op { + case cue.NoOp: + // It's a simple integer literal + n, err := constraintVal.Int64() + if err != nil { + // Not an integer, accept anything + return &itemTrue{} + } + switch n { + case 0: + // matchN(0, [x]) represents not + if len(items) != 1 { + // Unexpected form, accept anything + return &itemTrue{} + } + return &itemNot{elem: items[0]} + case 1: + if len(items) == 0 { + return &itemFalse{} + } + // matchN(1, [a, b, c, ...]) represents oneOf + return &itemOneOf{elems: items} + default: + // matchN(N, [...]) where N == len(list) represents allOf + if int(n) == len(items) { + return &itemAllOf{elems: items} + } + // Unknown matchN pattern, accept anything + return &itemTrue{} + } + + case cue.GreaterThanEqualOp: + // matchN(>=1, [a, b, c, ...]) represents anyOf + if len(opArgs) != 1 { + return &itemTrue{} + } + n, err := opArgs[0].Int64() + if err != nil || n != 1 { + // Unknown matchN pattern, accept anything + return &itemTrue{} + } + if len(items) == 0 { + return &itemFalse{} + } + return &itemAnyOf{elems: items} + + default: + // Unknown operator, accept anything + return &itemTrue{} + } + + case "matchIf": + // matchIf is generated by Extract for if/then/else constraints. + // - matchIf(ifExpr, thenExpr, elseExpr) + if len(args) != 4 { + // Unrecognized form, accept anything + return &itemTrue{} + } + + return &itemIfThenElse{ + ifElem: g.makeItem(args[1], open), + thenElem: trueAsNil(g.makeItem(args[2], open)), + elseElem: trueAsNil(g.makeItem(args[3], open)), + } + + default: + // For unknown functions, accept anything rather than fail. + // This allows for gradual implementation of more function types + return &itemTrue{} + } +} + +func (g *generator) makeStructItem(v cue.Value, mode closedMode) item { + props := itemProperties{ + properties: make(map[string]internItem), + patternProperties: make(map[string]internItem), + } + required := make(map[string]bool) + + allOf := &itemAllOf{} + addProperty := func(fieldName string, it internItem) { + props.properties[fieldName] = join(props.properties[fieldName], it, g.unique) + } + addPatternProperty := func(pattern string, it internItem) { + props.patternProperties[pattern] = join(props.patternProperties[pattern], it, g.unique) + } + hasUniversalConstraint := false + for v := range valueConjuncts(v) { + pkg, _ := v.ReferencePath() + if pkg.Exists() || v.Kind() != cue.StructKind { + // This conjunct is a reference or some other non-struct literal. + // Let's keep it as such. + allOf.elems = append(allOf.elems, g.makeItem(v, open)) + continue + } + iter, err := v.Fields(cue.Optional(true), cue.Patterns(true)) + if err != nil { + g.addError(v, err) + return &itemFalse{} + } + type pat struct { + pattern *regexp.Regexp + constraints map[internItem]bool + } + // patternConstraints keeps track of the pattern constraints in this + // particular conjunct so we can remove them from the individual fields. + var patternConstraints []pat + outer: + for iter.Next() { + sel := iter.Selector() + switch sel.ConstraintType() { + case cue.PatternConstraint: + re, ok := regexpForValue(sel.Pattern()) + if ok { + if re.String() == "" && acceptsAllString(sel.Pattern()) { + // Record the fact that we've seen a universal constraint + // because then we know that LookupPath(AnyString) + // will return it. + hasUniversalConstraint = true + } + constraint := g.makeItem(iter.Value(), mode.descend()) + addPatternProperty(re.String(), constraint) + p := pat{ + pattern: re, + constraints: make(map[internItem]bool), + } + for c := range itemConjuncts(constraint) { + p.constraints[c] = true + } + patternConstraints = append(patternConstraints, p) + } else { + // We can't express the constraint in JSON Schema, and it + // might cover any number of possible labels, so the + // only thing we can do is treat the whole thing as explicitly + // open. + addPatternProperty("", g.unique.intern(&itemTrue{})) + } + continue outer + case cue.OptionalConstraint: + case cue.RequiredConstraint: + required[sel.Unquoted()] = true + default: + // It's a regular field. If it's concrete, then we can + // consider the field to be optional because it's OK + // to omit it. Otherwise it'll be required. + if err := iter.Value().Validate(cue.Concrete(true)); err != nil { + required[sel.Unquoted()] = true + } + } + propItem := g.makeItem(iter.Value(), mode.descend()) + fieldName := sel.Unquoted() + if len(patternConstraints) == 0 { + addProperty(fieldName, propItem) + continue + } + // There are pattern constraints which will have been unified in with + // the constraints of any matching field. They're redundant with + // respect to patternProperties, so remove them. + // This has the potential to remove explicit constraints on the fields + // themselves, but this will not change behavior, just result in a slightly + // smaller resulting schema. + allof, ok := propItem.Value().(*itemAllOf) + if !ok || len(allof.elems) <= 1 { + // No possibility of removing any conjuncts. + addProperty(fieldName, propItem) + continue + } + var elems []internItem + for _, c := range patternConstraints { + if !c.pattern.MatchString(fieldName) { + continue + } + if elems == nil { + elems = slices.Collect(siblings(allof)) + } + // We've found a pattern constraint that unifies with the field name. + // Its constraint will have been added to this property's constraints + // but are redundant, so remove them. + elems = slices.DeleteFunc(elems, func(it internItem) bool { + return c.constraints[it] + }) + } + if len(elems) == 0 { + propItem = g.unique.intern(&itemTrue{}) + } else { + propItem = g.unique.intern(&itemAllOf{elems: elems}) + } + addProperty(fieldName, propItem) + } + } + + ellipsis := v.LookupPath(cue.MakePath(cue.AnyString)) + if ellipsis.Exists() && !hasUniversalConstraint { + constraint := g.makeItem(ellipsis, mode.descend()) + if isTrue(constraint) { + // `... _` is indistingishable from `[_]: _` so set it as a + // pattern property so we can treat it uniformly. + addPatternProperty("", constraint) + } else { + // Note: currently this will never happen as the CUE evaluator + // does not support `... T` in structs. + props.additionalProperties = constraint + } + } + + if constraint, ok := props.patternProperties[""]; ok && isTrue(constraint) || len(props.properties) == 0 { + // There's a universal pattern constraint and either no + // properties or we accept anything. In both these cases it's + // not possible to tell the difference between + // `additionalProperties` (only applies to properties not + // explicitly mentioned) and `patternProperties` (applies to all + // properties regardless), so use `additionalProperties` in + // preference as it's a little shorter and arguably more + // obvious. + props.additionalProperties = join(props.additionalProperties, constraint, g.unique) + delete(props.patternProperties, "") + } + if mode != open && !g.cfg.ExplicitOpen && props.additionalProperties.Value() == nil { + props.additionalProperties = g.unique.intern(&itemFalse{}) + } + props.required = slices.Sorted(maps.Keys(required)) + hasObjectConstraints := + len(props.properties) == 0 || + len(props.required) == 0 || + len(props.patternProperties) == 0 + if len(allOf.elems) > 0 { + if !hasObjectConstraints { + return allOf + } + allOf.elems = append(allOf.elems, g.unique.intern(&props)) + return allOf + } + if hasObjectConstraints { + return &props + } + return &itemTrue{} +} + +func (g *generator) makeListItem(v cue.Value, mode closedMode) item { + ellipsis := v.LookupPath(cue.MakePath(cue.AnyIndex)) + lenv := v.Len() + var n int64 + if ellipsis.Exists() { + // It's an open list. The length will be in the form int&>=5 + op, args := lenv.Expr() + if op != cue.AndOp || len(args) != 2 { + g.addErrorf(v, "list length has unexpected form; got %v want int&>=N", lenv) + return &itemFalse{} + } + op, args = args[1].Expr() + if op != cue.GreaterThanEqualOp || len(args) != 1 { + g.addErrorf(v, "list length has unexpected form (2); got %v want >=N", lenv) + return &itemFalse{} + } + var err error + n, err = args[0].Int64() + if err != nil { + g.addErrorf(v, "cannot extract list length from %v: %v", v, err) + return &itemFalse{} + } + } else { + var err error + n, err = lenv.Int64() + if err != nil { + g.addErrorf(v, "cannot extract concrete list length from %v: %v", v, err) + } + } + prefix := make([]internItem, n) + for i := range n { + elem := v.LookupPath(cue.MakePath(cue.Index(i))) + if !elem.Exists() { + g.addErrorf(v, "cannot get value at index %d in %v", i, v) + return &itemFalse{} + } + prefix[i] = g.makeItem(elem, mode) + } + a := &itemAllOf{ + elems: []internItem{g.unique.intern(&itemType{kinds: []string{"array"}})}, + } + items := &itemItems{} + if len(prefix) > 0 { + a.elems = append(a.elems, g.unique.intern(&itemLengthBounds{ + constraint: cue.GreaterThanEqualOp, + n: len(prefix), + })) + items.prefix = prefix + } + if ellipsis.Exists() { + items.rest = trueAsNil(g.makeItem(ellipsis, mode)) + } else { + a.elems = append(a.elems, g.unique.intern(&itemLengthBounds{ + constraint: cue.LessThanEqualOp, + n: len(prefix), + })) + } + if items.rest.Value() != nil || len(items.prefix) > 0 { + a.elems = append(a.elems, g.unique.intern(items)) + } + return a +} + +func join(it1, it2 internItem, u *uniqueItems) internItem { + if it1.Value() == nil || isTrue(it1) { + return it2 + } + if it2.Value() == nil || isTrue(it2) { + return it1 + } + return u.intern(&itemAllOf{ + elems: []internItem{it1, it2}, + }) +} + +// cueKindToJSONSchemaTypes converts a CUE kind to JSON Schema type strings +// as associated with the "type" keyword. +func cueKindToJSONSchemaTypes(kind cue.Kind) []string { + types := make([]string, 0, kind.Count()) + if (kind & cue.FloatKind) != 0 { + // JSON Schema doesn't distinguish between float and number, + // so any float allows all numbers (CUE models "number" as float|int). + kind &^= cue.NumberKind + types = append(types, "number") + } + + for k := range kind.Kinds() { + var t string + switch k { + case cue.NullKind: + t = "null" + case cue.BoolKind: + t = "boolean" + case cue.StringKind: + t = "string" + case cue.IntKind: + t = "integer" + case cue.StructKind: + t = "object" + case cue.ListKind: + t = "array" + default: + continue + } + types = append(types, t) + } + return types +} + +// regexpForValue tries to interpret v as a regular expression constraint, +// It returns the regular expression and reports whether it succeeded. +func regexpForValue(v cue.Value) (*regexp.Regexp, bool) { + s, ok := regexpForValue1(v) + if !ok { + return nil, false + } + pat, err := regexp.Compile(s) + return pat, err == nil +} + +func regexpForValue1(v cue.Value) (string, bool) { + op, args := v.Expr() + if op == cue.RegexMatchOp { + if len(args) != 1 { + return "", false + } + s, err := args[0].String() + if err != nil { + return "", false + } + return s, true + } + s, err := v.String() + if err == nil { + // Exact match. + return "^" + regexp.QuoteMeta(s) + "$", true + } + if acceptsAllString(v) { + // It matches all possible string labels: return + // a regular expression that matches all possible + // labels too. + return "", true + } + return "", false +} + +func acceptsAllString(v cue.Value) bool { + // TODO return v.AcceptsAll(cue.StringKind) if/when that + // method is implemented. + sv := v.Context().CompileString("string") + return v.Unify(sv).Subsume(sv, cue.Final()) == nil +} + +// trueAsNil returns the nil item if the item +// is *itemTrue (top). +func trueAsNil(it internItem) internItem { + if isTrue(it) { + return internItem{} + } + return it +} + +func isTrue(it internItem) bool { + _, ok := it.Value().(*itemTrue) + return ok +} + +// isConcreteScalar reports whether v should be considered concrete +// enough to be encoded as a const or enum value. +// +// Structs and lists are excluded for now to avoid O(n^2) +// overhead when checking. +// +// TODO handle struct and list kinds. +func isConcreteScalar(v cue.Value) bool { + if !v.IsConcrete() { + return false + } + return (v.Kind() & (cue.StructKind | cue.ListKind)) == 0 +} + +// DefaultNameFunc holds the default function used by [Generate] +// to generate a JSON Schema definition name from a reference path +// within the value inst, where inst is usually a CUE package value. +func DefaultNameFunc(inst cue.Value, ref cue.Path) string { + var buf strings.Builder + for i, sel := range ref.Selectors() { + if i > 0 { + buf.WriteByte('.') + } + // TODO what should this do when it's not a valid identifier? + buf.WriteString(sel.String()) + } + return buf.String() +} + +// mapSlice returns a slice of f(x) for each x in xs. +func mapSlice[T1, T2 any](xs []T1, f func(T1) T2) []T2 { + xs1 := make([]T2, len(xs)) + for i, x := range xs { + xs1[i] = f(x) + } + return xs1 +} +func valueConjuncts(v cue.Value) iter.Seq[cue.Value] { + return func(yield func(cue.Value) bool) { + yieldValueConjuncts(v, yield) + } +} + +func yieldValueConjuncts(v cue.Value, yield func(cue.Value) bool) bool { + op, args := v.Expr() + if op != cue.AndOp { + return yield(v) + } + for _, v := range args { + if !yieldValueConjuncts(v, yield) { + return false + } + } + return true +} diff --git a/vendor/cuelang.org/go/encoding/jsonschema/generate_items.go b/vendor/cuelang.org/go/encoding/jsonschema/generate_items.go new file mode 100644 index 0000000000..1416ed5cab --- /dev/null +++ b/vendor/cuelang.org/go/encoding/jsonschema/generate_items.go @@ -0,0 +1,916 @@ +// Copyright 2025 CUE Authors +// +// 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. + +package jsonschema + +import ( + "cmp" + "fmt" + "hash/maphash" + "maps" + "reflect" + "slices" + + "cuelang.org/go/cue" + "cuelang.org/go/cue/ast" + "cuelang.org/go/cue/format" + "cuelang.org/go/cue/token" + "cuelang.org/go/internal/anyunique" +) + +// TODO use a defined order when keywords are marshaled +// so that we always put $schema at the start, for example. + +// item represents a JSON Schema constraint or structure that can be +// converted to an AST representation for serialization. +type item interface { + // generate returns the AST representation of this item. + generate(g *generator) ast.Expr + + // apply invokes f on each sub-item, replacing each with the item + // returned, and returns the new item (or the same if nothing has + // changed). Note that it does not call f on the item itself. It can + // use u to create new unique items. + apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item + + // hash writes the hash of the item to h; it should use u.writeHash + // to write the hash value for any items it contains. + hash(h *maphash.Hash, u *uniqueItems) +} + +// itemTrue represents a schema that accepts any value (true schema) +type itemTrue struct{} + +func (i *itemTrue) generate(g *generator) ast.Expr { + return ast.NewBool(true) +} + +func (it *itemTrue) hash(h *maphash.Hash, u *uniqueItems) { +} + +func (i *itemTrue) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + return i +} + +// itemFalse represents a schema that accepts no values (false schema) +type itemFalse struct{} + +func (i *itemFalse) generate(g *generator) ast.Expr { + return ast.NewBool(false) +} + +func (it *itemFalse) hash(h *maphash.Hash, u *uniqueItems) { +} + +func (i *itemFalse) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + return i +} + +// itemAllOf represents an allOf combinator +type itemAllOf struct { + elems []internItem +} + +func (it *itemAllOf) hash(h *maphash.Hash, u *uniqueItems) { + for _, it := range it.elems { + u.writeHash(h, it) + } +} + +func (i *itemAllOf) add(it internItem) { + i.elems = append(i.elems, it) +} + +var _ elementsItem = (*itemAllOf)(nil) + +// elements implements [elementsItem]. +func (i *itemAllOf) elements() []internItem { + return i.elems +} + +func (i *itemAllOf) generate(g *generator) ast.Expr { + // Because a single json schema object is essentially an allOf itself, + // we can merge objects that don't share keywords + // but we also have to be careful not to merge keywords + // that interact with one another (for example `properties` and `patternProperties`). + var unmerged []ast.Expr + var finalFields []ast.Decl + finalFieldNames := make(map[string]bool) + + for _, e := range i.elems { + expr := e.Value().generate(g) + if lit, ok := expr.(*ast.BasicLit); ok { + switch lit.Kind { + case token.TRUE: + // true does nothing, so can be ignored. + continue + case token.FALSE: + // false means everything is false. + return expr + } + } + + // Try to extract struct literal fields for merging + st, ok := expr.(*ast.StructLit) + if !ok { + // A schema should only ever encode to a bool or a struct. + panic(fmt.Errorf("unexpected expression in itemAllOf: %T", expr)) + } + + // Check if we can merge these fields with existing ones + avoidMerging := false + loop: + for _, decl := range st.Elts { + name := fieldLabel(decl) + if name == "" { + panic(fmt.Errorf("unexpected element in struct %#v", decl)) + } + if finalFieldNames[name] { + // Field already exists in merge target. + avoidMerging = true + break + } + for _, ik := range keywordInteractions[name] { + if finalFieldNames[ik] { + // Field interacts with one of the other fields in merge target. + avoidMerging = true + break loop + } + } + } + + if avoidMerging { + unmerged = append(unmerged, expr) + continue + } + // Merge the fields + for _, decl := range st.Elts { + finalFieldNames[fieldLabel(decl)] = true + finalFields = append(finalFields, decl) + } + } + + if len(unmerged) == 0 { + return makeSchemaStructLit(finalFields...) + } + + // Add the merged fields as one element if non-empty + if len(finalFields) > 0 { + unmerged = append(unmerged, makeSchemaStructLit(finalFields...)) + } + + return singleKeyword("allOf", ast.NewList(unmerged...)) +} + +func (i *itemAllOf) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + elems, changed := applyElems(i.elems, f, u) + if !changed { + return i + } + return &itemAllOf{elems: elems} +} + +// itemOneOf represents a oneOf combinator +type itemOneOf struct { + elems []internItem +} + +func (it *itemOneOf) hash(h *maphash.Hash, u *uniqueItems) { + for _, it := range it.elems { + u.writeHash(h, it) + } +} + +func (i *itemOneOf) generate(g *generator) ast.Expr { + return singleKeyword("oneOf", generateList(g, i.elems)) +} + +func (i *itemOneOf) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + elems, changed := applyElems(i.elems, f, u) + if !changed { + return i + } + return &itemOneOf{elems: elems} +} + +var _ elementsItem = (*itemOneOf)(nil) + +// elements implements [elementsItem]. +func (i *itemOneOf) elements() []internItem { + return i.elems +} + +// itemAnyOf represents an anyOf combinator +type itemAnyOf struct { + elems []internItem +} + +func (it *itemAnyOf) hash(h *maphash.Hash, u *uniqueItems) { + for _, it := range it.elems { + u.writeHash(h, it) + } +} + +func (i *itemAnyOf) generate(g *generator) ast.Expr { + return singleKeyword("anyOf", generateList(g, i.elems)) +} + +func (i *itemAnyOf) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + elems, changed := applyElems(i.elems, f, u) + if !changed { + return i + } + return &itemAnyOf{elems: elems} +} + +var _ elementsItem = (*itemAnyOf)(nil) + +// elements implements [elementsItem]. +func (i *itemAnyOf) elements() []internItem { + return i.elems +} + +// itemNot represents a not combinator +type itemNot struct { + elem internItem +} + +func (it *itemNot) hash(h *maphash.Hash, u *uniqueItems) { + u.writeHash(h, it.elem) +} + +func (i *itemNot) generate(g *generator) ast.Expr { + return singleKeyword("not", i.elem.Value().generate(g)) +} + +func (i *itemNot) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + elem := f(i.elem, u) + if elem == i.elem { + return i + } + return &itemNot{elem: elem} +} + +// itemConst represents a constant value constraint. +// The value represents the actual constant in question as an AST expression. +type itemConst struct { + value ast.Expr +} + +func (it *itemConst) hash(h *maphash.Hash, u *uniqueItems) { + writeExprHash(h, it.value) +} + +func (i *itemConst) generate(g *generator) ast.Expr { + return singleKeyword("const", i.value) +} + +func (i *itemConst) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + return i +} + +// itemEnum represents an "enum" constraint. +// Each value represents one possible value of the enum. +type itemEnum struct { + values []ast.Expr +} + +func (it *itemEnum) hash(h *maphash.Hash, u *uniqueItems) { + for _, v := range it.values { + writeExprHash(h, v) + } +} + +func (i *itemEnum) generate(g *generator) ast.Expr { + return singleKeyword("enum", ast.NewList(i.values...)) +} + +func (i *itemEnum) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + return i +} + +type itemRef struct { + defName string +} + +func (it *itemRef) hash(h *maphash.Hash, u *uniqueItems) { + h.WriteString(it.defName) +} + +func (i *itemRef) generate(g *generator) ast.Expr { + return singleKeyword("$ref", ast.NewString("#/$defs/"+i.defName)) +} + +func (i *itemRef) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + return i +} + +// itemType represents a type constraint +type itemType struct { + kinds []string +} + +func (it *itemType) hash(h *maphash.Hash, u *uniqueItems) { + for _, k := range it.kinds { + h.WriteString(k) + } +} + +func (i *itemType) generate(g *generator) ast.Expr { + if len(i.kinds) == 1 { + return singleKeyword("type", ast.NewString(i.kinds[0])) + } + exprs := make([]ast.Expr, len(i.kinds)) + for i, k := range i.kinds { + exprs[i] = ast.NewString(k) + } + return singleKeyword("type", ast.NewList(exprs...)) +} + +func (i *itemType) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + return i +} + +// itemFormat represents a format constraint +type itemFormat struct { + format string +} + +func (it *itemFormat) hash(h *maphash.Hash, u *uniqueItems) { + h.WriteString(it.format) +} + +func (i *itemFormat) generate(g *generator) ast.Expr { + return singleKeyword("format", ast.NewString(i.format)) +} + +func (i *itemFormat) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + return i +} + +// itemPattern represents a pattern constraint +type itemPattern struct { + regexp string +} + +func (it *itemPattern) hash(h *maphash.Hash, u *uniqueItems) { + h.WriteString(it.regexp) +} + +func (i *itemPattern) generate(g *generator) ast.Expr { + return singleKeyword("pattern", ast.NewString(i.regexp)) +} + +func (i *itemPattern) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + return i +} + +// itemBounds represents numeric bounds constraints +type itemBounds struct { + constraint cue.Op // LessThanEqualOp, LessThanOp, GreaterThanEqualOp, GreaterThanOp + // TODO this encodes awkwardly in CUE (for example 10 becomes 1e0). It + // would be good to fix that. + n float64 +} + +func (it *itemBounds) hash(h *maphash.Hash, u *uniqueItems) { + maphash.WriteComparable(h, it.constraint) + maphash.WriteComparable(h, it.n) +} + +func (i *itemBounds) generate(g *generator) ast.Expr { + var keyword string + switch i.constraint { + case cue.LessThanOp: + keyword = "exclusiveMaximum" + case cue.LessThanEqualOp: + keyword = "maximum" + case cue.GreaterThanOp: + keyword = "exclusiveMinimum" + case cue.GreaterThanEqualOp: + keyword = "minimum" + default: + panic(fmt.Errorf("unexpected bound operand %v", i.constraint)) + } + return singleKeyword(keyword, ast.NewLit(token.FLOAT, fmt.Sprint(i.n))) +} + +func (i *itemBounds) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + return i +} + +// itemMultipleOf represents a multipleOf constraint +type itemMultipleOf struct { + n float64 +} + +func (it *itemMultipleOf) hash(h *maphash.Hash, u *uniqueItems) { + maphash.WriteComparable(h, it.n) +} + +func (i *itemMultipleOf) generate(g *generator) ast.Expr { + return singleKeyword("multipleOf", ast.NewLit(token.FLOAT, fmt.Sprint(i.n))) +} + +func (i *itemMultipleOf) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + return i +} + +// itemLengthBounds represents string length constraints +type itemLengthBounds struct { + constraint cue.Op // LessThanEqualOp, GreaterThanEqualOp + n int +} + +func (it *itemLengthBounds) hash(h *maphash.Hash, u *uniqueItems) { + maphash.WriteComparable(h, it.constraint) + maphash.WriteComparable(h, it.n) +} + +func (i *itemLengthBounds) generate(g *generator) ast.Expr { + var keyword string + switch i.constraint { + case cue.LessThanEqualOp: + keyword = "maxLength" + case cue.GreaterThanEqualOp: + keyword = "minLength" + default: + panic("unexpected constraint in length bounds") + } + + return singleKeyword(keyword, ast.NewLit(token.INT, fmt.Sprint(i.n))) +} + +func (i *itemLengthBounds) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + return i +} + +// itemItemsBounds represents array length constraints +type itemItemsBounds struct { + constraint cue.Op // LessThanEqualOp, GreaterThanEqualOp + n int +} + +func (it *itemItemsBounds) hash(h *maphash.Hash, u *uniqueItems) { + maphash.WriteComparable(h, it.constraint) + maphash.WriteComparable(h, it.n) +} + +func (i *itemItemsBounds) generate(g *generator) ast.Expr { + var keyword string + switch i.constraint { + case cue.LessThanEqualOp: + keyword = "maxItems" + case cue.GreaterThanEqualOp: + keyword = "minItems" + default: + panic("unexpected constraint in items bounds") + } + return singleKeyword(keyword, ast.NewLit(token.INT, fmt.Sprint(i.n))) +} + +func (i *itemItemsBounds) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + return i +} + +// itemPropertyBounds represents object property count constraints +type itemPropertyBounds struct { + constraint cue.Op // LessThanEqualOp, GreaterThanEqualOp + n int +} + +func (it *itemPropertyBounds) hash(h *maphash.Hash, u *uniqueItems) { + maphash.WriteComparable(h, it.constraint) + maphash.WriteComparable(h, it.n) +} + +func (i *itemPropertyBounds) generate(g *generator) ast.Expr { + var keyword string + switch i.constraint { + case cue.LessThanEqualOp: + keyword = "maxProperties" + case cue.GreaterThanEqualOp: + keyword = "minProperties" + default: + panic("unexpected constraint in items bounds") + } + return singleKeyword(keyword, ast.NewLit(token.INT, fmt.Sprint(i.n))) +} + +func (i *itemPropertyBounds) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + return i +} + +// itemItems represents the items and prefixItems constraint for arrays. +type itemItems struct { + // known prefix. + prefix []internItem + // all elements beyond the prefix. + rest internItem +} + +func (it *itemItems) hash(h *maphash.Hash, u *uniqueItems) { + for _, p := range it.prefix { + u.writeHash(h, p) + } + u.writeHash(h, it.rest) +} + +func (i *itemItems) generate(g *generator) ast.Expr { + fields := make([]ast.Decl, 0, 2) + if len(i.prefix) > 0 { + items := make([]ast.Expr, len(i.prefix)) + for i, e := range i.prefix { + items[i] = e.Value().generate(g) + } + fields = append(fields, makeField("prefixItems", &ast.ListLit{ + Elts: items, + })) + } + if i.rest.Value() != nil { + fields = append(fields, makeField("items", i.rest.Value().generate(g))) + } + return makeSchemaStructLit(fields...) +} + +func (i *itemItems) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + rest := i.rest + if rest.Value() != nil { + rest = f(rest, u) + } + prefix, changed := applyElems(i.prefix, f, u) + if !changed && rest == i.rest { + return i + } + return &itemItems{prefix: prefix, rest: rest} +} + +// itemContains represents a contains constraint for arrays +type itemContains struct { + elem internItem + min *int64 + max *int64 +} + +func (it *itemContains) hash(h *maphash.Hash, u *uniqueItems) { + u.writeHash(h, it.elem) + maphash.WriteComparable(h, it.min == nil) + if it.min != nil { + maphash.WriteComparable(h, *it.min) + } + maphash.WriteComparable(h, it.max == nil) + if it.max != nil { + maphash.WriteComparable(h, *it.max) + } +} + +func (i *itemContains) generate(g *generator) ast.Expr { + fields := []ast.Decl{makeField("contains", i.elem.Value().generate(g))} + if i.min != nil { + fields = append(fields, makeField("minContains", ast.NewLit(token.INT, fmt.Sprint(*i.min)))) + } + if i.max != nil { + fields = append(fields, makeField("maxContains", ast.NewLit(token.INT, fmt.Sprint(*i.max)))) + } + return makeSchemaStructLit(fields...) +} + +func (i *itemContains) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + elem := f(i.elem, u) + if elem == i.elem { + return i + } + return &itemContains{elem: elem, min: i.min, max: i.max} +} + +// property represents an object property +type property struct { + name string + item item +} + +// itemProperties represents object properties and associated keywords. +type itemProperties struct { + properties map[string]internItem + required []string + additionalProperties internItem + patternProperties map[string]internItem +} + +func (it *itemProperties) hash(h *maphash.Hash, u *uniqueItems) { + writeMapHash(h, it.properties, u) + for _, name := range slices.Sorted(slices.Values(it.required)) { + h.WriteString(name) + } + u.writeHash(h, it.additionalProperties) + writeMapHash(h, it.patternProperties, u) +} + +func (i *itemProperties) generate(g *generator) ast.Expr { + fields := []ast.Decl{} + if len(i.properties) > 0 { + propFields := make([]ast.Decl, 0, len(i.properties)) + for name, it := range i.properties { + propFields = append(propFields, makeField(name, it.Value().generate(g))) + } + slices.SortFunc(propFields, func(a, b ast.Decl) int { + return cmp.Compare(fieldLabel(a), fieldLabel(b)) + }) + fields = append(fields, makeField("properties", &ast.StructLit{Elts: propFields})) + } + if len(i.required) > 0 { + reqExprs := make([]ast.Expr, len(i.required)) + for j, r := range i.required { + reqExprs[j] = ast.NewString(r) + } + fields = append(fields, makeField("required", ast.NewList(reqExprs...))) + } + if i.additionalProperties.Value() != nil { + fields = append(fields, makeField("additionalProperties", i.additionalProperties.Value().generate(g))) + } + if len(i.patternProperties) > 0 { + pp := &ast.StructLit{} + for _, p := range slices.Sorted(maps.Keys(i.patternProperties)) { + pp.Elts = append(pp.Elts, makeField(p, i.patternProperties[p].Value().generate(g))) + } + fields = append(fields, makeField("patternProperties", pp)) + } + return makeSchemaStructLit(fields...) +} + +func (i *itemProperties) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + properties, changed0 := applyMap(i.properties, f, u) + patternProperties, changed1 := applyMap(i.patternProperties, f, u) + changed := changed0 || changed1 + additionalProperties := i.additionalProperties + if additionalProperties.Value() != nil { + if ap := f(additionalProperties, u); ap != additionalProperties { + additionalProperties = ap + changed = true + } + } + if !changed { + return i + } + return &itemProperties{ + properties: properties, + required: i.required, + additionalProperties: additionalProperties, + patternProperties: patternProperties, + } +} + +// itemIfThenElse represents if/then/else constraints +type itemIfThenElse struct { + ifElem internItem + thenElem internItem + elseElem internItem +} + +func (it *itemIfThenElse) hash(h *maphash.Hash, u *uniqueItems) { + u.writeHash(h, it.ifElem) + u.writeHash(h, it.thenElem) + u.writeHash(h, it.elseElem) +} + +func (i *itemIfThenElse) generate(g *generator) ast.Expr { + fields := []ast.Decl{makeField("if", i.ifElem.Value().generate(g))} + if i.thenElem.Value() != nil { + fields = append(fields, makeField("then", i.thenElem.Value().generate(g))) + } + if i.elseElem.Value() != nil { + fields = append(fields, makeField("else", i.elseElem.Value().generate(g))) + } + return makeSchemaStructLit(fields...) +} + +func (i *itemIfThenElse) apply(f func(internItem, *uniqueItems) internItem, u *uniqueItems) item { + ifElem := f(i.ifElem, u) + var thenElem, elseElem internItem + if i.thenElem.Value() != nil { + thenElem = f(i.thenElem, u) + } + if i.elseElem.Value() != nil { + elseElem = f(i.elseElem, u) + } + + if ifElem == i.ifElem && thenElem == i.thenElem && elseElem == i.elseElem { + return i + } + return &itemIfThenElse{ifElem: ifElem, thenElem: thenElem, elseElem: elseElem} +} + +func generateList(g *generator, items []internItem) ast.Expr { + exprs := make([]ast.Expr, len(items)) + for i, it := range items { + exprs[i] = it.Value().generate(g) + } + return ast.NewList(exprs...) +} + +func singleKeyword(name string, val ast.Expr) ast.Expr { + return makeSchemaStructLit(makeField(name, val)) +} + +// keywordGroups holds sets of JSON Schema keywords that +// interact directly with one another and therefore should not +// be merged with other keywords in the same group. +var keywordGroups = [][]string{ + {"properties", "patternProperties", "additionalProperties"}, + {"contains", "maxContains", "minContains"}, + {"items", "additionalItems", "prefixItems"}, + {"if", "then", "else"}, +} + +// keywordInteractions maps from a keyword to the set of +// keywords it interacts with (including itself). +var keywordInteractions = func() map[string][]string { + m := make(map[string][]string) + for _, ks := range keywordGroups { + for _, k := range ks { + m[k] = ks + } + } + return m +}() + +// fieldLabel extracts the field label name from a declaration. +func fieldLabel(d ast.Decl) string { + if f, ok := d.(*ast.Field); ok { + if name, _, _ := ast.LabelName(f.Label); name != "" { + return name + } + } + return "" +} + +// makeField creates a field with a string label and given value. +func makeField(name string, value ast.Expr) *ast.Field { + return &ast.Field{ + Label: ast.NewStringLabel(name), + Value: value, + } +} + +// makeSchemaStructLit creates a struct literal representing a JSON Schema +// schema, with fields in schema-centric order. +func makeSchemaStructLit(fields ...ast.Decl) *ast.StructLit { + slices.SortFunc(fields, func(a, b ast.Decl) int { + return cmpSchemaLabels(fieldLabel(a), fieldLabel(b)) + }) + return &ast.StructLit{ + Elts: fields, + } +} + +func cmpSchemaLabels(l1, l2 string) int { + return cmp.Or(cmp.Compare(labelPriority(l1), labelPriority(l2)), cmp.Compare(l1, l2)) +} + +// labelPriorityValues holds priority groups for sorting label names. +var labelPriorityValues = func() map[string]int { + // Always put these keywords at the start. + m := map[string]int{ + "$schema": 0, + "$defs": 1, + "type": 2, + } + // It's nice to group related keywords together. + n := len(m) + for i, g := range keywordGroups { + for _, name := range g { + m[name] = n + i + 1 + } + } + // Anything else gets put at the end in lexical order. + return m +}() + +func labelPriority(s string) int { + if pri, ok := labelPriorityValues[s]; ok { + return pri + } + return 1000 +} + +func writeMapHash[K cmp.Ordered](h *maphash.Hash, m map[K]internItem, u *uniqueItems) { + for _, k := range slices.Sorted(maps.Keys(m)) { + maphash.WriteComparable(h, k) + u.writeHash(h, m[k]) + } +} + +// writeExprHash hashes an AST expression using its formatted representation. +// This is a simple approach that ensures structurally equivalent expressions +// hash to the same value. +func writeExprHash(h *maphash.Hash, expr ast.Expr) { + // Use the formatted string representation of the expression for hashing. + // This ensures that expressions that format the same way will hash the same. + data, err := format.Node(expr, format.Simplify()) + if err != nil { + panic(fmt.Errorf("invalid ast Expr: %v", err)) + } + h.Write(data) +} + +type uniqueItems struct { + items *anyunique.Store[item, *uniqueItems] +} + +func newUniqueItems() *uniqueItems { + u := &uniqueItems{} + u.items = anyunique.New[item, *uniqueItems](u) + return u +} + +func (u *uniqueItems) writeHash(h *maphash.Hash, it internItem) { + u.items.WriteHash(h, it) +} + +func (u *uniqueItems) apply(it internItem, f func(internItem, *uniqueItems) internItem) internItem { + it1 := it.Value().apply(f, u) + if it1 == it.Value() { + return it + } + return u.items.Make(it1) +} + +type internItem = anyunique.Handle[item] + +func (u *uniqueItems) intern(it item) internItem { + return u.items.Make(it) +} + +// Hash implements [anyunique.Hasher.Hash]. +func (u *uniqueItems) Hash(h *maphash.Hash, x item) { + maphash.WriteComparable(h, reflect.TypeOf(x)) + x.hash(h, u) +} + +// Equal implements [anyunique.Hasher.Equal] for two +// items x0 and x1. +func (u *uniqueItems) Equal(x0, x1 item) bool { + if x0 == x1 { + return true + } + // TODO although this is typically only called when items are + // identical (because hash collisions are rare), it could made more + // efficient. It would be better to have custom equality methods for + // each type, or at least a reflect-based equality checker that + // avoids unexported fields and compares [anyunique.Handle] values + // without descending into them. + return reflect.DeepEqual(x0, x1) +} + +func applyMap(m map[string]internItem, f func(internItem, *uniqueItems) internItem, u *uniqueItems) (map[string]internItem, bool) { + var m1 map[string]internItem + for key, e := range m { + e1 := f(e, u) + if e1 == e { + continue + } + if m1 == nil { + m1 = make(map[string]internItem) + } + m1[key] = e1 + } + if m1 == nil { + return m, false + } + if len(m1) == len(m) { + return m1, true + } + for key, e := range m { + if _, ok := m1[key]; !ok { + m1[key] = e + } + } + return m1, true +} + +func applyElems(elems []internItem, f func(internItem, *uniqueItems) internItem, u *uniqueItems) ([]internItem, bool) { + changed := false + for i, e := range elems { + e1 := f(e, u) + if e1 == e { + continue + } + if !changed { + elems = slices.Clone(elems) + changed = true + } + elems[i] = e1 + } + return elems, changed +} diff --git a/vendor/cuelang.org/go/encoding/jsonschema/jsonschema.go b/vendor/cuelang.org/go/encoding/jsonschema/jsonschema.go index a62c5b1110..17f4d18944 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/jsonschema.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/jsonschema.go @@ -65,6 +65,9 @@ func Extract(data cue.InstanceOrValue, cfg *Config) (*ast.File, error) { cfg.StrictKeywords = true cfg.StrictFeatures = true } + if cfg.DefaultVersion.is(k8s) { + cfg.OpenOnlyWhenExplicit = true + } if cfg.ID == "" { // Always choose a fully-qualified ID for the schema, even // if it doesn't declare one. @@ -113,7 +116,7 @@ type Config struct { // JSON reference of location containing schemas. The empty string indicates // that there is a single schema at the root. If this is non-empty, // the referred-to location should be an object, and each member - // is taken to be a schema. + // is taken to be a schema (by default: see [Config.SingleRoot]) // // Examples: // "#/" or "#" top-level fields are schemas. @@ -124,6 +127,11 @@ type Config struct { // only. Just `#` is preferred. Root string + // SingleRoot is consulted only when Root is non-empty. + // If Root is non-empty and SingleRoot is true, then + // Root should specify the location of a single schema to extract. + SingleRoot bool + // AllowNonExistentRoot prevents an error when there is no value at // the above Root path. Such an error can be useful to signal that // the data may not be a JSON Schema, but is not always a good idea. @@ -216,7 +224,7 @@ type Config struct { // DefineSchema is called, if not nil, for any schema that is defined // within the json schema being converted but is mapped somewhere // external via [Config.MapRef]. The invoker of [Extract] is - // responsible for defining the schema e in the correct place as described + // responsible for defining the schema in the correct place as described // by the import path and its relative CUE path. // // The importPath and path are exactly as returned by [Config.MapRef]. @@ -224,7 +232,7 @@ type Config struct { // Note that importPath will never be empty, because if MapRef // returns an empty importPath, it's specifying an internal schema // which will be defined accordingly. - DefineSchema func(importPath string, path cue.Path, e ast.Expr) + DefineSchema func(importPath string, path cue.Path, e ast.Expr, docComment *ast.CommentGroup) // TODO: configurability to make it compatible with OpenAPI, such as // - locations of definitions: #/components/schemas, for instance. @@ -244,6 +252,24 @@ type Config struct { // are encountered. StrictKeywords bool + // OpenOnlyWhenExplicit requires a schema to be explicitly opened before a + // `...` will be added to a struct. A schema is considered + // explicitly opened when `additionalProperties` is present (unless + // its value is false) or, when the version is + // [VersionKubernetesCRD], when + // `x-kubernetes-preserve-unknown-fields` is set. + // + // Set to true when you'd like non-explicitly specified fields + // to be disallowed by default. + // + // This is useful for Kubernetes schemas and CRDs which never + // use additionalProperties: false but are nonetheless desired + // to be treated as closed. + // + // Implied true when the version is [VersionKubernetesCRD] or + // [VersionKubernetesAPI]. + OpenOnlyWhenExplicit bool + // DefaultVersion holds the default schema version to use // when no $schema field is present. If it is zero, [DefaultVersion] // will be used. diff --git a/vendor/cuelang.org/go/encoding/jsonschema/pointer.go b/vendor/cuelang.org/go/encoding/jsonschema/pointer.go deleted file mode 100644 index 1dbe4f0ce1..0000000000 --- a/vendor/cuelang.org/go/encoding/jsonschema/pointer.go +++ /dev/null @@ -1,45 +0,0 @@ -package jsonschema - -import "strings" - -// TODO this file contains functionality that mimics the JSON Pointer functionality -// in https://pkg.go.dev/github.com/go-json-experiment/json/jsontext#Pointer; -// perhaps use it when it moves into the stdlib as json/v2. - -var ( - jsonPtrEsc = strings.NewReplacer("~", "~0", "/", "~1") - jsonPtrUnesc = strings.NewReplacer("~0", "~", "~1", "/") -) - -// TODO(go1.23) func jsonPointerFromTokens(tokens iter.Seq[string]) string -func jsonPointerFromTokens(tokens func(func(string) bool)) string { - var buf strings.Builder - // TODO for tok := range tokens { - tokens(func(tok string) bool { - buf.WriteByte('/') - buf.WriteString(jsonPtrEsc.Replace(tok)) - return true - }) - return buf.String() -} - -// TODO(go1.23) func jsonPointerTokens(p string) iter.Seq[string] -func jsonPointerTokens(p string) func(func(string) bool) { - return func(yield func(string) bool) { - needUnesc := strings.IndexByte(p, '~') >= 0 - for len(p) > 0 { - p = strings.TrimPrefix(p, "/") - i := min(uint(strings.IndexByte(p, '/')), uint(len(p))) - var ok bool - if needUnesc { - ok = yield(jsonPtrUnesc.Replace(p[:i])) - } else { - ok = yield(p[:i]) - } - if !ok { - return - } - p = p[i:] - } - } -} diff --git a/vendor/cuelang.org/go/encoding/jsonschema/ref.go b/vendor/cuelang.org/go/encoding/jsonschema/ref.go index fd7bf644a6..1d3bc2348e 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/ref.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/ref.go @@ -19,6 +19,7 @@ import ( "fmt" "net/url" "path" + "slices" "strconv" "strings" @@ -26,7 +27,7 @@ import ( "cuelang.org/go/cue/ast" "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" - "cuelang.org/go/internal" + "cuelang.org/go/encoding/json" ) func parseRootRef(str string) (cue.Path, error) { @@ -44,22 +45,25 @@ func parseRootRef(str string) (cue.Path, error) { // (technically a trailing slash `/` means there's an empty // final element). u.Fragment = strings.TrimSuffix(u.Fragment, "/") - fragmentParts := collectSlice(jsonPointerTokens(u.Fragment)) + fragmentParts := slices.Collect(json.Pointer(u.Fragment).Tokens()) var selectors []cue.Selector for _, r := range fragmentParts { - // Technically this is incorrect because a numeric - // element could also index into a list, but the - // resulting CUE path will not allow that. - selectors = append(selectors, cue.Str(r)) + if i, err := strconv.ParseUint(r, 10, 64); err == nil && strconv.FormatUint(i, 10) == r { + // Technically this is incorrect because a numeric element + // could also be a string selector and the resulting path + // will not allow that. + selectors = append(selectors, cue.Index(int64(i))) + } else { + selectors = append(selectors, cue.Str(r)) + } } return cue.MakePath(selectors...), nil } var errRefNotFound = errors.New("JSON Pointer reference not found") -func lookupJSONPointer(v cue.Value, p string) (_ cue.Value, _err error) { - // TODO(go1.23) for part := range jsonPointerTokens(p) - jsonPointerTokens(p)(func(part string) bool { +func lookupJSONPointer(v cue.Value, p string) (cue.Value, error) { + for part := range json.Pointer(p).Tokens() { // Note: a JSON Pointer doesn't distinguish between indexing // and struct lookup. We have to use the value itself to decide // which operation is appropriate. @@ -71,23 +75,19 @@ func lookupJSONPointer(v cue.Value, p string) (_ cue.Value, _err error) { idx := int64(0) if len(part) > 1 && part[0] == '0' { // Leading zeros are not allowed - _err = errRefNotFound - return false + return cue.Value{}, errRefNotFound } idx, err := strconv.ParseInt(part, 10, 64) if err != nil { - _err = errRefNotFound - return false + return cue.Value{}, errRefNotFound } v = v.LookupPath(cue.MakePath(cue.Index(idx))) } if !v.Exists() { - _err = errRefNotFound - return false + return cue.Value{}, errRefNotFound } - return true - }) - return v, _err + } + return v, nil } func sameSchemaRoot(u1, u2 *url.URL) bool { @@ -122,8 +122,7 @@ func (s *state) resolveURI(n cue.Value) *url.URL { return u } - // TODO(go1.23) use ResolveReference directly. - return resolveReference(s.schemaRoot().id, u) + return s.schemaRoot().id.ResolveReference(u) } // schemaRoot returns the state for the nearest enclosing @@ -161,7 +160,7 @@ func defaultMapRef( ) (importPath string, path cue.Path, err error) { var fragment string if loc.IsLocal { - fragment = cuePathToJSONPointer(loc.Path) + fragment = mustCUEPathToJSONPointer(loc.Path) } else { // It's external: use mapURLFn. u := ref(*loc.ID) @@ -176,7 +175,7 @@ func defaultMapRef( if len(fragment) > 0 && fragment[0] != '/' { return "", cue.Path{}, fmt.Errorf("anchors (%s) not supported", fragment) } - parts := collectSlice(jsonPointerTokens(fragment)) + parts := slices.Collect(json.Pointer(fragment).Tokens()) labels, err := mapFn(token.Pos{}, parts) if err != nil { return "", cue.Path{}, err @@ -203,13 +202,11 @@ func defaultMap(p token.Pos, a []string) ([]ast.Label, error) { // TODO this is needlessly inefficient, as we're putting something // back together that was already joined before defaultMap was // invoked. This does avoid dual implementations though. - p := jsonPointerFromTokens(sliceValues(a)) - return []ast.Label{ast.NewIdent("_#defs"), ast.NewString(p)}, nil + p := json.PointerFromTokens(slices.Values(a)) + return []ast.Label{ast.NewIdent("_#defs"), ast.NewString(string(p))}, nil } name := a[1] - if ast.IsValidIdent(name) && - name != rootDefs[1:] && - !internal.IsDefOrHidden(name) { + if name != rootDefs[1:] && !ast.StringLabelNeedsQuoting(name) { return []ast.Label{ast.NewIdent("#" + name)}, nil } return []ast.Label{ast.NewIdent(rootDefs), ast.NewString(name)}, nil diff --git a/vendor/cuelang.org/go/encoding/jsonschema/resolveref_v1.22.go b/vendor/cuelang.org/go/encoding/jsonschema/resolveref_v1.22.go deleted file mode 100644 index b66b30518b..0000000000 --- a/vendor/cuelang.org/go/encoding/jsonschema/resolveref_v1.22.go +++ /dev/null @@ -1,46 +0,0 @@ -//go:build !go1.23 - -package jsonschema - -import "net/url" - -// resolveReference is exactly like [url.URL.ResolveReference] -// except that it fixes https://go.dev/issue/66084, which -// has been fixed in Go 1.23 (https://go.dev/cl/572915) but not go1.22 -// TODO(go1.23) remove this and use ResolveReference directly] -func resolveReference(u, ref *url.URL) *url.URL { - if !hitsBug(u, ref) { - return u.ResolveReference(ref) - } - url := *ref - if ref.Scheme == "" { - url.Scheme = u.Scheme - } - if ref.Path == "" && !ref.ForceQuery && ref.RawQuery == "" { - url.RawQuery = u.RawQuery - if ref.Fragment == "" { - url.Fragment = u.Fragment - url.RawFragment = u.RawFragment - } - } - url.Opaque = u.Opaque - url.User = nil - url.Host = "" - url.Path = "" - return &url -} - -// This mirrors the structure of the stdlib [url.URL.ResolveReference] -// method. -func hitsBug(u, ref *url.URL) bool { - if ref.Scheme != "" || ref.Host != "" || ref.User != nil { - return false - } - if ref.Opaque != "" { - return false - } - if ref.Path == "" && u.Opaque != "" { - return true - } - return false -} diff --git a/vendor/cuelang.org/go/encoding/jsonschema/resolveref_v1.23.go b/vendor/cuelang.org/go/encoding/jsonschema/resolveref_v1.23.go deleted file mode 100644 index a878c93e7e..0000000000 --- a/vendor/cuelang.org/go/encoding/jsonschema/resolveref_v1.23.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build go1.23 - -// TODO(go1.12) remove this file. - -package jsonschema - -import "net/url" - -func resolveReference(u, ref *url.URL) *url.URL { - return u.ResolveReference(ref) -} diff --git a/vendor/cuelang.org/go/encoding/jsonschema/structbuilder.go b/vendor/cuelang.org/go/encoding/jsonschema/structbuilder.go index 5cd875013b..5caf4eb29c 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/structbuilder.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/structbuilder.go @@ -3,6 +3,8 @@ package jsonschema import ( "cmp" "fmt" + "maps" + "slices" "cuelang.org/go/cue" "cuelang.org/go/cue/ast" @@ -201,8 +203,7 @@ func (b *structBuilder) appendDecls(n *structBuilderNode, db *declBuilder) (_err return _err } } - // TODO slices.SortedFunc(maps.Keys(n.entries), cmpSelector) - for _, sel := range sortedKeys(n.entries, cmpSelector) { + for _, sel := range slices.SortedFunc(maps.Keys(n.entries), cmpSelector) { entry := n.entries[sel] db.pushPath(sel) err := b.appendDecls(entry, db) diff --git a/vendor/cuelang.org/go/encoding/jsonschema/util.go b/vendor/cuelang.org/go/encoding/jsonschema/util.go index 4320d0c4e6..6ee3d56b03 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/util.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/util.go @@ -17,12 +17,12 @@ package jsonschema import ( "fmt" "slices" - "strconv" "strings" "cuelang.org/go/cue" "cuelang.org/go/cue/ast" "cuelang.org/go/cue/token" + "cuelang.org/go/encoding/json" ) // TODO a bunch of stuff in this file is potentially suitable @@ -37,7 +37,7 @@ func pathConcat(p1, p2 cue.Path) cue.Path { if len(sels2) == 0 { return p1 } - return cue.MakePath(append(slices.Clip(sels1), sels2...)...) + return cue.MakePath(slices.Concat(sels1, sels2)...) } func labelsToCUEPath(labels []ast.Label) (cue.Path, error) { @@ -112,9 +112,7 @@ func pathRefSyntax(cuePath cue.Path, root ast.Expr) (ast.Expr, error) { // be exposed as a method on [cue.Path], say // `SyntaxForDefinition` or something. func exprAtPath(path cue.Path, expr ast.Expr) (ast.Expr, error) { - sels := path.Selectors() - for i := len(sels) - 1; i >= 0; i-- { - sel := sels[i] + for i, sel := range slices.Backward(path.Selectors()) { label, err := labelForSelector(sel) if err != nil { return nil, err @@ -161,23 +159,12 @@ func labelForSelector(sel cue.Selector) (ast.Label, error) { } } -func cuePathToJSONPointer(p cue.Path) string { - return jsonPointerFromTokens(func(yield func(s string) bool) { - for _, sel := range p.Selectors() { - var token string - switch sel.Type() { - case cue.StringLabel: - token = sel.Unquoted() - case cue.IndexLabel: - token = strconv.Itoa(sel.Index()) - default: - panic(fmt.Errorf("cannot convert selector %v to JSON pointer", sel)) - } - if !yield(token) { - return - } - } - }) +func mustCUEPathToJSONPointer(p cue.Path) string { + ptr, err := json.PointerFromCUEPath(p) + if err != nil { + panic(err) + } + return string(ptr) } // relPath returns the path to v relative to root, @@ -197,34 +184,3 @@ func sliceHasPrefix[E comparable](s1, s2 []E) bool { } return slices.Equal(s1[:len(s2)], s2) } - -// TODO remove this when we can use [slices.SortedFunc] and [maps.Keys]. -func sortedKeys[K comparable, V any](m map[K]V, cmp func(K, K) int) []K { - ks := make([]K, 0, len(m)) - for k := range m { - ks = append(ks, k) - } - slices.SortFunc(ks, cmp) - return ks -} - -// TODO(go1.23) use slices.Collect -func collectSlice[E any](seq func(func(E) bool)) []E { - var s []E - seq(func(v E) bool { - s = append(s, v) - return true - }) - return s -} - -// TODO(go1.23) use slices.Values -func sliceValues[Slice ~[]E, E any](s Slice) func(func(E) bool) { - return func(yield func(E) bool) { - for _, v := range s { - if !yield(v) { - return - } - } - } -} diff --git a/vendor/cuelang.org/go/encoding/jsonschema/version.go b/vendor/cuelang.org/go/encoding/jsonschema/version.go index d6dc767208..d9d11beee3 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/version.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/version.go @@ -19,7 +19,7 @@ import ( "strings" ) -//go:generate go run golang.org/x/tools/cmd/stringer -type=Version -linecomment +//go:generate go tool stringer -type=Version -linecomment type Version int @@ -34,11 +34,24 @@ const ( numJSONSchemaVersions // unknown - // Note: OpenAPI stands alone: it's not in the regular JSON Schema lineage. - VersionOpenAPI // OpenAPI 3.0 + // Note: The following versions stand alone: they're not in the regular JSON Schema lineage. + VersionOpenAPI // OpenAPI 3.0 + VersionKubernetesAPI // Kubernetes API + VersionKubernetesCRD // Kubernetes CRD ) -const openAPI = versionSet(1 << VersionOpenAPI) +const ( + openAPI = versionSet(1 << VersionOpenAPI) + k8sAPI = versionSet(1 << VersionKubernetesAPI) + k8sCRD = versionSet(1 << VersionKubernetesCRD) + k8s = k8sAPI | k8sCRD + openAPILike = openAPI | k8s +) + +// is reports whether v is in the set vs. +func (v Version) is(vs versionSet) bool { + return vs.contains(v) +} type versionSet int diff --git a/vendor/cuelang.org/go/encoding/jsonschema/version_string.go b/vendor/cuelang.org/go/encoding/jsonschema/version_string.go index ff122a6bae..b9439d1e60 100644 --- a/vendor/cuelang.org/go/encoding/jsonschema/version_string.go +++ b/vendor/cuelang.org/go/encoding/jsonschema/version_string.go @@ -16,15 +16,18 @@ func _() { _ = x[VersionDraft2020_12-5] _ = x[numJSONSchemaVersions-6] _ = x[VersionOpenAPI-7] + _ = x[VersionKubernetesAPI-8] + _ = x[VersionKubernetesCRD-9] } -const _Version_name = "unknownhttp://json-schema.org/draft-04/schema#http://json-schema.org/draft-06/schema#http://json-schema.org/draft-07/schema#https://json-schema.org/draft/2019-09/schemahttps://json-schema.org/draft/2020-12/schemaunknownOpenAPI 3.0" +const _Version_name = "unknownhttp://json-schema.org/draft-04/schema#http://json-schema.org/draft-06/schema#http://json-schema.org/draft-07/schema#https://json-schema.org/draft/2019-09/schemahttps://json-schema.org/draft/2020-12/schemaunknownOpenAPI 3.0Kubernetes APIKubernetes CRD" -var _Version_index = [...]uint8{0, 7, 46, 85, 124, 168, 212, 219, 230} +var _Version_index = [...]uint16{0, 7, 46, 85, 124, 168, 212, 219, 230, 244, 258} func (i Version) String() string { - if i < 0 || i >= Version(len(_Version_index)-1) { + idx := int(i) - 0 + if i < 0 || idx >= len(_Version_index)-1 { return "Version(" + strconv.FormatInt(int64(i), 10) + ")" } - return _Version_name[_Version_index[i]:_Version_index[i+1]] + return _Version_name[_Version_index[idx]:_Version_index[idx+1]] } diff --git a/vendor/cuelang.org/go/encoding/openapi/build.go b/vendor/cuelang.org/go/encoding/openapi/build.go index 7cb06fb76e..bc52f110f1 100644 --- a/vendor/cuelang.org/go/encoding/openapi/build.go +++ b/vendor/cuelang.org/go/encoding/openapi/build.go @@ -15,20 +15,21 @@ package openapi import ( + "cmp" "fmt" + "maps" "math" "path" "regexp" "slices" - "sort" "strings" "cuelang.org/go/cue" "cuelang.org/go/cue/ast" "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" - "cuelang.org/go/internal" "cuelang.org/go/internal/core/adt" + "cuelang.org/go/internal/core/subsume" ) type buildContext struct { @@ -78,7 +79,7 @@ func schemas(g *Generator, inst cue.InstanceOrValue) (schemas *ast.StructLit, er } // verify that certain elements are still passed. - for _, f := range strings.Split( + for f := range strings.SplitSeq( "version,title,allOf,anyOf,not,enum,Schema/properties,Schema/items"+ "nullable,type", ",") { if fieldFilter.MatchString(f) { @@ -149,13 +150,7 @@ func schemas(g *Generator, inst cue.InstanceOrValue) (schemas *ast.StructLit, er done = len(c.externalRefs) // From now on, all references need to be expanded - external := []string{} - for k := range c.externalRefs { - external = append(external, k) - } - slices.Sort(external) - - for _, k := range external { + for _, k := range slices.Sorted(maps.Keys(c.externalRefs)) { ext := c.externalRefs[k] c.instExt = ext.inst sels := ext.path.Selectors() @@ -166,11 +161,8 @@ func schemas(g *Generator, inst cue.InstanceOrValue) (schemas *ast.StructLit, er } } - a := c.schemas.Elts - sort.Slice(a, func(i, j int) bool { - x, _, _ := ast.LabelName(a[i].(*ast.Field).Label) - y, _, _ := ast.LabelName(a[j].(*ast.Field).Label) - return x < y + slices.SortFunc(c.schemas.Elts, func(a, b ast.Decl) int { + return cmp.Compare(label(a), label(b)) }) return (*ast.StructLit)(c.schemas), c.errs @@ -265,7 +257,7 @@ func (b *builder) fillSchema(v cue.Value) *ast.StructLit { } schema := b.finish() - s := (*ast.StructLit)(schema) + s := schema simplify(b, s) @@ -286,15 +278,12 @@ func value(d ast.Decl) ast.Expr { } func sortSchema(s *ast.StructLit) { - sort.Slice(s.Elts, func(i, j int) bool { - iName := label(s.Elts[i]) - jName := label(s.Elts[j]) - pi := fieldOrder[iName] - pj := fieldOrder[jName] - if pi != pj { - return pi > pj - } - return iName < jName + slices.SortFunc(s.Elts, func(a, b ast.Decl) int { + aName := label(a) + bName := label(b) + aOrder := fieldOrder[aName] + bOrder := fieldOrder[bName] + return cmp.Or(-cmp.Compare(aOrder, bOrder), cmp.Compare(aName, bName)) }) } @@ -540,7 +529,7 @@ func (b *builder) disjunction(a []cue.Value, f typeFunc) { c := newOASBuilder(b) c.value(v, f) t := c.finish() - schemas[i] = (*ast.StructLit)(t) + schemas[i] = t if len(t.Elts) == 0 { if c.typ == "" { return @@ -562,7 +551,7 @@ func (b *builder) disjunction(a []cue.Value, f typeFunc) { continue } err := v.Subsume(w, cue.Schema()) - if err == nil || errors.Is(err, internal.ErrInexact) { + if err == nil || errors.Is(err, subsume.ErrInexact) { subsumed = append(subsumed, schemas[j]) } } @@ -884,7 +873,7 @@ func (b *builder) listCap(v cue.Value) { // must be type, so okay. case cue.NotEqualOp: i := b.int(a[0]) - b.setNot("allOff", ast.NewList( + b.setNot("allOf", ast.NewList( b.kv("minItems", i), b.kv("maxItems", i), )) @@ -924,7 +913,7 @@ func (b *builder) number(v cue.Value) { case cue.NotEqualOp: i := b.big(a[0]) - b.setNot("allOff", ast.NewList( + b.setNot("allOf", ast.NewList( b.kv("minimum", i), b.kv("maximum", i), )) @@ -1218,7 +1207,7 @@ func (b *builder) add(t *ast.StructLit) { func (b *builder) addConjunct(f func(*builder)) { c := newOASBuilder(b) f(c) - b.add((*ast.StructLit)(c.finish())) + b.add(c.finish()) } func (b *builder) addRef(v cue.Value, inst cue.Value, ref cue.Path) { diff --git a/vendor/cuelang.org/go/encoding/openapi/cycle.go b/vendor/cuelang.org/go/encoding/openapi/cycle.go index a8c6933d02..8c39c25d44 100644 --- a/vendor/cuelang.org/go/encoding/openapi/cycle.go +++ b/vendor/cuelang.org/go/encoding/openapi/cycle.go @@ -15,6 +15,8 @@ package openapi import ( + "slices" + "cuelang.org/go/cue" "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" @@ -40,17 +42,15 @@ func (b *builder) checkCycle(v cue.Value) bool { ctx := eval.NewContext(r, n) err := dep.Visit(nil, ctx, n, func(d dep.Dependency) error { - for _, m := range b.ctx.cycleNodes { - if m == d.Node { - var p token.Pos - if src := d.Node.Source(); src != nil { - p = src.Pos() - } - err := errors.Newf(p, - "cycle in reference at %v: cyclic structures not allowed when reference expansion is requested", v.Path()) - b.ctx.errs = errors.Append(b.ctx.errs, err) - return err + if slices.Contains(b.ctx.cycleNodes, d.Node) { + var p token.Pos + if src := d.Node.Source(); src != nil { + p = src.Pos() } + err := errors.Newf(p, + "cycle in reference at %v: cyclic structures not allowed when reference expansion is requested", v.Path()) + b.ctx.errs = errors.Append(b.ctx.errs, err) + return err } return nil }) diff --git a/vendor/cuelang.org/go/encoding/openapi/decode.go b/vendor/cuelang.org/go/encoding/openapi/decode.go index 279610fa0c..5a6fea05e6 100644 --- a/vendor/cuelang.org/go/encoding/openapi/decode.go +++ b/vendor/cuelang.org/go/encoding/openapi/decode.go @@ -106,7 +106,7 @@ func Extract(data cue.InstanceOrValue, c *Config) (*ast.File, error) { // TODO: do we want to store the OpenAPI version? // if version, _ := v.Lookup("openapi").String(); version != "" { - // add(internal.NewAttr("openapi", "version="+ version)) + // add(&ast.Attribute{Text: fmt.Sprintf("@openapi(version=%s)", version)}) // } if info := v.LookupPath(cue.MakePath(cue.Str("info"))); info.Exists() { @@ -157,9 +157,7 @@ func openAPIMapping(pos token.Pos, a []string) ([]ast.Label, error) { oapiSchemas, strings.Join(a, "/")) } name := a[2] - if ast.IsValidIdent(name) && - name != rootDefs[1:] && - !internal.IsDefOrHidden(name) { + if name != rootDefs[1:] && !ast.StringLabelNeedsQuoting(name) { return []ast.Label{ast.NewIdent("#" + name)}, nil } return []ast.Label{ast.NewIdent(rootDefs), ast.NewString(name)}, nil diff --git a/vendor/cuelang.org/go/encoding/openapi/openapi.go b/vendor/cuelang.org/go/encoding/openapi/openapi.go index f4efc39791..9e594a11ee 100644 --- a/vendor/cuelang.org/go/encoding/openapi/openapi.go +++ b/vendor/cuelang.org/go/encoding/openapi/openapi.go @@ -87,19 +87,14 @@ type Generator = Config // Gen generates the set OpenAPI schema for all top-level types of the // given instance. +// +// Deprecated: use [Generate]. func Gen(inst cue.InstanceOrValue, c *Config) ([]byte, error) { - if c == nil { - c = defaultConfig - } - all, err := schemas(c, inst) - if err != nil { - return nil, err - } - top, err := c.compose(inst, all) + f, err := Generate(inst, c) if err != nil { return nil, err } - topValue := inst.Value().Context().BuildExpr(top) + topValue := inst.Value().Context().BuildFile(f) if err := topValue.Err(); err != nil { return nil, err } diff --git a/vendor/cuelang.org/go/encoding/protobuf/parse.go b/vendor/cuelang.org/go/encoding/protobuf/parse.go index 09929f53bd..2d3846d78c 100644 --- a/vendor/cuelang.org/go/encoding/protobuf/parse.go +++ b/vendor/cuelang.org/go/encoding/protobuf/parse.go @@ -20,6 +20,7 @@ import ( "os" "path" "path/filepath" + "slices" "strconv" "strings" "text/scanner" @@ -260,8 +261,8 @@ func (p *protoConverter) resolve(pos scanner.Position, name string, options []*p if strings.HasPrefix(name, ".") { return p.resolveTopScope(pos, name[1:], options) } - for i := len(p.scope) - 1; i > 0; i-- { - if m, ok := p.scope[i][name]; ok { + for _, scope := range slices.Backward(p.scope) { + if m, ok := scope[name]; ok { return m.cue() } } @@ -276,7 +277,11 @@ func (p *protoConverter) resolveTopScope(pos scanner.Position, name string, opti if k == -1 { i = len(name) } - if m, ok := p.scope[0][name[:i]]; ok { + curName := name[:i] + if local, ok := strings.CutPrefix(curName, p.protoPkg+"."); ok { + curName = local + } + if m, ok := p.scope[0][curName]; ok { if m.pkg != nil { p.imported[m.pkg.qualifiedImportPath()] = true } @@ -297,7 +302,7 @@ func (p *protoConverter) resolveTopScope(pos scanner.Position, name string, opti } func (p *protoConverter) doImport(v *proto.Import) error { - if v.Filename == "cue/cue.proto" { + if p.mapBuiltinPackage(v.Filename) { return nil } @@ -318,10 +323,6 @@ func (p *protoConverter) doImport(v *proto.Import) error { return err } - if !p.mapBuiltinPackage(v.Position, v.Filename, filename == "") { - return nil - } - imp, err := p.state.parse(filename, nil) if err != nil { fail(v.Position, err) @@ -529,6 +530,7 @@ func (p *protoConverter) messageField(s *ast.StructLit, i int, v proto.Visitee) if !o.required { f.Optional = token.NoSpace.Pos() + f.Constraint = token.OPTION } case *proto.Enum: @@ -722,6 +724,7 @@ func (p *protoConverter) oneOf(x *proto.Oneof) { newStruct() oneOf := p.parseField(s, 0, x.Field) oneOf.Optional = token.NoPos + oneOf.Constraint = token.ILLEGAL case *proto.Comment: cg := comment(x, false) @@ -761,6 +764,7 @@ func (p *protoConverter) parseField(s *ast.StructLit, i int, x *proto.Field) *as if !o.required { f.Optional = token.NoSpace.Pos() + f.Constraint = token.OPTION } return f } @@ -795,6 +799,7 @@ func (p *optionParser) parse(options []*proto.Option) { p.message.Elts = append(p.message.Elts, constraint) if !p.required { constraint.Optional = token.NoSpace.Pos() + constraint.Constraint = token.OPTION } case "(google.api.field_behavior)": if o.Constant.Source == "REQUIRED" { diff --git a/vendor/cuelang.org/go/encoding/protobuf/protobuf.go b/vendor/cuelang.org/go/encoding/protobuf/protobuf.go index 477f98a93e..7a24aa8fc0 100644 --- a/vendor/cuelang.org/go/encoding/protobuf/protobuf.go +++ b/vendor/cuelang.org/go/encoding/protobuf/protobuf.go @@ -99,7 +99,6 @@ import ( "cuelang.org/go/cue/parser" "cuelang.org/go/cue/token" "cuelang.org/go/internal" - "cuelang.org/go/mod/module" // Generated protobuf CUE may use builtins. Ensure that these can always be // found, even if the user does not use cue/load or another package that @@ -189,12 +188,7 @@ func NewExtractor(c *Config) *Extractor { // TODO(rogpeppe) the Go package path might itself include a major // version, so we should probably consider that too. if c.Module != "" { - var ok bool - modulePath, _, ok = module.SplitPathVersion(c.Module) - if !ok { - modulePath = c.Module - - } + modulePath, _, _ = ast.SplitPackageVersion(c.Module) } cwd, _ := os.Getwd() b := &Extractor{ diff --git a/vendor/cuelang.org/go/encoding/protobuf/textproto/decoder.go b/vendor/cuelang.org/go/encoding/protobuf/textproto/decoder.go index 01f63efc16..349e435f73 100644 --- a/vendor/cuelang.org/go/encoding/protobuf/textproto/decoder.go +++ b/vendor/cuelang.org/go/encoding/protobuf/textproto/decoder.go @@ -320,17 +320,10 @@ func (d *decoder) decodeMsg(m *mapping, n []*pbast.Node) ast.Expr { } if value != nil { - var label ast.Label - if s := f.CUEName; ast.IsValidIdent(s) { - label = ast.NewIdent(s) - } else { - label = ast.NewString(s) - - } // TODO: convert line number information. However, position // information in textpbfmt packages is too wonky to be useful f := &ast.Field{ - Label: label, + Label: ast.NewStringLabel(f.CUEName), Value: value, // Attrs: []*ast.Attribute{{Text: f.attr.}}, } diff --git a/vendor/cuelang.org/go/encoding/protobuf/textproto/encoder.go b/vendor/cuelang.org/go/encoding/protobuf/textproto/encoder.go index 7994089898..3dbcf61ddf 100644 --- a/vendor/cuelang.org/go/encoding/protobuf/textproto/encoder.go +++ b/vendor/cuelang.org/go/encoding/protobuf/textproto/encoder.go @@ -150,7 +150,7 @@ func (e *encoder) encodeMsg(parent *pbast.Node, v cue.Value) { func copyMeta(x *pbast.Node, v cue.Value) { for _, doc := range v.Doc() { s := strings.TrimRight(doc.Text(), "\n") - for _, c := range strings.Split(s, "\n") { + for c := range strings.SplitSeq(s, "\n") { x.PreComments = append(x.PreComments, "# "+c) } } diff --git a/vendor/cuelang.org/go/encoding/protobuf/types.go b/vendor/cuelang.org/go/encoding/protobuf/types.go index b451fbfbee..beb2b57dea 100644 --- a/vendor/cuelang.org/go/encoding/protobuf/types.go +++ b/vendor/cuelang.org/go/encoding/protobuf/types.go @@ -16,7 +16,6 @@ package protobuf import ( "fmt" - "text/scanner" "cuelang.org/go/cue/ast" "cuelang.org/go/cue/parser" @@ -84,11 +83,11 @@ var ( importStruct = ast.NewImport(nil, "struct") ) -func (p *protoConverter) mapBuiltinPackage(pos scanner.Position, file string, required bool) (generate bool) { +func (p *protoConverter) mapBuiltinPackage(file string) (found bool) { // Map some builtin types to their JSON/CUE mappings. switch file { - case "gogoproto/gogo.proto": - + case "cue/cue.proto": + return true case "google/protobuf/struct.proto": p.setBuiltin("google.protobuf.Struct", func() ast.Expr { return ast.NewStruct() @@ -118,7 +117,7 @@ func (p *protoConverter) mapBuiltinPackage(pos scanner.Position, file string, re return predeclared("number") }, nil) - return false + return true case "google/protobuf/empty.proto": f := func() ast.Expr { @@ -129,7 +128,7 @@ func (p *protoConverter) mapBuiltinPackage(pos scanner.Position, file string, re ) } p.setBuiltin("google.protobuf.Empty", f, pkgStruct) - return false + return true case "google/protobuf/duration.proto": f := func() ast.Expr { @@ -137,7 +136,7 @@ func (p *protoConverter) mapBuiltinPackage(pos scanner.Position, file string, re return ast.NewSel(time, "Duration") } p.setBuiltin("google.protobuf.Duration", f, pkgTime) - return false + return true case "google/protobuf/timestamp.proto": f := func() ast.Expr { @@ -145,7 +144,7 @@ func (p *protoConverter) mapBuiltinPackage(pos scanner.Position, file string, re return ast.NewSel(time, "Time") } p.setBuiltin("google.protobuf.Timestamp", f, pkgTime) - return false + return true case "google/protobuf/any.proto": // TODO: technically, the value should be `_` (anything), but that @@ -160,7 +159,7 @@ func (p *protoConverter) mapBuiltinPackage(pos scanner.Position, file string, re // The remaining fields of this object correspond to fields of the proto messsage. If the embedded message is well-known and has a custom JSON representation, that representation is assigned to the 'value' field. "@type": string, }`, nil) - return false + return true case "google/protobuf/wrappers.proto": p.setBuiltinParse("google.protobuf.DoubleValue", `null | float`, nil) @@ -172,17 +171,12 @@ func (p *protoConverter) mapBuiltinPackage(pos scanner.Position, file string, re p.setBuiltinParse("google.protobuf.BoolValue", `null | bool`, nil) p.setBuiltinParse("google.protobuf.StringValue", `null | string`, nil) p.setBuiltinParse("google.protobuf.BytesValue", `null | bytes`, nil) - return false - - // case "google/protobuf/field_mask.proto": - // p.setBuiltin("google.protobuf.FieldMask", "protobuf.FieldMask", nil) + return true - // protobuf.Any + // case "google/protobuf/field_mask.proto": + // p.setBuiltin("google.protobuf.FieldMask", "protobuf.FieldMask", nil) - default: - if required { - failf(pos, "import %q not found", file) - } + // protobuf.Any } - return true + return false } diff --git a/vendor/cuelang.org/go/encoding/protobuf/util.go b/vendor/cuelang.org/go/encoding/protobuf/util.go index 13afa50326..43949ebdeb 100644 --- a/vendor/cuelang.org/go/encoding/protobuf/util.go +++ b/vendor/cuelang.org/go/encoding/protobuf/util.go @@ -40,18 +40,15 @@ type protoError struct { error } -var ( - newSection = token.NewSection.Pos() -) +var newSection = token.NewSection.Pos() -func addComments(f ast.Node, i int, doc, inline *proto.Comment) bool { +func addComments(f ast.Node, i int, doc, inline *proto.Comment) { cg := comment(doc, true) if cg != nil && len(cg.List) > 0 && i > 0 { cg.List[0].Slash = newSection } ast.AddComment(f, cg) ast.AddComment(f, comment(inline, false)) - return doc != nil } func comment(c *proto.Comment, doc bool) *ast.CommentGroup { diff --git a/vendor/cuelang.org/go/encoding/toml/decode.go b/vendor/cuelang.org/go/encoding/toml/decode.go index 8c7da995a7..0670e2ca25 100644 --- a/vendor/cuelang.org/go/encoding/toml/decode.go +++ b/vendor/cuelang.org/go/encoding/toml/decode.go @@ -202,11 +202,28 @@ func (d *Decoder) nextRootNode(tnode *toml.Node) error { case toml.Table: // Tables always begin a new line. key, keyElems := d.decodeKey("", tnode.Key()) + + // Check if this table is a subtable of an existing array element + array := d.findArrayPrefix(key) + var actualKey string + if array != nil { // [last_array.new_table] + if array.rkey == key { + return d.nodeErrf(tnode.Child(), "cannot redeclare table array %q as a table", key) + } + // For subtables within array elements, we need to use the current array element's key + // to avoid false duplicate key errors between different array elements + subKey := key[len(array.rkey)+1:] // Remove the array prefix and dot + actualKey = fmt.Sprintf("%s.%d.%s", array.rkey, len(array.list.Elts)-1, subKey) + + } else { + actualKey = key + } + // All table keys must be unique, including for the top-level table. - if d.seenTableKeys[key] { + if d.seenTableKeys[actualKey] { return d.nodeErrf(tnode.Child(), "duplicate key: %s", key) } - d.seenTableKeys[key] = true + d.seenTableKeys[actualKey] = true // We want a multi-line struct with curly braces, // just like TOML's tables are on multiple lines. @@ -215,11 +232,7 @@ func (d *Decoder) nextRootNode(tnode *toml.Node) error { Lbrace: token.NoPos.WithRel(token.Blank), Rbrace: token.NoPos.WithRel(token.Newline), } - array := d.findArrayPrefix(key) if array != nil { // [last_array.new_table] - if array.rkey == key { - return d.nodeErrf(tnode.Child(), "cannot redeclare table array %q as a table", key) - } subKeyElems := keyElems[array.level:] topField, leafField := d.inlineFields(subKeyElems, token.Newline) array.lastTable.Elts = append(array.lastTable.Elts, topField) @@ -229,7 +242,7 @@ func (d *Decoder) nextRootNode(tnode *toml.Node) error { d.topFile.Elts = append(d.topFile.Elts, topField) leafField.Value = d.currentTable } - d.currentTableKey = key + d.currentTableKey = actualKey case toml.ArrayTable: // Table array elements always begin a new line. @@ -392,13 +405,11 @@ func (d *Decoder) inlineFields(tkeys []tomlKey, relPos token.RelPos) (top, leaf } // quoteLabelIfNeeded quotes a label name only if it needs quoting. -// -// TODO(mvdan): this exists in multiple packages; move to cue/literal or cue/ast? func quoteLabelIfNeeded(name string) string { - if ast.IsValidIdent(name) { - return name + if ast.StringLabelNeedsQuoting(name) { + return literal.Label.Quote(name) } - return literal.Label.Quote(name) + return name } // label creates an ast.Label that represents a key with exactly the literal string name. @@ -407,17 +418,9 @@ func quoteLabelIfNeeded(name string) string { // cue/format knows how to quote any other identifiers correctly. func (d *Decoder) label(tkey tomlKey, relPos token.RelPos) ast.Label { pos := d.tokenFile.Pos(tkey.shape.Start.Offset, relPos) - if strings.HasPrefix(tkey.name, "_") { - return &ast.BasicLit{ - ValuePos: pos, - Kind: token.STRING, - Value: literal.String.Quote(tkey.name), - } - } - return &ast.Ident{ - NamePos: pos, - Name: tkey.name, - } + label := ast.NewStringLabel(tkey.name) + ast.SetPos(label, pos) + return label } // decodeExpr decodes a single TOML value expression, found on the right side diff --git a/vendor/cuelang.org/go/encoding/xml/koala/decode.go b/vendor/cuelang.org/go/encoding/xml/koala/decode.go new file mode 100644 index 0000000000..f35f344956 --- /dev/null +++ b/vendor/cuelang.org/go/encoding/xml/koala/decode.go @@ -0,0 +1,327 @@ +// Copyright 2025 The CUE Authors +// +// 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. + +// Package koala converts XML to and from CUE, as described in the proposal for the [koala] encoding. +// This encoding is inspired by the [BadgerFish] convention for translating XML to JSON. +// It differs from this to better fit CUE syntax, (as "$" and "@" are special characters), +// and for improved readability, as described in the koala proposal. +// +// XML elements are modeled as CUE structs, their attributes are modeled as struct fields +// prefixed with "$", and their inner text content is modeled as a field named "$$". +// +// WARNING: THIS PACKAGE IS EXPERIMENTAL. +// ITS API MAY CHANGE AT ANY TIME. +// +// [koala]: https://cuelang.org/discussion/3776 +// [BadgerFish]: http://www.sklar.com/badgerfish/ +package koala + +import ( + "bytes" + "encoding/xml" + "fmt" + "io" + "strings" + "unicode" + + "cuelang.org/go/cue/ast" + "cuelang.org/go/cue/token" +) + +// Decoder implements the decoding state. +type Decoder struct { + reader io.Reader + fileName string + tokenFile *token.File + + decoderRan bool + + // current XML element being processed. + currXmlElement *xmlElement + + // The top-level CUE struct. + astRoot *ast.StructLit + // CUE model of ancestors of current XML element being processed. + ancestors []currFieldInfo + // CUE model of current XML element being processed. + currField currFieldInfo + // CUE model of current XML element's inner content ($$ attribute). + currInnerText *ast.Field +} + +// currFieldInfo encapsulates details of the CUE field for the current XML element being processed. +type currFieldInfo struct { + // CUE model of current XML element. + field *ast.Field + // Running map of the current field's children. + currFieldChildren map[string]*ast.Field +} + +// xmlElement models an XML Element hierarchy. +// It is used for tracking namespace prefixes. +type xmlElement struct { + xmlName xml.Name + attr []xml.Attr + parent *xmlElement + children []*xmlElement + textContentIsWhiteSpace bool +} + +// The prefix used to model the inner text content within an XML element. +const contentAttribute string = "$$" + +// The prefix used to model each attribute of an XML element. +const attributeSymbol string = "$" + +// NewDecoder creates a decoder from a stream of XML input. +func NewDecoder(fileName string, r io.Reader) *Decoder { + return &Decoder{reader: r, fileName: fileName} +} + +// Decode parses the input stream as XML and converts it to a CUE [ast.Expr]. +// The input stream is taken from the [Decoder] and consumed. +func (dec *Decoder) Decode() (ast.Expr, error) { + if dec.decoderRan { + return nil, io.EOF + } + dec.decoderRan = true + xmlText, err := io.ReadAll(dec.reader) + if err != nil { + return nil, err + } + reader := bytes.NewReader(xmlText) + xmlDec := xml.NewDecoder(reader) + + // Create a token file to track the position of the XML content in the CUE file. + dec.tokenFile = token.NewFile(dec.fileName, 0, len(xmlText)) + dec.tokenFile.SetLinesForContent(xmlText) + + for { + startOffset := xmlDec.InputOffset() + t, err := xmlDec.Token() + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + switch xmlToken := t.(type) { + case xml.StartElement: + err = dec.decodeStartElement(xmlToken, startOffset) + case xml.CharData: + err = dec.decoderInnerText(xmlToken, startOffset) + case xml.EndElement: + err = dec.decodeEndElement() + } + if err != nil { + return nil, err + } + // If the XML document has ended, break out of the loop. + if dec.astRoot != nil && dec.currXmlElement == nil { + break + } + } + return dec.astRoot, nil +} + +func (dec *Decoder) decoderInnerText(xmlToken xml.CharData, contentOffset int64) error { + // If this is text content within an XML element. + textContent := string(xml.CharData(xmlToken)) + if dec.currField.field == nil { + if isWhiteSpace(textContent) { + return nil + } + return fmt.Errorf("text content outside of an XML element is not supported") + } + pos := dec.tokenFile.Pos(int(contentOffset), token.NoRelPos) + txtLabel := ast.NewStringLabel(contentAttribute) + ast.SetPos(txtLabel, pos) + val := toBasicLit(textContent) + ast.SetPos(val, pos) + textContentNode := &ast.Field{ + Label: txtLabel, + Value: val, + TokenPos: pos, + } + dec.currInnerText = textContentNode + dec.currXmlElement.textContentIsWhiteSpace = isWhiteSpace(textContent) + return nil +} + +func (dec *Decoder) decodeEndElement() error { + // If there is text content within the element, add it to the element's value. + if dec.currXmlElement != nil && dec.currInnerText != nil { + // Only support text content within an element that has no sub-elements. + if len(dec.currXmlElement.children) == 0 { + dec.appendToCurrFieldStruct(dec.currInnerText) + dec.currInnerText = nil + } else if len(dec.currXmlElement.children) > 0 && !dec.currXmlElement.textContentIsWhiteSpace { + // If there is text content within an element that has sub-elements, return an error. + return mixedContentError() + } + } + // For the xmlElement hierarchy: step back up the XML hierarchy. + if dec.currXmlElement != nil { + dec.currXmlElement = dec.currXmlElement.parent + } + // For the CUE ast: end current element, and step back up the XML hierarchy. + if len(dec.ancestors) > 0 { + dec.currField = dec.ancestors[len(dec.ancestors)-1] + dec.ancestors = dec.ancestors[:len(dec.ancestors)-1] + } + return nil +} + +func (dec *Decoder) decodeStartElement(xmlToken xml.StartElement, startOffset int64) error { + // Covers the root node. + if dec.currField.field == nil { + dec.currXmlElement = &xmlElement{xmlName: xmlToken.Name, attr: xmlToken.Attr} + cueElement := dec.cueFieldFromXmlElement(xmlToken, dec.currXmlElement, startOffset) + dec.currField.assignNewCurrField(cueElement) + dec.astRoot = ast.NewStruct(dec.currField.field) + ast.SetPos(dec.astRoot, dec.tokenFile.Pos(0, token.NoRelPos)) + return nil + } + // If this is not the root node, check if there is text content within the element. + if dec.currInnerText != nil && !dec.currXmlElement.textContentIsWhiteSpace { + return mixedContentError() + } + // Clear any whitespace text content. + dec.currInnerText = nil + // For xmlElement hierarchy: step down the XML hierarchy. + parentXmlNode := dec.currXmlElement + dec.currXmlElement = &xmlElement{xmlName: xmlToken.Name, attr: xmlToken.Attr, parent: parentXmlNode} + parentXmlNode.children = append(parentXmlNode.children, dec.currXmlElement) + // For the CUE ast: step down the CUE hierarchy. + dec.ancestors = append(dec.ancestors, dec.currField) + newElement := dec.cueFieldFromXmlElement(xmlToken, dec.currXmlElement, startOffset) + // Check if this new XML element has a name that's been seen before at the current level. + prefixedXmlElementName := prefixedElementName(xmlToken, dec.currXmlElement) + sameNameElements := dec.currField.currFieldChildren[prefixedXmlElementName] + if sameNameElements != nil { + list, ok := sameNameElements.Value.(*ast.ListLit) + // If the field's value is not a ListLit, create a new ListLit and append the existing field. + if !ok { + list = &ast.ListLit{Elts: []ast.Expr{sameNameElements.Value}} + sameNameElements.Value = list + } + // Append the new element to the ListLit, which we now know exists. + list.Elts = append(list.Elts, newElement.Value) + dec.currField.assignNewCurrField(newElement) + return nil + } + dec.currField.currFieldChildren[prefixedXmlElementName] = newElement + dec.appendToCurrFieldStruct(newElement) + dec.currField.assignNewCurrField(newElement) + return nil +} + +func (dec *Decoder) appendToCurrFieldStruct(field *ast.Field) { + dec.currField.field.Value.(*ast.StructLit).Elts = append(dec.currField.field.Value.(*ast.StructLit).Elts, field) +} + +func mixedContentError() error { + return fmt.Errorf("text content within an XML element that has sub-elements is not supported") +} + +func isWhiteSpace(s string) bool { + for _, r := range s { + if !unicode.IsSpace(r) { + return false + } + } + return true +} + +// cueFieldFromXmlElement creates a new [ast.Field] to model the given xml element information +// in [xml.StartElement] and [xmlElement]. The startOffset represents the offset +// for the beginning of the start tag of the given XML element. +func (dec *Decoder) cueFieldFromXmlElement(elem xml.StartElement, xmlNode *xmlElement, startOffset int64) *ast.Field { + elementName := prefixedElementName(elem, xmlNode) + resLabel := ast.NewStringLabel(elementName) + pos := dec.tokenFile.Pos(int(startOffset), token.NoRelPos) + ast.SetPos(resLabel, pos) + resultValue := &ast.StructLit{} + result := &ast.Field{ + Label: resLabel, + Value: resultValue, + TokenPos: pos, + } + // Extract attributes as children. + for _, a := range elem.Attr { + attrName := prefixedAttrName(a, elem, xmlNode) + label := ast.NewStringLabel(attributeSymbol + attrName) + value := toBasicLit(a.Value) + ast.SetPos(label, pos) + ast.SetPos(value, pos) + attrExpr := &ast.Field{ + Label: label, + Value: value, + TokenPos: pos, + } + resultValue.Elts = append(resultValue.Elts, attrExpr) + } + return result +} + +// prefixedElementName returns the full name of an element, +// including its namespace prefix if it has one; but without namespace prefix if it is "xmlns". +func prefixedElementName(elem xml.StartElement, xmlNode *xmlElement) string { + elementName := elem.Name.Local + if elem.Name.Space != "" { + prefixNS := nsPrefix(elem.Name.Space, elem.Attr, xmlNode) + if prefixNS != "xmlns" { + elementName = prefixNS + ":" + elem.Name.Local + } + } + return elementName +} + +// prefixedAttrName returns the full name of an attribute, including its namespace prefix if it has one. +func prefixedAttrName(a xml.Attr, elem xml.StartElement, xmlNode *xmlElement) string { + attrName := a.Name.Local + if a.Name.Space != "" { + prefix := nsPrefix(a.Name.Space, elem.Attr, xmlNode) + attrName = prefix + ":" + a.Name.Local + } + return attrName +} + +func toBasicLit(s string) *ast.BasicLit { + s = strings.ReplaceAll(s, "\r", "") + return ast.NewString(s) +} + +// nsPrefix finds the prefix label for a given namespace by looking at the current node's +// attributes and then walking up the hierarchy of XML nodes. +func nsPrefix(nameSpace string, attributes []xml.Attr, xmlNode *xmlElement) string { + // When the prefix is xmlns, then the namespace is xmlns according to the golang XML parser. + if nameSpace == "xmlns" { + return "xmlns" + } + for _, attr := range attributes { + if attr.Value == nameSpace { + return attr.Name.Local + } + } + if xmlNode.parent != nil { + return nsPrefix(nameSpace, xmlNode.parent.attr, xmlNode.parent) + } + panic("could not find prefix for namespace " + nameSpace) +} + +func (cf *currFieldInfo) assignNewCurrField(field *ast.Field) { + cf.field = field + cf.currFieldChildren = make(map[string]*ast.Field) +} diff --git a/vendor/cuelang.org/go/encoding/yaml/yaml.go b/vendor/cuelang.org/go/encoding/yaml/yaml.go index a06da8384f..c0a5da3190 100644 --- a/vendor/cuelang.org/go/encoding/yaml/yaml.go +++ b/vendor/cuelang.org/go/encoding/yaml/yaml.go @@ -24,7 +24,7 @@ import ( "cuelang.org/go/cue/ast" cueyaml "cuelang.org/go/internal/encoding/yaml" "cuelang.org/go/internal/source" - pkgyaml "cuelang.org/go/pkg/encoding/yaml" + "cuelang.org/go/internal/value" ) // Extract parses the YAML specified by src to a CUE expression. If @@ -70,7 +70,9 @@ func Extract(filename string, src interface{}) (*ast.File, error) { // Encode returns the YAML encoding of v. func Encode(v cue.Value) ([]byte, error) { - n := v.Syntax(cue.Final()) + // Note that we use [cue.Concrete] in this package, which expands all references. + // If we want YAML to encode with anchors in the future, we can change this. + n := v.Syntax(cue.Concrete(true)) b, err := cueyaml.Encode(n) return b, err } @@ -84,7 +86,7 @@ func EncodeStream(iter cue.Iterator) ([]byte, error) { if i > 0 { buf.WriteString("---\n") } - n := iter.Value().Syntax(cue.Final()) + n := iter.Value().Syntax(cue.Concrete(true)) b, err := cueyaml.Encode(n) if err != nil { return nil, err @@ -94,10 +96,44 @@ func EncodeStream(iter cue.Iterator) ([]byte, error) { return buf.Bytes(), nil } +// NewDecoder configures a YAML decoder. The path is used to associate position +// information with each node. +// +// Use the Decoder's Extract method to extract YAML values one at a time. +// For YAML streams with multiple documents separated by `---`, each call to +// Extract will return the next document. +func NewDecoder(path string, src io.Reader) *Decoder { + b, err := source.ReadAll(path, src) + return &Decoder{ + path: path, + dec: cueyaml.NewDecoder(path, b), + readAllErr: err, + } +} + +// A Decoder converts YAML values to CUE. +type Decoder struct { + path string + dec cueyaml.Decoder + readAllErr error +} + +// Extract converts the current YAML value to a CUE ast. It returns io.EOF +// if the input has been exhausted. +// +// For YAML streams with multiple documents separated by `---`, each call to +// Extract will return the next document as a separate CUE expression. +func (d *Decoder) Extract() (ast.Expr, error) { + if d.readAllErr != nil { + return nil, d.readAllErr + } + return d.dec.Decode() +} + // Validate validates the YAML and confirms it matches the constraints // specified by v. For YAML streams, all values must match v. func Validate(b []byte, v cue.Value) error { - // TODO(mvdan): encoding/yaml should not import pkg/encoding/yaml. - _, err := pkgyaml.Validate(b, v) + ctx := value.OpContext(v) + _, err := cueyaml.Validate(ctx, b, v) return err } diff --git a/vendor/cuelang.org/go/internal/anyunique/unique.go b/vendor/cuelang.org/go/internal/anyunique/unique.go new file mode 100644 index 0000000000..13906a46bc --- /dev/null +++ b/vendor/cuelang.org/go/internal/anyunique/unique.go @@ -0,0 +1,122 @@ +// Package anyunique provides canonicalization of values under a +// caller-defined equivalence relation. +// +// A [Store] holds a set of unique values of a specific type T. Calling +// [Store.Make] with two values that are equivalent according to the provided +// [Hasher] returns [Handle] values that are identical. [Handle] is a lightweight +// wrapper around the canonical value; use [U.Get] to obtain the +// underlying T. +// +// The zero [Handle] represents the zero value of T. Make returns the zero +// [Handle] when called with the zero value of T: it will never try to hash +// the zero value. +// +// [Store.WriteHash] writes a short representation of a canonicalized +// value to a [maphash.Hash]. It is useful when hashing structures that +// themselves contain canonicalized values, avoiding re-hashing the full +// value graph. +// +// NOTE this package assumes that T values are treated as immutable. +// That is, after calling [Store.Make] a value must not change. +package anyunique + +import "hash/maphash" + +// A Hasher defines a hash function and an equivalence relation over +// values of type T. +// +// Hash must write a hash of its argument to the provided *maphash.Hash, +// and Equal must report whether two values are equivalent. Hash and +// Equal must be consistent: if Equal(x, y) is true then Hash must +// produce the same output for x and y. +// +// Note: this is an exact copy of the proposed new Hasher interface +// for the Go API. +// See https://go-review.googlesource.com/c/go/+/657296/11/src/hash/maphash/hasher.go +// +// TODO alias this to maphash.Hasher when the above CL lands. +type Hasher[T any] interface { + Hash(*maphash.Hash, T) + Equal(x, y T) bool +} + +// New returns a new store holding a set of unique values +// of type T, using h to determine whether values are the +// same. +// +// The equivalence relation and hash are supplied by the given [Hasher]. +func New[T comparable, H Hasher[T]](h H) *Store[T, H] { + s := &Store[T, H]{ + h: h, + seed: maphash.MakeSeed(), + hashes: make(map[T]uint64), + entries: make(map[uint64][]T), + } + return s +} + +// Store holds a set of unique values of type T. +type Store[T comparable, H Hasher[T]] struct { + h H + seed maphash.Seed + entries map[uint64][]T + hashes map[T]uint64 +} + +// Handle represents a unique value of type T. If two values of type Handle[T] +// originating from the same [Store] compare equal, they are guaranteed +// to be equal according to the equality criteria that the store was +// created with. +type Handle[T comparable] struct { + x T +} + +// Value returns the actual value held in u. +func (u Handle[T]) Value() T { + return u.x +} + +// WriteHash writes a short representation of x to h. +// This allows callers to avoid hashing an tree of values +// when hashing a value that itself contains other Handle[T] items. +func (s *Store[T, H]) WriteHash(h *maphash.Hash, x Handle[T]) { + z := isZero(x) + maphash.WriteComparable(h, z) + if !z { + // TODO we _could_ write two independent hashes here + // if we were concerned about collisions. + maphash.WriteComparable(h, s.hashes[x.Value()]) + } +} + +// Make returns a unique value u such that u.Get() is equal to x +// according to the equality criteria defined by the store. +// +// It is assumed that values will not change after passing to Make: the +// caller must take care to preserve immutability. +func (s *Store[T, H]) Make(x T) Handle[T] { + if isZero(x) { + return Handle[T]{} + } + + if _, ok := s.hashes[x]; ok { + return Handle[T]{x} + } + var hasher maphash.Hash + hasher.SetSeed(s.seed) + s.h.Hash(&hasher, x) + h := hasher.Sum64() + entries := s.entries[h] + for _, e := range entries { + if s.h.Equal(x, e) { + return Handle[T]{e} + } + } + s.entries[h] = append(entries, x) + s.hashes[x] = h + return Handle[T]{x} +} + +func isZero[T comparable](x T) bool { + return x == *new(T) +} diff --git a/vendor/cuelang.org/go/internal/astinternal/debug.go b/vendor/cuelang.org/go/internal/astinternal/debug.go index 24e4398237..dc92b3281a 100644 --- a/vendor/cuelang.org/go/internal/astinternal/debug.go +++ b/vendor/cuelang.org/go/internal/astinternal/debug.go @@ -23,7 +23,6 @@ import ( "cuelang.org/go/cue/ast" "cuelang.org/go/cue/token" - "cuelang.org/go/internal" ) // AppendDebug writes a multi-line Go-like representation of a syntax tree node, @@ -196,7 +195,7 @@ func (d *debugPrinter) sliceElems(v reflect.Value, elemType reflect.Type) (anyEl func (d *debugPrinter) structFields(v reflect.Value) (anyElems bool) { t := v.Type() - for i := 0; i < v.NumField(); i++ { + for i := range v.NumField() { f := t.Field(i) if !gotoken.IsExported(f.Name) { continue @@ -295,7 +294,7 @@ func (d *debugPrinter) addNodeRefs(v reflect.Value) { } case reflect.Struct: t := v.Type() - for i := 0; i < v.NumField(); i++ { + for i := range v.NumField() { f := t.Field(i) if !gotoken.IsExported(f.Name) { continue @@ -420,16 +419,25 @@ func DebugStr(x interface{}) (out string) { case *ast.Field: out := DebugStr(v.Label) - if t, ok := internal.ConstraintToken(v); ok { + if v.Alias != nil { + out += "~" + if v.Alias.Label != nil { + // Dual form + out += "(" + out += DebugStr(v.Alias.Label) + out += "," + out += DebugStr(v.Alias.Field) + out += ")" + } else { + // Simple form + out += DebugStr(v.Alias.Field) + } + } + if t := v.Constraint; t != token.ILLEGAL { out += t.String() } if v.Value != nil { - switch v.Token { - case token.ILLEGAL, token.COLON: - out += ": " - default: - out += fmt.Sprintf(" %s ", v.Token) - } + out += ": " out += DebugStr(v.Value) for _, a := range v.Attrs { out += " " @@ -473,6 +481,9 @@ func DebugStr(x interface{}) (out string) { out += DebugStr(v.Y) return out + case *ast.PostfixExpr: + return DebugStr(v.X) + v.Op.String() + case []*ast.CommentGroup: var a []string for _, c := range v { diff --git a/vendor/cuelang.org/go/internal/core/adt/adt.go b/vendor/cuelang.org/go/internal/core/adt/adt.go index a6722c1e23..dee94207c3 100644 --- a/vendor/cuelang.org/go/internal/core/adt/adt.go +++ b/vendor/cuelang.org/go/internal/core/adt/adt.go @@ -39,7 +39,11 @@ func Resolve(ctx *OpContext, c Conjunct) *Vertex { v = x case Resolver: - r, err := ctx.resolveState(c, x, attempt(finalized, allKnown)) + r, err := ctx.resolveState(c, x, Flags{ + status: finalized, + condition: allKnown, + mode: attemptOnly, + }) if err != nil { v = err break @@ -108,14 +112,14 @@ type Evaluator interface { // evaluate evaluates the underlying expression. If the expression // is incomplete, it may record the error in ctx and return nil. - evaluate(ctx *OpContext, state combinedFlags) Value + evaluate(ctx *OpContext, state Flags) Value } // A Resolver represents a reference somewhere else within a tree that resolves // a value. type Resolver interface { Node - resolve(ctx *OpContext, state combinedFlags) *Vertex + resolve(ctx *OpContext, state Flags) *Vertex } type YieldFunc func(env *Environment) @@ -228,6 +232,7 @@ func (*SliceExpr) expr() {} func (*Interpolation) expr() {} func (*UnaryExpr) expr() {} func (*BinaryExpr) expr() {} +func (*OpenExpr) expr() {} func (*CallExpr) expr() {} // Decl and Expr (so allow attaching original source in Conjunct) @@ -325,6 +330,8 @@ func (*UnaryExpr) declNode() {} func (*UnaryExpr) elemNode() {} func (*BinaryExpr) declNode() {} func (*BinaryExpr) elemNode() {} +func (*OpenExpr) declNode() {} +func (*OpenExpr) elemNode() {} func (*CallExpr) declNode() {} func (*CallExpr) elemNode() {} func (*Builtin) declNode() {} @@ -341,6 +348,7 @@ func (*Comprehension) elemNode() {} func (*Vertex) node() {} func (*Conjunction) node() {} +func (*OpenExpr) node() {} func (*ConjunctGroup) node() {} func (*Disjunction) node() {} func (*BoundValue) node() {} diff --git a/vendor/cuelang.org/go/internal/core/adt/arctype_string.go b/vendor/cuelang.org/go/internal/core/adt/arctype_string.go new file mode 100644 index 0000000000..50786dab80 --- /dev/null +++ b/vendor/cuelang.org/go/internal/core/adt/arctype_string.go @@ -0,0 +1,28 @@ +// Code generated by "stringer -type=ArcType -trimprefix=Arc"; DO NOT EDIT. + +package adt + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ArcMember-0] + _ = x[ArcRequired-1] + _ = x[ArcOptional-2] + _ = x[ArcPending-3] + _ = x[ArcNotPresent-4] +} + +const _ArcType_name = "MemberRequiredOptionalPendingNotPresent" + +var _ArcType_index = [...]uint8{0, 6, 14, 22, 29, 39} + +func (i ArcType) String() string { + idx := int(i) - 0 + if i < 0 || idx >= len(_ArcType_index)-1 { + return "ArcType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _ArcType_name[_ArcType_index[idx]:_ArcType_index[idx+1]] +} diff --git a/vendor/cuelang.org/go/internal/core/adt/binop.go b/vendor/cuelang.org/go/internal/core/adt/binop.go index 0c75c0f843..7ed760ce63 100644 --- a/vendor/cuelang.org/go/internal/core/adt/binop.go +++ b/vendor/cuelang.org/go/internal/core/adt/binop.go @@ -17,30 +17,50 @@ package adt import ( "bytes" "strings" + + "cuelang.org/go/cue/token" ) +var checkConcrete = &ValidateConfig{ + Concrete: true, + Final: true, +} + +// errOnDiffType is a special value that is used as a source to BinOp to +// indicate that the operation is not supported for the operands of different +// kinds. +var errOnDiffType = &UnaryExpr{} + // BinOp handles all operations except AndOp and OrOp. This includes processing // unary comparators such as '<4' and '=~"foo"'. // +// The node argument is the adt node corresponding to the binary expression. It +// is used to determine the source position of the operation, which in turn is +// used to determine the experiment context. +// // BinOp returns nil if not both left and right are concrete. -func BinOp(c *OpContext, op Op, left, right Value) Value { +func BinOp(c *OpContext, node Node, op Op, left, right Value) Value { + var p token.Pos + if node != nil { + if src := node.Source(); src != nil { + p = src.Pos() + } + } leftKind := left.Kind() rightKind := right.Kind() - const msg = "non-concrete value '%v' to operation '%s'" - if left.Concreteness() > Concrete { - return &Bottom{ - Code: IncompleteError, - Err: c.Newf(msg, left, op), - Node: c.vertex, - } + if err := validateValue(c, left, checkConcrete); err != nil { + const msg = "invalid left-hand value to '%s' (type %s): %v" + // TODO: Wrap bottom instead of using NewErrf? + b := c.NewErrf(msg, op, left.Kind(), err.Err) + b.Code = err.Code + return b } - if right.Concreteness() > Concrete { - return &Bottom{ - Code: IncompleteError, - Err: c.Newf(msg, right, op), - Node: c.vertex, - } + if err := validateValue(c, right, checkConcrete); err != nil { + const msg = "invalid right-hand value to '%s' (type %s): %v" + b := c.NewErrf(msg, op, left.Kind(), err.Err) + b.Code = err.Code + return b } if err := CombineErrors(c.src, left, right); err != nil { @@ -50,11 +70,18 @@ func BinOp(c *OpContext, op Op, left, right Value) Value { switch op { case EqualOp: switch { - case leftKind == NullKind && rightKind == NullKind: - return c.newBool(true) + case leftKind&NumberKind != 0 && rightKind&NumberKind != 0: + return cmpTonode(c, op, c.Num(left, op).X.Cmp(&c.Num(right, op).X)) - case leftKind == NullKind || rightKind == NullKind: - return c.newBool(false) + case leftKind != rightKind: + if p.Experiment().StructCmp || + // compatibility with !structCmp: + leftKind == NullKind || rightKind == NullKind { + return c.newBool(false) + } + + case leftKind == NullKind: + return c.newBool(true) case leftKind == BoolKind: return c.newBool(c.BoolValue(left) == c.BoolValue(right)) @@ -66,33 +93,29 @@ func BinOp(c *OpContext, op Op, left, right Value) Value { case leftKind == BytesKind: return cmpTonode(c, op, bytes.Compare(c.bytesValue(left, op), c.bytesValue(right, op))) - case leftKind&NumberKind != 0 && rightKind&NumberKind != 0: - // n := c.newNum() - return cmpTonode(c, op, c.Num(left, op).X.Cmp(&c.Num(right, op).X)) + case leftKind == ListKind: + return c.newBool(Equal(c, left, right, RegularOnly|IgnoreOptional)) - case leftKind == ListKind && rightKind == ListKind: - x := c.Elems(left) - y := c.Elems(right) - if len(x) != len(y) { - return c.newBool(false) - } - for i, e := range x { - a, _ := c.concrete(nil, e, op) - b, _ := c.concrete(nil, y[i], op) - if !test(c, EqualOp, a, b) { - return c.newBool(false) - } - } - return c.newBool(true) + case !p.Experiment().StructCmp: + case leftKind == StructKind: + return c.newBool(Equal(c, left, right, RegularOnly|IgnoreOptional)) } case NotEqualOp: switch { - case leftKind == NullKind && rightKind == NullKind: - return c.newBool(false) + case leftKind&NumberKind != 0 && rightKind&NumberKind != 0: + return cmpTonode(c, op, c.Num(left, op).X.Cmp(&c.Num(right, op).X)) - case leftKind == NullKind || rightKind == NullKind: - return c.newBool(true) + case leftKind != rightKind: + if p.Experiment().StructCmp || + // compatibility with !structCmp: + leftKind == NullKind || + rightKind == NullKind { + return c.newBool(true) + } + + case leftKind == NullKind: + return c.newBool(false) case leftKind == BoolKind: return c.newBool(c.boolValue(left, op) != c.boolValue(right, op)) @@ -104,24 +127,12 @@ func BinOp(c *OpContext, op Op, left, right Value) Value { case leftKind == BytesKind: return cmpTonode(c, op, bytes.Compare(c.bytesValue(left, op), c.bytesValue(right, op))) - case leftKind&NumberKind != 0 && rightKind&NumberKind != 0: - // n := c.newNum() - return cmpTonode(c, op, c.Num(left, op).X.Cmp(&c.Num(right, op).X)) + case leftKind == ListKind: + return c.newBool(!Equal(c, left, right, RegularOnly|IgnoreOptional)) - case leftKind == ListKind && rightKind == ListKind: - x := c.Elems(left) - y := c.Elems(right) - if len(x) != len(y) { - return c.newBool(true) - } - for i, e := range x { - a, _ := c.concrete(nil, e, op) - b, _ := c.concrete(nil, y[i], op) - if !test(c, EqualOp, a, b) { - return c.newBool(true) - } - } - return c.newBool(false) + case !p.Experiment().StructCmp: + case leftKind == StructKind: + return c.newBool(!Equal(c, left, right, RegularOnly|IgnoreOptional)) } case LessThanOp, LessEqualOp, GreaterEqualOp, GreaterThanOp: diff --git a/vendor/cuelang.org/go/internal/core/adt/call.go b/vendor/cuelang.org/go/internal/core/adt/call.go new file mode 100644 index 0000000000..670e931a36 --- /dev/null +++ b/vendor/cuelang.org/go/internal/core/adt/call.go @@ -0,0 +1,112 @@ +// Copyright 2025 CUE Authors +// +// 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 +// +// https://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. + +package adt + +import ( + "cuelang.org/go/cue/ast" + "cuelang.org/go/cue/token" +) + +// A CallContext holds all relevant information for a function call to +// be executed. +type CallContext struct { + ctx *OpContext + call *CallExpr + builtin *Builtin + args []Value + isValidator bool +} + +func (c *CallContext) OpContext() *OpContext { + return c.ctx +} + +func (c *CallContext) Pos() token.Pos { + var src ast.Node + switch { + case c.call != nil: + src = c.call.Source() + case c.builtin != nil: + src = c.builtin.Source() + } + if src != nil { + return src.Pos() + } + return token.NoPos +} + +func (c *CallContext) Value(i int) Value { + return c.args[i] +} + +// NumParams returns the total number of parameters to this function. +func (c *CallContext) NumParams() int { + return len(c.args) +} + +func (c *CallContext) AddPositions(err *ValueError) { + for _, v := range c.args { + err.AddPosition(v) + } +} + +// Args return the pre-evaluated arguments. This function is only used for +// transitioning and will be removed at some point. Use [CallContext.Value] +// instead. +func (c *CallContext) Args() []Value { + return c.args +} + +// Arg returns the nth argument expression. The value is evaluated and any +// cycle information is accumulated in the context. This allows cycles in +// arguments to be detected. +// +// This method of getting an argument should be used when the argument is used +// as a schema and may contain cycles. +func (c *CallContext) Arg(i int) Value { + // If the call context represents a validator call, the argument will be + // offset by 1. + if c.isValidator { + if i == 0 { + c.Errf("Expr may not be called for 0th argument of validator") + return nil + } + i-- + } + x := c.call.Args[i] + + // Evaluated while keeping any cycle information in the context. + return c.ctx.EvaluateKeepState(x) +} + +// Expr returns the nth argument expression without evaluating it. +func (c *CallContext) Expr(i int) Expr { + // If the call context represents a validator call, the argument will be + // offset by 1. + if c.isValidator { + if i == 0 { + c.Errf("Expr may not be called for 0th argument of validator") + return nil + } + i-- + } + x := c.call.Args[i] + + return x +} + +func (c *CallContext) Errf(format string, args ...interface{}) *Bottom { + return c.ctx.NewErrf(format, args...) +} diff --git a/vendor/cuelang.org/go/internal/core/adt/closed.go b/vendor/cuelang.org/go/internal/core/adt/closed.go index 6db1eebf18..45439fb481 100644 --- a/vendor/cuelang.org/go/internal/core/adt/closed.go +++ b/vendor/cuelang.org/go/internal/core/adt/closed.go @@ -14,6 +14,12 @@ package adt +import ( + "iter" + + "cuelang.org/go/internal/core/layer" +) + // This file implements the closedness algorithm. // Outline of algorithm @@ -70,45 +76,32 @@ package adt // TODO(errors): return a dedicated ConflictError that can track original // positions on demand. -// IsInOneOf reports whether any of the Structs associated with v is contained -// within any of the span types in the given mask. -func (v *Vertex) IsInOneOf(mask SpanType) bool { - for _, s := range v.Structs { - if s.CloseInfo.IsInOneOf(mask) { - return true - } - } - return false -} - // IsRecursivelyClosed returns true if this value is either a definition or unified // with a definition. func (v *Vertex) IsRecursivelyClosed() bool { - return v.ClosedRecursive || v.IsInOneOf(DefinitionSpan) + return v.ClosedRecursive } -type closeNodeType uint8 - -const ( - // a closeRef node is created when there is a non-definition reference. - closeRef closeNodeType = iota - - // closeDef indicates this node was introduced as a result of referencing - // a definition. - closeDef - - // closeEmbed indicates this node was added as a result of an embedding. - closeEmbed -) +// ShouldRecursivelyClose reports whether this vertex should be closed +// recursively using __reclose. This is to simulate compatibility mode +// with the semantics from before explicitOpen was introduced. +// +// This is the case if any of the embeddings marked with ... were recursively +// closed before opening them up with .... +func (v *Vertex) ShouldRecursivelyClose() bool { + if v.state == nil { + return false + } + return v.state.embedsRecursivelyClosed +} -// TODO: merge with closeInfo: this is a leftover of the refactoring. type CloseInfo struct { - *closeInfo // old implementation (TODO: remove) - cc *closeContext // new implementation (TODO: rename field to closeCtx) - - // IsClosed is true if this conjunct represents a single level of closing - // as indicated by the closed builtin. - IsClosed bool + // defID is a unique ID to track anything that gets inserted from this + // Conjunct. + opID uint64 // generation of this conjunct, used for sanity check. + defID defID + enclosingEmbed defID // Tracks an embedding within a struct. + outerID defID // Tracks the {} that should be closed after unifying. // FromEmbed indicates whether this conjunct was inserted because of an // embedding. This flag is sticky: it will be set for conjuncts created @@ -122,120 +115,41 @@ type CloseInfo struct { // NOTE: only used when using closeContext. FromDef bool - // GroupUnify indicates that this conjunct needs to spawn its own - // closeContext. This is necessary when programmatically combining - // top-level values, such as with Value.Unify. - GroupUnify bool + // Like FromDef, but used by APIs to force FromDef to be true. + TopDef bool - // FieldTypes indicates which kinds of fields (optional, dynamic, patterns, - // etc.) are contained in this conjunct. - FieldTypes OptionalType + // This conjunct was opened by the ... postfix operator. + Opened bool + + // Priority is used for default resolution. Higher values win. 0 means no + // priority is assigned. Default handling may be more restrictive than + // specified in the spec when a priority is assigned. + Priority layer.Priority CycleInfo } -func (c CloseInfo) Location() Node { - if c.closeInfo == nil { +func (c CloseInfo) Location(ctx *OpContext) Node { + if c.opID != ctx.opID || c.defID == 0 { return nil } - return c.closeInfo.location + return ctx.containments[c.defID].n } -func (c CloseInfo) span() SpanType { - if c.closeInfo == nil { - return 0 - } - return c.closeInfo.span -} - -func (c CloseInfo) RootSpanType() SpanType { - if c.closeInfo == nil { - return 0 - } - return c.root -} - -// IsInOneOf reports whether c is contained within any of the span types in the -// given mask. -func (c CloseInfo) IsInOneOf(t SpanType) bool { - return c.span()&t != 0 -} - -// TODO(perf): remove: error positions should always be computed on demand -// in dedicated error types. -func (c *CloseInfo) AddPositions(ctx *OpContext) { - for s := c.closeInfo; s != nil; s = s.parent { - if loc := s.location; loc != nil { - ctx.AddPosition(loc) +// AncestorPositions returns an iterator over each parent of c, +// starting with the most immediate parent. This is used +// to add positions to errors that are associated with a CloseInfo. +func (c *CloseInfo) AncestorPositions(ctx *OpContext) iter.Seq[Node] { + return func(yield func(Node) bool) { + if c.opID != ctx.opID { + return } - } -} - -// TODO(perf): use on StructInfo. Then if parent and expression are the same -// it is possible to use cached value. -func (c CloseInfo) SpawnEmbed(x Node) CloseInfo { - c.closeInfo = &closeInfo{ - parent: c.closeInfo, - location: x, - mode: closeEmbed, - root: EmbeddingSpan, - span: c.span() | EmbeddingSpan, - } - return c -} - -// SpawnGroup is used for structs that contain embeddings that may end up -// closing the struct. This is to force that `b` is not allowed in -// -// a: {#foo} & {b: int} -func (c CloseInfo) SpawnGroup(x Expr) CloseInfo { - c.closeInfo = &closeInfo{ - parent: c.closeInfo, - location: x, - span: c.span(), - } - return c -} - -// SpawnSpan is used to track that a value is introduced by a comprehension -// or constraint. Definition and embedding spans are introduced with SpawnRef -// and SpawnEmbed, respectively. -func (c CloseInfo) SpawnSpan(x Node, t SpanType) CloseInfo { - c.closeInfo = &closeInfo{ - parent: c.closeInfo, - location: x, - root: t, - span: c.span() | t, - } - return c -} - -func (c CloseInfo) SpawnRef(arc *Vertex, isDef bool, x Expr) CloseInfo { - span := c.span() - found := false - if !isDef { - xnode := Node(x) // Optimization so we're comparing identical interface types. - // TODO: make this work for non-definitions too. - for p := c.closeInfo; p != nil; p = p.parent { - if p.span == span && p.location == xnode { - found = true - break + for p := c.defID; p != 0; p = ctx.containments[p].id { + if !yield(ctx.containments[p].n) { + return } } } - if !found { - c.closeInfo = &closeInfo{ - parent: c.closeInfo, - location: x, - span: span, - } - } - if isDef { - c.mode = closeDef - c.closeInfo.root = DefinitionSpan - c.closeInfo.span |= DefinitionSpan - } - return c } // IsDef reports whether an expressions is a reference that references a @@ -262,75 +176,6 @@ func IsDef(x Expr) (isDef bool, depth int) { return isDef, depth } -// A SpanType is used to indicate whether a CUE value is within the scope of -// a certain CUE language construct, the span type. -type SpanType uint8 - -const ( - // EmbeddingSpan means that this value was embedded at some point and should - // not be included as a possible root node in the todo field of OpContext. - EmbeddingSpan SpanType = 1 << iota - ConstraintSpan - ComprehensionSpan - DefinitionSpan -) - -type closeInfo struct { - // location records the expression that led to this node's introduction. - location Node - - // The parent node in the tree. - parent *closeInfo - - // TODO(performance): if references are chained, we could have a separate - // parent pointer to skip the chain. - - // mode indicates whether this node was added as part of an embedding, - // definition or non-definition reference. - mode closeNodeType - - // noCheck means this struct is irrelevant for closedness checking. This can - // happen when: - // - it is a sibling of a new definition. - noCheck bool // don't process for inclusion info - - root SpanType - span SpanType - - // decl is the parent declaration which contains the conjuct which - // gave rise to this closeInfo. - decl Decl -} - -// closeStats holds the administrative fields for a closeInfo value. Each -// closeInfo is associated with a single closeStats value per unification -// operator. This association is done through an OpContext. This allows the -// same value to be used in multiple concurrent unification operations. -// NOTE: there are other parts of the algorithm that are not thread-safe yet. -type closeStats struct { - // the other fields of this closeStats value are only valid if generation - // is equal to the generation in OpContext. This allows for lazy - // initialization of closeStats. - generation int - - // These counts keep track of how many required child nodes need to be - // completed before this node is accepted. - requiredCount int - acceptedCount int - - // accepted is set if this node is accepted. - accepted bool - - required bool - - inTodoList bool // true if added to todo list. - next *closeStats -} - -func (c *closeInfo) isClosed() bool { - return c.mode == closeDef -} - // isClosed reports whether v is closed at this level (so not recursively). func isClosed(v *Vertex) bool { // We could have used IsRecursivelyClosed here, but (effectively) @@ -339,213 +184,11 @@ func isClosed(v *Vertex) bool { if v.ClosedRecursive || v.ClosedNonRecursive { return true } - // TODO(evalv3): this can be removed once we delete the evalv2 code. - for _, s := range v.Structs { - if s.IsClosed || s.IsInOneOf(DefinitionSpan) { - return true - } - } return false } // Accept determines whether f is allowed in n. It uses the OpContext for // caching administrative fields. func Accept(ctx *OpContext, n *Vertex, f Feature) (found, required bool) { - if ctx.isDevVersion() { - return n.accept(ctx, f), true - } - ctx.generation++ - ctx.todo = nil - - var optionalTypes OptionalType - - // TODO(perf): more aggressively determine whether a struct is open or - // closed: open structs do not have to be checked, yet they can particularly - // be the ones with performance issues, for instanced as a result of - // embedded for comprehensions. - for _, s := range n.Structs { - if !s.useForAccept() { - continue - } - markCounts(ctx, s.CloseInfo) - optionalTypes |= s.types - } - - var str Value - if f.Index() == MaxIndex { - f &= fTypeMask - } else if optionalTypes&(HasComplexPattern|HasDynamic) != 0 && f.IsString() { - str = f.ToValue(ctx) - } - - for _, s := range n.Structs { - if !s.useForAccept() { - continue - } - if verifyArc(ctx, s, f, str) { - // Beware: don't add to below expression: this relies on the - // side effects of markUp. - ok := markUp(ctx, s.closeInfo, 0) - found = found || ok - } - } - - // Reject if any of the roots is not accepted. - for x := ctx.todo; x != nil; x = x.next { - if !x.accepted { - return false, true - } - } - - return found, ctx.todo != nil -} - -func markCounts(ctx *OpContext, info CloseInfo) { - if info.IsClosed { - markRequired(ctx, info.closeInfo) - return - } - for s := info.closeInfo; s != nil; s = s.parent { - if s.isClosed() { - markRequired(ctx, s) - return - } - } -} - -func markRequired(ctx *OpContext, info *closeInfo) { - count := 0 - for ; ; info = info.parent { - var s closeInfo - if info != nil { - s = *info - } - - x := getScratch(ctx, info) - - x.requiredCount += count - - if x.required { - return - } - - if s.span&EmbeddingSpan == 0 && !x.inTodoList { - x.next = ctx.todo - ctx.todo = x - x.inTodoList = true - } - - x.required = true - - if info == nil { - return - } - - count = 0 - if s.mode != closeEmbed { - count = 1 - } - } -} - -func markUp(ctx *OpContext, info *closeInfo, count int) bool { - for ; ; info = info.parent { - var s closeInfo - if info != nil { - s = *info - } - - x := getScratch(ctx, info) - - x.acceptedCount += count - - if x.acceptedCount < x.requiredCount { - return false - } - - x.accepted = true - - if info == nil { - return true - } - - count = 0 - if x.required && s.mode != closeEmbed { - count = 1 - } - } -} - -// getScratch: explain generation. -func getScratch(ctx *OpContext, s *closeInfo) *closeStats { - m := ctx.closed - if m == nil { - m = map[*closeInfo]*closeStats{} - ctx.closed = m - } - - x := m[s] - if x == nil { - x = &closeStats{} - m[s] = x - } - - if x.generation != ctx.generation { - *x = closeStats{generation: ctx.generation} - } - - return x -} - -func verifyArc(ctx *OpContext, s *StructInfo, f Feature, label Value) bool { - isRegular := f.IsString() - - o := s.StructLit - env := s.Env - - if len(o.Additional) > 0 || o.IsOpen { - return true - } - - for _, g := range o.Fields { - if f == g.Label { - return true - } - } - - if !isRegular { - return false - } - - // Do not record errors during this validation. - errs := ctx.errs - defer func() { ctx.errs = errs }() - - if len(o.Dynamic) > 0 && f.IsString() && label != nil { - for _, b := range o.Dynamic { - v := env.evalCached(ctx, b.Key) - v, _ = ctx.getDefault(v) - s, ok := Unwrap(v).(*String) - if !ok { - continue - } - if label.(*String).Str == s.Str { - return true - } - } - } - - for _, b := range o.Bulk { - if matchBulk(ctx, env, b, f, label) { - return true - } - } - - // TODO(perf): delay adding this position: create a special error type that - // computes all necessary positions on demand. - if ctx != nil { - ctx.AddPosition(s.StructLit) - } - - return false + return n.accept(ctx, f), true } diff --git a/vendor/cuelang.org/go/internal/core/adt/closed2.go b/vendor/cuelang.org/go/internal/core/adt/closed2.go deleted file mode 100644 index ce25d47009..0000000000 --- a/vendor/cuelang.org/go/internal/core/adt/closed2.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2020 CUE Authors -// -// 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. - -package adt - -// CloseDef defines how individual fieldSets (corresponding to conjuncts) -// combine to determine whether a field is contained in a closed set. -// -// A CloseDef combines multiple conjuncts and embeddings. All CloseDefs are -// stored in slice. References to other CloseDefs are indices within this slice. -// Together they define the top of the tree of the expression tree of how -// conjuncts combine together (a canopy). - -// isComplexStruct reports whether the Closed information should be copied as a -// subtree into the parent node using InsertSubtree. If not, the conjuncts can -// just be inserted at the current ID. -func isComplexStruct(ctx *OpContext, v *Vertex) bool { - return v.IsClosedStruct() -} - -// TODO: cleanup code and error messages. Reduce duplication in some related -// code. -func verifyArc2(ctx *OpContext, f Feature, v *Vertex, isClosed bool) (found bool, err *Bottom) { - unreachableForDev(ctx) - - // Don't check computed, temporary vertices. - if v.Label == InvalidLabel { - return true, nil - } - - // TODO(perf): collect positions in error. - defer ctx.ReleasePositions(ctx.MarkPositions()) - - // Note: it is okay to use parent here as this only needs to be computed - // for the original location. - if ok, required := Accept(ctx, v.Parent, f); ok || (!required && !isClosed) { - return true, nil - } - - if !f.IsString() { - // if f.IsHidden() { Also change Accept in composite.go - return false, nil - } - - if v != nil { - for _, c := range v.Conjuncts { - if pos := c.Field(); pos != nil { - ctx.AddPosition(pos) - } - } - } - - for _, s := range v.Parent.Structs { - s.AddPositions(ctx) - } - - return false, ctx.NewErrf("field not allowed") -} diff --git a/vendor/cuelang.org/go/internal/core/adt/composite.go b/vendor/cuelang.org/go/internal/core/adt/composite.go index 4e728285e8..ff485f39ee 100644 --- a/vendor/cuelang.org/go/internal/core/adt/composite.go +++ b/vendor/cuelang.org/go/internal/core/adt/composite.go @@ -16,11 +16,13 @@ package adt import ( "fmt" + "iter" "slices" "cuelang.org/go/cue/ast" "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" + "cuelang.org/go/internal/iterutil" ) // TODO: unanswered questions about structural cycles: @@ -110,34 +112,6 @@ func (e *Environment) up(ctx *OpContext, count int32) *Environment { return e } -type ID int32 - -// evalCached is used to look up dynamic field pattern constraint expressions. -func (e *Environment) evalCached(c *OpContext, x Expr) Value { - if v, ok := x.(Value); ok { - return v - } - key := cacheKey{x, nil} - v, ok := e.cache[key] - if !ok { - if e.cache == nil { - e.cache = map[cacheKey]Value{} - } - env, src := c.e, c.src - c.e, c.src = e, x.Source() - // Save and restore errors to ensure that only relevant errors are - // associated with the cash. - err := c.errs - v = c.evalState(x, require(partial, allKnown)) // TODO: should this be finalized? - c.e, c.src = env, src - c.errs = err - if b, ok := v.(*Bottom); !ok || !b.IsIncomplete() { - e.cache[key] = v - } - } - return v -} - // A Vertex is a node in the value tree. It may be a leaf or internal node. // It may have arcs to represent elements of a fully evaluated struct or list. // @@ -158,11 +132,8 @@ type Vertex struct { // eval: *, BaseValue: * -- finalized // state *nodeContext - - // _cc manages the closedness logic for this Vertex. It is created - // by rootCloseContext. - // TODO: move back to nodeContext, but be sure not to clone it. - _cc *closeContext + // TODO: move to nodeContext. + overlay *Vertex // Label is the feature leading to this vertex. Label Feature @@ -172,11 +143,6 @@ type Vertex struct { // status indicates the evaluation progress of this vertex. status vertexStatus - // hasAllConjuncts indicates that the set of conjuncts is complete. - // This is the case if the conjuncts of all its ancestors have been - // processed. - hasAllConjuncts bool - // isData indicates that this Vertex is to be interpreted as data: pattern // and additional constraints, as well as optional fields, should be // ignored. @@ -191,6 +157,10 @@ type Vertex struct { // level only. This supports the close builtin. ClosedNonRecursive bool + // Opened is set when a node that is opened with @experiment(explicitopen) + // is structure shared. This will override any of the above booleans. + OpenedShared bool + // HasEllipsis indicates that this Vertex is open by means of an ellipsis. // TODO: combine this field with Closed once we removed the old evaluator. HasEllipsis bool @@ -200,11 +170,6 @@ type Vertex struct { // the per-Environment value cache. MultiLet bool - // After this is set, no more arcs may be added during evaluation. This is - // set, for instance, after a Vertex is used as a source for comprehensions, - // or any other operation that relies on the set of arcs being constant. - LockArcs bool - // IsDynamic signifies whether this struct is computed as part of an // expression and not part of the static evaluation tree. // Used for cycle detection. @@ -221,16 +186,13 @@ type Vertex struct { // rooted. nonRooted bool // indicates that there is no path from the root of the tree. - // anonymous indicates that this Vertex is being computed within a + // anonymous indicates that this Vertex is being computed without an // addressable context, or in other words, a context for which there is - // a path from the root of the file. Typically, the only addressable + // np path from the root of the file. Typically, the only addressable // contexts are fields. Examples of fields that are not addressable are // the for source of comprehensions and let fields or let clauses. anonymous bool - // hasPendingArc is set if this Vertex has a void arc (e.g. for comprehensions) - hasPendingArc bool - // IsDisjunct indicates this Vertex is a disjunct resulting from a // disjunction evaluation. IsDisjunct bool @@ -240,18 +202,9 @@ type Vertex struct { // The debug printer, for instance, takes extra care not to print in a loop. IsShared bool - // IsCyclic is true if a node is cyclic, for instance if its value is - // a cyclic reference to a shared node or if the value is a conjunction - // of which at least one value is cyclic (not yet supported). - IsCyclic bool - // ArcType indicates the level of optionality of this arc. ArcType ArcType - // cyclicReferences is a linked list of internal references pointing to this - // Vertex. This is used to shorten the path of some structural cycles. - cyclicReferences *RefNode - // BaseValue is the value associated with this vertex. For lists and structs // this is a sentinel value indicating its kind. BaseValue BaseValue @@ -278,8 +231,8 @@ type Vertex struct { // the final value of this Vertex. // // TODO: all access to Conjuncts should go through functions like - // VisitLeafConjuncts and VisitAllConjuncts. We should probably make this - // an unexported field. + // [Vertex.LeafConjuncts] and [Vertex.AllConjuncts]. + // We should probably make this an unexported field. Conjuncts ConjunctGroup // Structs is a slice of struct literals that contributed to this value. @@ -303,43 +256,21 @@ func equalDeref(a, b *Vertex) bool { return deref(a) == deref(b) } -func (v *Vertex) cc() *closeContext { - return v._cc -} - -// rootCloseContext creates a closeContext for this Vertex or returns the -// existing one. -func (v *Vertex) rootCloseContext(ctx *OpContext) *closeContext { - if v._cc == nil { - v._cc = &closeContext{ - group: &v.Conjuncts, - parent: nil, - src: v, - parentConjuncts: v, - decl: v, - } - v._cc.incDependent(ctx, ROOT, nil) // matched in REF(decrement:nodeDone) - } - - if p := v.Parent; p != nil { - pcc := p.rootCloseContext(ctx) - v._cc.depth = pcc.depth + 1 - } - - return v._cc -} - // newInlineVertex creates a Vertex that is needed for computation, but for // which there is no CUE path defined from the root Vertex. func (ctx *OpContext) newInlineVertex(parent *Vertex, v BaseValue, a ...Conjunct) *Vertex { + // TODO: parent is an unused parameter here. Setting [Vertex.Parent] to it + // improves paths in a bunch of errors, fixing regressions compared to evalv2. + // However, it also breaks a few tests. Perhaps try with evalv4. n := &Vertex{ BaseValue: v, IsDynamic: true, ArcType: ArcMember, Conjuncts: a, } - if !ctx.isDevVersion() { - n.Parent = parent + if len(ctx.freeScope) > 0 { + state := ctx.freeScope[len(ctx.freeScope)-1] + state.toFree = append(state.toFree, n) } if ctx.inDetached > 0 { n.anonymous = true @@ -370,7 +301,7 @@ func (v *Vertex) updateArcType(t ArcType) { return } } - if v.Parent != nil && v.Parent.ArcType == ArcPending && v.Parent.state != nil && v.Parent.state.ctx.isDevVersion() { + if v.Parent != nil && v.Parent.ArcType == ArcPending && v.Parent.state != nil { // TODO: check that state is always non-nil. v.Parent.state.unshare() } @@ -396,6 +327,9 @@ func (v *Vertex) IsDefined(c *OpContext) bool { if v.isDefined() { return true } + if v.Parent != nil && v.Parent.status == finalized { + return false + } v.Finalize(c) return v.isDefined() } @@ -407,6 +341,11 @@ func (v *Vertex) Rooted() bool { return !v.nonRooted && !v.Label.IsLet() && !v.IsDynamic } +// Internal is like !Rooted, but also counts internal let nodes as internal. +func (v *Vertex) Internal() bool { + return v.nonRooted || v.anonymous || v.IsDynamic +} + // IsDetached reports whether this Vertex does not have a path from the root. func (v *Vertex) IsDetached() bool { // v might have resulted from an inline struct that was subsequently shared. @@ -432,6 +371,8 @@ func (v *Vertex) MayAttach() bool { return !v.Label.IsLet() && !v.anonymous } +//go:generate go tool stringer -type=ArcType -trimprefix=Arc + type ArcType uint8 const ( @@ -451,6 +392,9 @@ const ( // its conjuncts need to be processed to find out. This happens when an arc // is provisionally added as part of a comprehension, but when this // comprehension has not yet yielded any results. + // + // TODO: make this a separate state so that we can track which arcs still + // have unresolved comprehensions. ArcPending // ArcNotPresent indicates that this arc is not present and, unlike @@ -463,29 +407,6 @@ const ( // We could also define types for required fields and potentially lets. ) -func (a ArcType) String() string { - switch a { - case ArcMember: - return "Member" - case ArcOptional: - return "Optional" - case ArcRequired: - return "Required" - case ArcPending: - return "Pending" - case ArcNotPresent: - return "NotPresent" - } - return fmt.Sprintf("ArcType(%d)", a) -} - -// definitelyExists reports whether an arc is a constraint or member arc. -// TODO: we should check that users of this call ensure there are no -// ArcPendings. -func (v *Vertex) definitelyExists() bool { - return v.ArcType < ArcPending -} - // ConstraintFromToken converts a given AST constraint token to the // corresponding ArcType. func ConstraintFromToken(t token.Token) ArcType { @@ -545,27 +466,12 @@ type StructInfo struct { // or nil if this is a root structure. // Embed *StructInfo // Context *RefInfo // the location from which this struct originates. - Disable bool - - Embedding bool - - // Decl contains this Struct - Decl Decl -} - -// TODO(perf): this could be much more aggressive for eliminating structs that -// are immaterial for closing. -func (s *StructInfo) useForAccept() bool { - if c := s.closeInfo; c != nil { - return !c.noCheck - } - return true } // vertexStatus indicates the evaluation progress of a Vertex. type vertexStatus int8 -//go:generate go run golang.org/x/tools/cmd/stringer -type=vertexStatus +//go:generate go tool stringer -type=vertexStatus const ( // unprocessed indicates a Vertex has not been processed before. @@ -587,11 +493,6 @@ const ( // but without recursively processing arcs. conjuncts - // evaluatingArcs indicates that the arcs of the Vertex are currently being - // evaluated. If this is encountered it indicates a structural cycle. - // Value does not have to be nil - evaluatingArcs - // finalized means that this node is fully evaluated and that the results // are save to use without further consideration. finalized @@ -602,7 +503,7 @@ const ( func (c *OpContext) Wrap(v *Vertex, id CloseInfo) *Vertex { w := c.newInlineVertex(nil, nil, v.Conjuncts...) n := w.getState(c) - n.share(makeAnonymousConjunct(nil, v, nil), v, CloseInfo{}) + n.share(makeAnonymousConjunct(nil, v, nil), v, id) return w } @@ -652,29 +553,32 @@ func (v *Vertex) updateStatus(s vertexStatus) { // received all their conjuncts as well, after which this node will have been // notified of these conjuncts. func (v *Vertex) setParentDone() { - v.hasAllConjuncts = true // Could set "Conjuncts" flag of arc at this point. - if n := v.state; n != nil && len(n.conjuncts) == n.conjunctsPos { + if n := v.state; n != nil { for _, a := range v.Arcs { a.setParentDone() } } } -// VisitLeafConjuncts visits all conjuncts that are leafs of the ConjunctGroup tree. -func (v *Vertex) VisitLeafConjuncts(f func(Conjunct) bool) { - VisitConjuncts(v.Conjuncts, f) +// LeafConjuncts iterates over all conjuncts that are leaves of the [ConjunctGroup] tree. +func (v *Vertex) LeafConjuncts() iter.Seq[Conjunct] { + return func(yield func(Conjunct) bool) { + _ = iterConjuncts(v.Conjuncts, yield) + } } -func VisitConjuncts(a []Conjunct, f func(Conjunct) bool) bool { +func iterConjuncts(a []Conjunct, yield func(Conjunct) bool) bool { + // TODO: note that this is iterAllConjuncts but without yielding ConjunctGroups. + // Can we reuse the code in a simple enough way? for _, c := range a { switch x := c.x.(type) { case *ConjunctGroup: - if !VisitConjuncts(*x, f) { + if !iterConjuncts(*x, yield) { return false } default: - if !f(c) { + if !yield(c) { return false } } @@ -682,22 +586,39 @@ func VisitConjuncts(a []Conjunct, f func(Conjunct) bool) bool { return true } -// VisitAllConjuncts visits all conjuncts of v, including ConjunctGroups. +// ConjunctsSeq iterates over all conjuncts that are leafs in the list of trees given. +func ConjunctsSeq(a []Conjunct) iter.Seq[Conjunct] { + return func(yield func(Conjunct) bool) { + _ = iterConjuncts(a, yield) + } +} + +// AllConjuncts iterates through all conjuncts of v, including [ConjunctGroup]s. // Note that ConjunctGroups do not have an Environment associated with them. -func (v *Vertex) VisitAllConjuncts(f func(c Conjunct, isLeaf bool)) { - visitAllConjuncts(v.Conjuncts, f) +// The boolean reports whether the conjunct is a leaf. +func (v *Vertex) AllConjuncts() iter.Seq2[Conjunct, bool] { + return func(yield func(Conjunct, bool) bool) { + _ = iterAllConjuncts(v.Conjuncts, yield) + } } -func visitAllConjuncts(a []Conjunct, f func(c Conjunct, isLeaf bool)) { +func iterAllConjuncts(a []Conjunct, yield func(c Conjunct, isLeaf bool) bool) bool { for _, c := range a { switch x := c.x.(type) { case *ConjunctGroup: - f(c, false) - visitAllConjuncts(*x, f) + if !yield(c, false) { + return false + } + if !iterAllConjuncts(*x, yield) { + return false + } default: - f(c, true) + if !yield(c, true) { + return false + } } } + return true } // HasConjuncts reports whether v has any conjuncts. @@ -714,14 +635,11 @@ func (v *Vertex) SingleConjunct() (c Conjunct, count int) { if v == nil { return c, 0 } - v.VisitLeafConjuncts(func(x Conjunct) bool { - c = x + for c = range v.LeafConjuncts() { if count++; count > 1 { - return false + break } - return true - }) - + } return c, count } @@ -783,6 +701,7 @@ func (v *Vertex) IsData() bool { // of this vertex. Arcs are left untouched. // It is used by cue.Eval to convert nodes to data on per-node basis. func (v *Vertex) ToDataSingle() *Vertex { + v = v.DerefValue() w := *v w.isData = true w.state = nil @@ -793,7 +712,21 @@ func (v *Vertex) ToDataSingle() *Vertex { // ToDataAll returns a new v where v and all its descendents contain only // the regular fields. func (v *Vertex) ToDataAll(ctx *OpContext) *Vertex { - v.Finalize(ctx) + // Create a map to track processed vertices to avoid duplicate processing + processed := make(map[*Vertex]*Vertex) + + // TODO(evalv3): for EvalV3 we could call finalize only here. + + return v.toDataAllRec(ctx, processed) +} + +func (v *Vertex) toDataAllRec(ctx *OpContext, processed map[*Vertex]*Vertex) *Vertex { + // Check if this vertex has already been processed + if result, exists := processed[v]; exists { + return result + } + + v.Finalize(ctx) // Needed recursively for eval v2. arcs := make([]*Vertex, 0, len(v.Arcs)) for _, a := range v.Arcs { @@ -801,17 +734,16 @@ func (v *Vertex) ToDataAll(ctx *OpContext) *Vertex { continue } if a.Label.IsRegular() { - arcs = append(arcs, a.ToDataAll(ctx)) + arcs = append(arcs, a.toDataAllRec(ctx, processed)) } } w := *v w.state = nil w.status = finalized - w.BaseValue = toDataAll(ctx, w.BaseValue) + w.BaseValue = toDataAllBaseValue(ctx, w.BaseValue, processed) w.Arcs = arcs w.isData = true - w.Conjuncts = slices.Clone(v.Conjuncts) // Converting to dat drops constraints and non-regular fields. This means // that the domain on which they are defined is reduced, which will change @@ -820,26 +752,30 @@ func (v *Vertex) ToDataAll(ctx *OpContext) *Vertex { w.ClosedRecursive = false w.ClosedNonRecursive = false - // TODO(perf): this is not strictly necessary for evaluation, but it can - // hurt performance greatly. Drawback is that it may disable ordering. - for _, s := range w.Structs { - s.Disable = true - } + w.Conjuncts = slices.Clone(v.Conjuncts) + for i, c := range w.Conjuncts { if v, _ := c.x.(Value); v != nil { - w.Conjuncts[i].x = toDataAll(ctx, v).(Value) + w.Conjuncts[i].x = toDataAllBaseValue(ctx, v, processed).(Value) } + // Always reset all CloseInfo fields to zero. Normally only the top + // conjuncts matter and get inserted and conjuncts of recursive arcs + // never come in play. ToDataAll is an exception. + w.Conjuncts[i].CloseInfo = w.Conjuncts[i].CloseInfo.clearCloseCheck() } + + // Store the processed vertex before returning + processed[v] = &w return &w } -func toDataAll(ctx *OpContext, v BaseValue) BaseValue { +func toDataAllBaseValue(ctx *OpContext, v BaseValue, processed map[*Vertex]*Vertex) BaseValue { switch x := v.(type) { default: return x case *Vertex: - return x.ToDataAll(ctx) + return x.toDataAllRec(ctx, processed) case *Disjunction: d := *x @@ -849,7 +785,7 @@ func toDataAll(ctx *OpContext, v BaseValue) BaseValue { switch x.NumDefaults { case 0: case 1: - return toDataAll(ctx, values[0]) + return toDataAllBaseValue(ctx, values[0], processed) default: values = values[:x.NumDefaults] } @@ -857,7 +793,7 @@ func toDataAll(ctx *OpContext, v BaseValue) BaseValue { for i, v := range values { switch x := v.(type) { case *Vertex: - d.Values[i] = x.ToDataAll(ctx) + d.Values[i] = x.toDataAllRec(ctx, processed) default: d.Values[i] = x } @@ -869,7 +805,7 @@ func toDataAll(ctx *OpContext, v BaseValue) BaseValue { c.Values = make([]Value, len(x.Values)) for i, v := range x.Values { // This case is okay because the source is of type Value. - c.Values[i] = toDataAll(ctx, v).(Value) + c.Values[i] = toDataAllBaseValue(ctx, v, processed).(Value) } return &c } @@ -888,9 +824,6 @@ func isFinal(v Value, isClosed bool) bool { case *Vertex: closed := isClosed || x.ClosedNonRecursive || x.ClosedRecursive - // TODO(evalv3): this is for V2 compatibility. Remove once V2 is gone. - closed = closed || x.IsClosedList() || x.IsClosedStruct() - // This also dereferences the value. if v, ok := x.BaseValue.(Value); ok { return isFinal(v, closed) @@ -955,22 +888,124 @@ func (v *Vertex) Bottom() *Bottom { // func (v *Vertex) Evaluate() +// Unify unifies two values and returns the result. +// +// TODO: introduce: Open() wrapper that indicates closedness should be ignored. +// +// Change Value to Node to allow any kind of type to be passed. +func Unify(c *OpContext, a, b Value) *Vertex { + v := &Vertex{} + + // We set the parent of the context to be able to detect structural cycles + // early enough to error on schemas used for validation. + if n := c.vertex; n != nil { + v.Parent = n.Parent + v.Label = n.Label + } + + addConjuncts(c, v, a) + addConjuncts(c, v, b) + + s := v.getState(c) + // As this is a new node, we should drop all the requirements from + // parent nodes, as these will not be aligned with the reinsertion + // of the conjuncts. + s.dropParentRequirements = true + if p := c.vertex; p != nil && p.state != nil && s != nil { + s.hasNonCyclic = p.state.hasNonCyclic + } + + v.Finalize(c) + + if c.vertex != nil { + v.Label = c.vertex.Label + } + + return v +} + +func addConjuncts(ctx *OpContext, dst *Vertex, src Value) { + closeInfo := ctx.CloseInfo() + closeInfo.FromDef = false + c := MakeConjunct(nil, src, closeInfo) + + if v, ok := src.(*Vertex); ok { + // TODO(v1.0.0): we should determine whether to apply the new semantics + // for closedness. However, this is not applicable for a Vertex. + // Ultimately, this logic should be removed. + + // By default, all conjuncts in a node are considered to be not + // mutually closed. This means that if one of the arguments to Unify + // closes, but is acquired to embedding, the closeness information + // is disregarded. For instance, for Unify(a, b) where a and b are + // + // a: {#D, #D: d: f: int} + // b: {d: e: 1} + // + // we expect 'e' to be not allowed. + // + // In order to do so, we wrap the outer conjunct in a separate + // scope that will be closed in the presence of closed embeddings + // independently from the other conjuncts. + n := dst.getBareState(ctx) + c.CloseInfo = n.splitScope(nil, c.CloseInfo) + + // Even if a node is marked as ClosedRecursive, it may be that this + // is the first node that references a definition. + // We approximate this to see if the path leading up to this + // value is a defintion. This is not fully accurate. We could + // investigate the closedness information contained in the parent. + for p := v; p != nil; p = p.Parent { + if p.Label.IsDef() { + c.CloseInfo.TopDef = true + break + } + } + } + + dst.AddConjunct(c) +} + func (v *Vertex) Finalize(c *OpContext) { // Saving and restoring the error context prevents v from panicking in // case the caller did not handle existing errors in the context. err := c.errs c.errs = nil - c.unify(v, final(finalized, allKnown)) + c.unify(v, Flags{ + status: finalized, + condition: allKnown, + mode: finalize, + checkTypos: true, + }) + c.errs = err +} + +func (v *Vertex) Unify(c *OpContext, flags Flags) { + // Saving and restoring the error context prevents v from panicking in + // case the caller did not handle existing errors in the context. + err := c.errs + c.errs = nil + c.unify(v, flags) c.errs = err } // CompleteArcs ensures the set of arcs has been computed. func (v *Vertex) CompleteArcs(c *OpContext) { - c.unify(v, final(conjuncts, allKnown)) + c.unify(v, Flags{ + status: conjuncts, + condition: allKnown, + mode: finalize, + checkTypos: true, + }) } func (v *Vertex) CompleteArcsOnly(c *OpContext) { - c.unify(v, final(conjuncts, fieldSetKnown)) + c.unify(v, Flags{ + status: conjuncts, + condition: fieldSetKnown, + mode: finalize, + checkTypos: false, + }) } func (v *Vertex) AddErr(ctx *OpContext, b *Bottom) { @@ -1039,19 +1074,6 @@ func Unwrap(v Value) Value { return x.Value() } -// OptionalType is a bit field of the type of optional constraints in use by an -// Acceptor. -type OptionalType int8 - -const ( - HasField OptionalType = 1 << iota // X: T - HasDynamic // (X): T or "\(X)": T - HasPattern // [X]: T - HasComplexPattern // anything but a basic type - HasAdditional // ...T - IsOpen // Defined for all fields -) - func (v *Vertex) Kind() Kind { // This is possible when evaluating comprehensions. It is potentially // not known at this time what the type is. @@ -1067,14 +1089,6 @@ func (v *Vertex) Kind() Kind { } } -func (v *Vertex) OptionalTypes() OptionalType { - var mask OptionalType - for _, s := range v.Structs { - mask |= s.OptionalTypes() - } - return mask -} - // IsOptional reports whether a field is explicitly defined as optional, // as opposed to whether it is allowed by a pattern constraint. func (v *Vertex) IsOptional(label Feature) bool { @@ -1090,17 +1104,33 @@ func (v *Vertex) accepts(ok, required bool) bool { return ok || (!required && !v.ClosedRecursive) } +// IsOpenStruct reports whether any field that is not contained within v is allowed. +// +// TODO: merge this function with IsClosedStruct and possibly IsClosedList. +// right now this causes too many issues if we do so. +func (v *Vertex) IsOpenStruct() bool { + // TODO: move this check to IsClosedStruct. Right now this causes too many + // changes in the debug output, and it also appears to be not entirely + // correct. + if v.HasEllipsis { + return true + } + if v.ClosedNonRecursive { + return false + } + if v.IsClosedStruct() { + return false + } + return true +} + func (v *Vertex) IsClosedStruct() bool { - // TODO: uncomment this. This fixes a bunch of closedness bugs - // in the old and new evaluator. For compability sake, though, we - // keep it as is for now. - // if v.Closed { - // return true - // } + // TODO: add this check. Right now this causes issues. It will have + // to be carefully introduced. // if v.HasEllipsis { // return false // } - switch x := v.BaseValue.(type) { + switch v.BaseValue.(type) { default: return false @@ -1108,10 +1138,6 @@ func (v *Vertex) IsClosedStruct() bool { return v.ClosedRecursive && !v.HasEllipsis case *StructMarker: - if x.NeedClose { - return true - } - case *Disjunction: } return isClosed(v) @@ -1156,7 +1182,7 @@ func (v *Vertex) Accept(ctx *OpContext, f Feature) bool { switch v.BaseValue.(type) { case *ListMarker: // TODO(perf): use precomputed length. - if f.Index() < len(v.Elems()) { + if f.Index() < iterutil.Count(v.Elems()) { return true } return !v.IsClosedList() @@ -1174,15 +1200,7 @@ func (v *Vertex) Accept(ctx *OpContext, f Feature) bool { } } - // TODO: move this check to IsClosedStruct. Right now this causes too many - // changes in the debug output, and it also appears to be not entirely - // correct. - if v.HasEllipsis { - return true - - } - - if !v.IsClosedStruct() || v.Lookup(f) != nil { + if v.IsOpenStruct() || v.Lookup(f) != nil { return true } @@ -1201,13 +1219,6 @@ func (v *Vertex) MatchAndInsert(ctx *OpContext, arc *Vertex) { } // Go backwards to simulate old implementation. - for i := len(v.Structs) - 1; i >= 0; i-- { - s := v.Structs[i] - if s.Disable { - continue - } - s.MatchAndInsert(ctx, arc) - } // This is the equivalent for the new implementation. if pcs := v.PatternConstraints; pcs != nil { @@ -1220,14 +1231,19 @@ func (v *Vertex) MatchAndInsert(ctx *OpContext, arc *Vertex) { } c.Env = &env - root := arc.rootCloseContext(ctx) - root.insertConjunct(ctx, root, c, c.CloseInfo, ArcMember, true, false) + arc.insertConjunct(ctx, c, c.CloseInfo, ArcMember, true, false) } } } } -} + if len(arc.Conjuncts) == 0 && v.HasEllipsis { + // TODO: consider adding an Ellipsis fields to the Constraints struct + // to record the original position of the elllipsis. + c := MakeRootConjunct(nil, &Top{}) + arc.insertConjunct(ctx, c, c.CloseInfo, ArcOptional, false, false) + } +} func (v *Vertex) IsList() bool { _, ok := v.BaseValue.(*ListMarker) return ok @@ -1266,15 +1282,17 @@ func (v *Vertex) LookupRaw(f Feature) *Vertex { } // Elems returns the regular elements of a list. -func (v *Vertex) Elems() []*Vertex { - // TODO: add bookkeeping for where list arcs start and end. - a := make([]*Vertex, 0, len(v.Arcs)) - for _, x := range v.Arcs { - if x.Label.IsInt() { - a = append(a, x) +func (v *Vertex) Elems() iter.Seq[*Vertex] { + return func(yield func(*Vertex) bool) { + // TODO: add bookkeeping for where list arcs start and end. + for _, x := range v.Arcs { + if x.Label.IsInt() { + if !yield(x) { + break + } + } } } - return a } func (v *Vertex) Init(c *OpContext) { @@ -1290,33 +1308,7 @@ func (v *Vertex) GetArc(c *OpContext, f Feature, t ArcType) (arc *Vertex, isNew return arc, false } - if c.isDevVersion() { - return nil, false - } - - if v.LockArcs { - // TODO(errors): add positions. - if f.IsInt() { - c.addErrf(EvalError, token.NoPos, - "element at index %v not allowed by earlier comprehension or reference cycle", f) - } else { - c.addErrf(EvalError, token.NoPos, - "field %v not allowed by earlier comprehension or reference cycle", f) - } - } - // TODO: consider setting Dynamic here from parent. - arc = &Vertex{ - Parent: v, - Label: f, - ArcType: t, - nonRooted: v.IsDynamic || v.Label.IsLet() || v.nonRooted, - anonymous: v.anonymous || v.Label.IsLet(), - } - v.Arcs = append(v.Arcs, arc) - if t == ArcPending { - v.hasPendingArc = true - } - return arc, true + return nil, false } func (v *Vertex) Source() ast.Node { @@ -1370,86 +1362,27 @@ func (v *Vertex) hasConjunct(c Conjunct) (added bool) { default: v.ArcType = ArcMember } - return findConjunct(v.Conjuncts, c) >= 0 + p, _ := findConjunct(v.Conjuncts, c) + return p >= 0 } // findConjunct reports the position of c within cs or -1 if it is not found. // // NOTE: we are not comparing closeContexts. The intended use of this function // is only to add to list of conjuncts within a closeContext. -func findConjunct(cs []Conjunct, c Conjunct) int { +func findConjunct(cs []Conjunct, c Conjunct) (int, Conjunct) { for i, x := range cs { // TODO: disregard certain fields from comparison (e.g. Refs)? - if x.CloseInfo.closeInfo == c.CloseInfo.closeInfo && // V2 - x.x == c.x && + if x.x == c.x && x.Env.Up == c.Env.Up && x.Env.Vertex == c.Env.Vertex { - return i + return i, x } } - return -1 -} - -func (n *nodeContext) addConjunction(c Conjunct, index int) { - unreachableForDev(n.ctx) - - // NOTE: This does not split binary expressions for comprehensions. - // TODO: split for comprehensions and rewrap? - if x, ok := c.Elem().(*BinaryExpr); ok && x.Op == AndOp { - c.x = x.X - n.conjuncts = append(n.conjuncts, conjunct{C: c, index: index}) - c.x = x.Y - n.conjuncts = append(n.conjuncts, conjunct{C: c, index: index}) - } else { - n.conjuncts = append(n.conjuncts, conjunct{C: c, index: index}) - } + return -1, Conjunct{} } func (v *Vertex) addConjunctUnchecked(c Conjunct) { - index := len(v.Conjuncts) v.Conjuncts = append(v.Conjuncts, c) - if n := v.state; n != nil && !n.ctx.isDevVersion() { - // TODO(notify): consider this as a central place to send out - // notifications. At the moment this is not necessary, but it may - // be if we move the notification mechanism outside of the path of - // running tasks. - n.addConjunction(c, index) - - // TODO: can we remove notifyConjunct here? This method is only - // used if either Unprocessed is 0, in which case there will be no - // notification recipients, or for "pushed down" comprehensions, - // which should also have been added at an earlier point. - n.notifyConjunct(c) - } -} - -// addConjunctDynamic adds a conjunct to a vertex and immediately evaluates -// it, whilst doing the same for any vertices on the notify list, recursively. -func (n *nodeContext) addConjunctDynamic(c Conjunct) { - unreachableForDev(n.ctx) - - n.node.Conjuncts = append(n.node.Conjuncts, c) - n.addExprConjunct(c, partial) - n.notifyConjunct(c) - -} - -func (n *nodeContext) notifyConjunct(c Conjunct) { - unreachableForDev(n.ctx) - - for _, rec := range n.notify { - arc := rec.v - if !arc.hasConjunct(c) { - if arc.state == nil { - // TODO: continuing here is likely to result in a faulty - // (incomplete) configuration. But this may be okay. The - // CUE_DEBUG=0 flag disables this assertion. - n.ctx.Assertf(n.ctx.pos(), !n.ctx.Strict, "unexpected nil state") - n.ctx.addErrf(0, n.ctx.pos(), "cannot add to field %v", arc.Label) - continue - } - arc.state.addConjunctDynamic(c) - } - } } func (v *Vertex) AddStruct(s *StructLit, env *Environment, ci CloseInfo) *StructInfo { @@ -1458,16 +1391,6 @@ func (v *Vertex) AddStruct(s *StructLit, env *Environment, ci CloseInfo) *Struct Env: env, CloseInfo: ci, } - if env.Vertex != nil { - // be careful to avoid promotion of nil env.Vertex to non-nil - // info.Decl - info.Decl = env.Vertex - } - if cc := ci.cc; cc != nil && cc.decl != nil { - info.Decl = cc.decl - } else if ci := ci.closeInfo; ci != nil && ci.decl != nil { - info.Decl = ci.decl - } for _, t := range v.Structs { if *t == info { // TODO: check for different identity. return t diff --git a/vendor/cuelang.org/go/internal/core/adt/comprehension.go b/vendor/cuelang.org/go/internal/core/adt/comprehension.go index d2a4ddc05c..2745c49fbf 100644 --- a/vendor/cuelang.org/go/internal/core/adt/comprehension.go +++ b/vendor/cuelang.org/go/internal/core/adt/comprehension.go @@ -77,8 +77,6 @@ type envComprehension struct { // runtime-related fields - err *Bottom - // envs holds all the environments that define a single "yield" result in // combination with the comprehension struct. envs []*Environment // nil: unprocessed, non-nil: done. @@ -98,8 +96,6 @@ type envYield struct { // Values specific to the field corresponding to this envYield - // This envYield was added to selfComprehensions - self bool // This envYield was successfully executed and the resulting conjuncts were // added. inserted bool @@ -143,29 +139,20 @@ func (n *nodeContext) insertComprehension( ec = &envComprehension{ comp: c, vertex: n.node, - - err: nil, // shut up linter - envs: nil, // shut up linter - done: false, // shut up linter } } - if ec.done && len(ec.envs) == 0 { - n.decComprehension(c) - return - } - x := c.Value - if !n.ctx.isDevVersion() { - ci = ci.SpawnEmbed(c) - ci.closeInfo.span |= ComprehensionSpan - ci.decl = c - } + ci.setOptionalV3(nil) + node := n.node.DerefDisjunct() var decls []Decl switch v := ToExpr(x).(type) { case *StructLit: + ci = n.splitStruct(v, ci) + + kind := TopKind numFixed := 0 var fields []Decl for _, d := range v.Decls { @@ -173,28 +160,27 @@ func (n *nodeContext) insertComprehension( case *Field: numFixed++ + if f.Label.IsInt() { + kind &= ListKind + } else if f.Label.IsString() { + kind &= StructKind + } + // Create partial comprehension c := &Comprehension{ Syntax: c.Syntax, Clauses: c.Clauses, Value: f, arcType: f.ArcType, // TODO: can be derived, remove this field. - cc: ci.cc, comp: ec, parent: c, - arc: n.node, + arc: node, } conjunct := MakeConjunct(env, c, ci) - if n.ctx.isDevVersion() { - n.assertInitialized() - _, c.arcCC = n.insertArcCC(f.Label, ArcPending, conjunct, conjunct.CloseInfo, false) - c.cc = ci.cc - ci.cc.incDependent(n.ctx, COMP, c.arcCC) - } else { - n.insertFieldUnchecked(f.Label, ArcPending, conjunct) - } + n.assertInitialized() + n.insertArc(f.Label, ArcPending, conjunct, conjunct.CloseInfo, false) fields = append(fields, f) @@ -211,17 +197,13 @@ func (n *nodeContext) insertComprehension( comp: ec, parent: c, - arc: n.node, + arc: node, } conjunct := MakeConjunct(env, c, ci) n.assertInitialized() arc := n.insertFieldUnchecked(f.Label, ArcMember, conjunct) - if n.ctx.isDevVersion() { - arc.MultiLet = true - } else { - arc.MultiLet = f.IsMulti - } + arc.MultiLet = true // NOTE: v2 was f.IsMulti fields = append(fields, f) @@ -240,47 +222,51 @@ func (n *nodeContext) insertComprehension( st := v if len(fields) < len(v.Decls) { st = &StructLit{ - Src: v.Src, - Decls: fields, + Src: v.Src, + Decls: fields, + isComprehension: true, } } - n.node.AddStruct(st, env, ci) + node.AddStruct(st, env, ci) switch { case !ec.done: ec.structs = append(ec.structs, st) case len(ec.envs) > 0: st.Init(n.ctx) + if kind == StructKind || kind == ListKind { + n.updateNodeType(kind, st, ci) + } } } + c.kind = kind + switch numFixed { case 0: // Add comprehension as is. case len(v.Decls): // No comprehension to add at this level. + // The should be considered a struct if it has only non-regular + // fields (like definitions), and no embeddings. + if kind == TopKind { + c.kind = StructKind + } return default: // Create a new StructLit with only the fields that need to be // added at this level. - x = &StructLit{Decls: decls} + x = &StructLit{ + Decls: decls, + isComprehension: true, + } } } - if n.ctx.isDevVersion() { - t := n.scheduleTask(handleComprehension, env, x, ci) - t.comp = ec - t.leaf = c - } else { - n.comprehensions = append(n.comprehensions, envYield{ - envComprehension: ec, - leaf: c, - env: env, - id: ci, - expr: x, - }) - } + t := n.scheduleTask(handleComprehension, env, x, ci) + t.comp = ec + t.leaf = c } type compState struct { @@ -297,14 +283,14 @@ func (c *OpContext) yield( node *Vertex, // errors are associated with this node env *Environment, // env for field for which this yield is called comp *Comprehension, - state combinedFlags, + state Flags, f YieldFunc, // called for every result ) *Bottom { s := &compState{ ctx: c, comp: comp, f: f, - state: state.vertexStatus(), + state: state.status, } y := comp.Clauses[0] @@ -340,96 +326,10 @@ func (s *compState) yield(env *Environment) (ok bool) { return !c.HasErr() } -// injectComprehension evaluates and inserts embeddings. It first evaluates all -// embeddings before inserting the results to ensure that the order of -// evaluation does not matter. -func (n *nodeContext) injectComprehensions(state vertexStatus) (progress bool) { - unreachableForDev(n.ctx) - - workRemaining := false - - // We use variables, instead of range, as the list may grow dynamically. - for i := 0; i < len(n.comprehensions); i++ { - d := &n.comprehensions[i] - if d.self || d.inserted { - continue - } - if err := n.processComprehension(d, state); err != nil { - // TODO: Detect that the nodes are actually equal - if err.ForCycle && err.Value == n.node { - n.selfComprehensions = append(n.selfComprehensions, *d) - progress = true - d.self = true - return - } - - d.err = err - workRemaining = true - - continue - - // TODO: add this when it can be done without breaking other - // things. - // - // // Add comprehension to ensure incomplete error is inserted. - // // This ensures that the error is reported in the Vertex - // // where the comprehension was defined, and not just in the - // // node below. This, in turn, is necessary to support - // // certain logic, like export, that expects to be able to - // // detect an "incomplete" error at the first level where it - // // is necessary. - // n := d.node.getNodeContext(ctx) - // n.addBottom(err) - - } - progress = true - } - - if !workRemaining { - n.comprehensions = n.comprehensions[:0] // Signal that all work is done. - } - - return progress -} - -// injectSelfComprehensions processes comprehensions that were earlier marked -// as iterating over the node in which they are defined. Such comprehensions -// are legal as long as they do not modify the arc set of the node. -func (n *nodeContext) injectSelfComprehensions(state vertexStatus) { - unreachableForDev(n.ctx) - - // We use variables, instead of range, as the list may grow dynamically. - for i := 0; i < len(n.selfComprehensions); i++ { - n.processComprehension(&n.selfComprehensions[i], state) - } - n.selfComprehensions = n.selfComprehensions[:0] // Signal that all work is done. -} - // processComprehension processes a single Comprehension conjunct. // It returns an incomplete error if there was one. Fatal errors are // processed as a "successfully" completed computation. func (n *nodeContext) processComprehension(d *envYield, state vertexStatus) *Bottom { - err := n.processComprehensionInner(d, state) - - // NOTE: we cannot move this to defer in processComprehensionInner, as we - // use panics to implement "yielding" (and possibly coroutines in the - // future). - n.decComprehension(d.leaf) - - return err -} - -func (n *nodeContext) decComprehension(p *Comprehension) { - for ; p != nil; p = p.parent { - cc := p.cc - if cc != nil { - cc.decDependent(n.ctx, COMP, p.arcCC) - } - p.cc = nil - } -} - -func (n *nodeContext) processComprehensionInner(d *envYield, state vertexStatus) *Bottom { ctx := n.ctx // Compute environments, if needed. @@ -439,7 +339,11 @@ func (n *nodeContext) processComprehensionInner(d *envYield, state vertexStatus) envs = append(envs, env) } - if err := ctx.yield(d.vertex, d.env, d.comp, oldOnly(state), f); err != nil { + if err := ctx.yield(d.vertex, d.env, d.comp, Flags{ + status: state, + condition: allKnown, + mode: ignore, + }, f); err != nil { if err.IsIncomplete() { return err } @@ -468,21 +372,13 @@ func (n *nodeContext) processComprehensionInner(d *envYield, state vertexStatus) d.inserted = true if len(d.envs) == 0 { - c := d.leaf.arcCC - // because the parent referrer will reach a zero count before this - // node will reach a zero count, we need to propagate the arcType. - c.updateArcType(ctx, ArcNotPresent) + n.node.updateArcType(ArcNotPresent) return nil } v := n.node for c := d.leaf; c.parent != nil; c = c.parent { - // because the parent referrer will reach a zero count before this - // node will reach a zero count, we need to propagate the arcType. - if p := c.arcCC; p != nil { - p.src.updateArcType(c.arcType) - p.updateArcType(ctx, c.arcType) - } + v = n.ctx.deref(v) v.updateArcType(c.arcType) if v.ArcType == ArcNotPresent { parent := v.Parent @@ -492,6 +388,12 @@ func (n *nodeContext) processComprehensionInner(d *envYield, state vertexStatus) ctx.current().state = taskFAILED return nil } + if k := c.kind; k == StructKind || k == ListKind { + v := v.DerefDisjunct() + if s := v.getBareState(n.ctx); s != nil { + s.updateNodeType(k, ToExpr(c.Value), d.id) + } + } v = c.arc } @@ -510,11 +412,7 @@ func (n *nodeContext) processComprehensionInner(d *envYield, state vertexStatus) env = linkChildren(env, d.leaf) - if ctx.isDevVersion() { - n.scheduleConjunct(Conjunct{env, d.expr, id}, id) - } else { - n.addExprConjunct(Conjunct{env, d.expr, id}, state) - } + n.scheduleConjunct(Conjunct{env, d.expr, id}, id) } return nil diff --git a/vendor/cuelang.org/go/internal/core/adt/conjunct.go b/vendor/cuelang.org/go/internal/core/adt/conjunct.go index 5150f2b8e3..aab04a24b4 100644 --- a/vendor/cuelang.org/go/internal/core/adt/conjunct.go +++ b/vendor/cuelang.org/go/internal/core/adt/conjunct.go @@ -16,8 +16,8 @@ package adt import ( "fmt" + "slices" - "cuelang.org/go/cue/ast" "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" ) @@ -39,111 +39,30 @@ import ( func (n *nodeContext) scheduleConjunct(c Conjunct, id CloseInfo) { n.assertInitialized() - // Explanation of switch statement: - // - // A Conjunct can be a leaf or, through a ConjunctGroup, a tree. The tree - // reflects the history of how the conjunct was inserted in terms of - // definitions and embeddings. This, in turn, is used to compute closedness. - // - // Once all conjuncts for a Vertex have been collected, this tree contains - // all the information needed to trace its histroy: if a Vertex is - // referenced in an expression, this tree can be used to insert the - // conjuncts keeping closedness in mind. - // - // In the collection phase, however, this is not sufficient. CUE computes - // conjuncts "out of band". This means that conjuncts accumulate in - // different parts of the tree in an indeterminate order. closeContext is - // used to account for this. - // - // Basically, if the closeContext associated with c belongs to n, we take - // it that the conjunct needs to be inserted at the point in the tree - // associated by this closeContext. If, on the other hand, the closeContext - // is not defined or does not belong to this node, we take this conjunct - // is inserted by means of a reference. In this case we assume that the - // computation of the tree has completed and the tree can be used to reflect - // the closedness structure. - // - // TODO: once the evaluator is done and all tests pass, consider having - // two different entry points to account for these cases. - switch cc := c.CloseInfo.cc; { - case cc == nil || cc.src != n.node: - // In this case, a Conjunct is inserted from another Arc. If the - // conjunct represents an embedding or definition, we need to create a - // new closeContext to represent this. - if id.cc == nil { - id.cc = n.node.rootCloseContext(n.ctx) - } - if id.cc == cc { - panic("inconsistent state: same closeContext") - } - var t closeNodeType - if c.CloseInfo.FromDef { - t |= closeDef - } - // NOTE: the check for OpenInline is not strictly necessary, but it - // clarifies that using id.FromEmbed is not used when OpenInline is not - // used. - if c.CloseInfo.FromEmbed || (n.ctx.OpenInline && id.FromEmbed) { - t |= closeEmbed - } - if t != 0 || c.CloseInfo.GroupUnify { - id, _ = id.spawnCloseContext(n.ctx, t) - } - if !id.cc.done { - id.cc.incDependent(n.ctx, DEFER, nil) - defer id.cc.decDependent(n.ctx, DEFER, nil) - } - - if id.cc.src != n.node { - // TODO(#3406): raise a panic again. - // out: d & { d } - // d: { - // kind: "foo" | "bar" - // { kind: "foo" } | { kind: "bar" } - // } - // panic("inconsistent state: nodes differ") - } - default: - - // In this case, the conjunct is inserted as the result of an expansion - // of a conjunct in place, not a reference. In this case, we must use - // the cached closeContext. - id.cc = cc - - // Note this subtlety: we MUST take the cycle info from c when this is - // an in place evaluated node, otherwise we must take that of id. - id.CycleInfo = c.CloseInfo.CycleInfo + if c.CloseInfo.FromDef { + n.node.ClosedRecursive = true } - if id.cc.needsCloseInSchedule != nil { - dep := id.cc.needsCloseInSchedule - id.cc.needsCloseInSchedule = nil - defer id.cc.decDependent(n.ctx, EVAL, dep) - } + // TODO: consider setting this as a safety measure. + // if c.CloseInfo.CycleType > id.CycleType { + // id.CycleType = c.CloseInfo.CycleType + // } + // if c.CloseInfo.IsCyclic { + // id.IsCyclic = true + // } + // default: + // Note this subtlety: we MUST take the cycle info from c when this is + // an in place evaluated node, otherwise we must take that of id. + + // TODO(evalv3): Why do we no longer need to do this? + // id.CycleInfo = c.CloseInfo.CycleInfo env := c.Env - if id.cc.isDef { - n.node.ClosedRecursive = true - } + n.markNonCyclic(id) switch x := c.Elem().(type) { case *ConjunctGroup: - for _, c := range *x { - // TODO(perf): can be one loop - - cc := c.CloseInfo.cc - if cc.src == n.node && cc.needsCloseInSchedule != nil { - // We need to handle this specifically within the ConjunctGroup - // loop, because multiple conjuncts may be using the same root - // closeContext. This can be merged once Vertex.Conjuncts is an - // interface, requiring any list to be a root conjunct. - - dep := cc.needsCloseInSchedule - cc.needsCloseInSchedule = nil - defer cc.decDependent(n.ctx, EVAL, dep) - } - } for _, c := range *x { n.scheduleConjunct(c, id) } @@ -159,10 +78,17 @@ func (n *nodeContext) scheduleConjunct(c Conjunct, id CloseInfo) { } case Value: - // TODO: perhaps some values could be shared. - n.unshare() n.insertValueConjunct(env, x, id) + case *OpenExpr: + // This is not strictly necessary, but it ensures the same code path + // is taken for references that now have been rewritten to have a ... + // suffix. + c.x = x.X + c.CloseInfo.Opened = true // NOTE: seems unnecessary, but just to be sure. + id.Opened = true + n.scheduleConjunct(c, id) + case *BinaryExpr: // NOTE: do not unshare: a conjunction could still allow structure // sharing, such as in the case of `ref & ref`. @@ -208,16 +134,15 @@ func (n *nodeContext) scheduleConjunct(c Conjunct, id CloseInfo) { cloneID: id, holeID: n.ctx.holeID, src: x, - expr: x, } for _, dv := range x.Values { d.disjuncts = append(d.disjuncts, disjunct{ - expr: dv.Val, - isDefault: dv.Default, - mode: mode(x.HasDefaults, dv.Default), + expr: dv.Val, + mode: mode(x.HasDefaults, dv.Default), }) } n.scheduleDisjunction(d) + n.updateConjunctInfo(TopKind, id, 0) case *Comprehension: // always a partial comprehension. @@ -228,6 +153,17 @@ func (n *nodeContext) scheduleConjunct(c Conjunct, id CloseInfo) { case Evaluator: n.unshare() + + // Expressions that contain a call may end up in an infinite recursion + // here if we do not ensure that there is non-cyclic data to propagate + // the evaluation. We therefore postpone expressions until we have + // evidence that such non-cyclic conjuncts exist. + if id.CycleType == IsCyclic && !n.hasNonCycle && !n.hasNonCyclic { + n.hasAncestorCycle = true + n.cyclicConjuncts = append(n.cyclicConjuncts, cyclicConjunct{c: c}) + return + } + // Interpolation, UnaryExpr, CallExpr n.scheduleTask(handleExpr, env, x, id) @@ -245,6 +181,7 @@ func (n *nodeContext) scheduleStruct(env *Environment, s *StructLit, ci CloseInfo) { n.updateCyclicStatusV3(ci) + n.updateConjunctInfo(StructKind, ci, cHasStruct) // NOTE: This is a crucial point in the code: // Unification dereferencing happens here. The child nodes are set to @@ -259,50 +196,29 @@ func (n *nodeContext) scheduleStruct(env *Environment, hasEmbed := false hasEllipsis := false + n.hasStruct = true + // TODO: do we still need this? // shouldClose := ci.cc.isDef || ci.cc.isClosedOnce s.Init(n.ctx) - // TODO: do we still need to AddStruct and do we still need to Disable? - parent := n.node.AddStruct(s, childEnv, ci) - parent.Disable = true // disable until processing is done. - ci.IsClosed = false + // TODO: do we still need to AddStruct? + n.node.AddStruct(s, childEnv, ci) - // TODO: precompile + // TODO(perf): precompile whether struct has embedding. loop1: for _, d := range s.Decls { switch d.(type) { - case *Ellipsis: - hasEllipsis = true + case *Comprehension, Expr: + hasEmbed = true break loop1 } } - // TODO(perf): precompile whether struct has embedding. -loop2: - for _, d := range s.Decls { - switch d.(type) { - case *Comprehension, Expr: - // No need to increment and decrement, as there will be at least - // one entry. - if _, ok := s.Src.(*ast.File); !ok && s.Src != nil { - // If this is not a file, the struct indicates the scope/ - // boundary at which closedness should apply. This is not true - // for files. - // We should also not spawn if this is a nested Comprehension, - // where the spawn is already done as it may lead to spurious - // field not allowed errors. We can detect this with a nil s.Src. - // TODO(evalv3): use a more principled detection mechanism. - // TODO: set this as a flag in StructLit so as to not have to - // do the somewhat dangerous cast here. - ci, _ = ci.spawnCloseContext(n.ctx, 0) - } - // Note: adding a count is not needed here, as there will be an - // embed spawn below. - hasEmbed = true - break loop2 - } + // When inserting a replace that is a definition, flip the ignore. + if hasEmbed && !s.isComprehension { // only if more than one decl. + ci = n.splitStruct(s, ci) } // First add fixed fields and schedule expressions. @@ -313,34 +229,30 @@ loop2: n.aStruct = s n.aStructID = ci } - ci := ci + ci := n.ctx.subField(ci) if x.ArcType == ArcOptional { ci.setOptionalV3(n) } fc := MakeConjunct(childEnv, x, ci) - // fc.CloseInfo.cc = nil // TODO: should we add this? n.insertArc(x.Label, x.ArcType, fc, ci, true) case *LetField: + ci := n.ctx.subField(ci) lc := MakeConjunct(childEnv, x, ci) n.insertArc(x.Label, ArcMember, lc, ci, true) case *Comprehension: - ci, cc := ci.spawnCloseContext(n.ctx, closeEmbed) - cc.decl = x - cc.incDependent(n.ctx, DEFER, nil) - defer cc.decDependent(n.ctx, DEFER, nil) + ci := n.injectEmbedNode(x, ci) n.insertComprehension(childEnv, x, ci) hasEmbed = true case *Ellipsis: // Can be added unconditionally to patterns. - ci.cc.isDef = false - ci.cc.isClosed = false - ci.cc.isDefOrig = false + hasEllipsis = true case *DynamicField: + ci := n.ctx.subField(ci) if x.ArcType == ArcMember { n.aStruct = s n.aStructID = ci @@ -348,42 +260,55 @@ loop2: n.scheduleTask(handleDynamic, childEnv, x, ci) case *BulkOptionalField: - ci := ci + ci := n.ctx.subField(ci) ci.setOptionalV3(n) // All do not depend on each other, so can be added at once. n.scheduleTask(handlePatternConstraint, childEnv, x, ci) case Expr: - // TODO: perhaps special case scalar Values to avoid creating embedding. - ci, cc := ci.spawnCloseContext(n.ctx, closeEmbed) - cc.decl = x - - // TODO: do we need to increment here? - cc.incDependent(n.ctx, DEFER, nil) // decrement deferred below - defer cc.decDependent(n.ctx, DEFER, nil) - + ci := n.injectEmbedNode(x, ci) ec := MakeConjunct(childEnv, x, ci) n.scheduleConjunct(ec, ci) hasEmbed = true } } if hasEllipsis { - ci.cc.isTotal = true + n.node.HasEllipsis = true + n.updateConjunctInfo(TopKind, ci, cHasEllipsis) } if !hasEmbed { n.aStruct = s n.aStructID = ci - ci.cc.hasNonTop = true } - - // TODO: probably no longer necessary. - parent.Disable = false } // scheduleVertexConjuncts injects the conjuncst of src n. If src was not fully // evaluated, it subscribes dst for future updates. func (n *nodeContext) scheduleVertexConjuncts(c Conjunct, arc *Vertex, closeInfo CloseInfo) { + // We should not "activate" an enclosing struct for typo checking if it is + // derived from an embedded, inlined value: + // + // #Schema: foo: { {embed: embedded: "foo"}.embed } + // #Schema: foo: { field: string } + // + // Even though the embedding is within a schema, it should not treat the + // struct as closed if it itself does not refer to a schema, as it may still + // be unified with another struct. + // + // We check this by checking if the result is not marked as Closed. + // Alternativley, we could always disable this for inlined structs. + // + // TODO(#A...): this code could go if we had explicitly opened values. + if !arc.ClosedRecursive && + !arc.ClosedNonRecursive && + closeInfo.enclosingEmbed != 0 { + closeInfo.FromDef = false + } + if arc.ClosedRecursive && c.CloseInfo.Opened { + n.embedsRecursivelyClosed = true + } + // disjunctions, we need to dereference he underlying node. if deref(n.node) == deref(arc) { if n.isShared { @@ -418,42 +343,51 @@ func (n *nodeContext) scheduleVertexConjuncts(c Conjunct, arc *Vertex, closeInfo ciKey := closeInfo ciKey.Refs = nil - ciKey.Inline = false - key := arcKey{arc, ciKey} - for _, k := range n.arcMap { - if key == k { - return - } - } - n.arcMap = append(n.arcMap, key) + // No need to key on CloseInfo with evalv3. + ciKey = CloseInfo{} - mode := closeRef - isDef, relDepth := IsDef(c.Expr()) - // Also check arc.Label: definitions themselves do not have the FromDef - // and corresponding closeContexts to reflect their closedness. This means - // that if we are structure sharing, we may end up with a Vertex that is - // a definition without the reference reflecting that. We need to handle - // this case here and create a closeContext accordingly. Note that if an + // Also check arc.Label: definitions themselves do not have the FromDef to + // reflect their closedness. This means that if we are structure sharing, we + // may end up with a Vertex that is a definition without the reference + // reflecting that. We need to handle this case here. Note that if an // intermediate node refers to a definition, things are evaluated at least - // once and the closeContext is in place. - // See eval/closedness.txtar/test patterns.*.indirect. - // TODO: investigate whether we should add the corresponding closeContexts - // within definitions as well to avoid having to deal with these special - // cases. - if isDef || arc.Label.IsDef() { - mode = closeDef + // once. + switch isDef, _ := IsDef(c.Expr()); { + case isDef || arc.Label.IsDef() || closeInfo.TopDef: + if c.CloseInfo.Opened { + n.embedsRecursivelyClosed = true + } + n.isDef = true + // n.node.ClosedRecursive = true // TODO: should we set this here? + closeInfo.FromDef = true + closeInfo.TopDef = false + + closeInfo = n.addResolver(c.x, arc, closeInfo, false) + default: + closeInfo = n.addResolver(c.x, arc, closeInfo, true) + } + if closeInfo.defID != 0 && closeInfo.opID == n.ctx.opID { + c.CloseInfo.opID = closeInfo.opID + c.CloseInfo.defID = closeInfo.defID + c.CloseInfo.outerID = closeInfo.outerID + c.CloseInfo.enclosingEmbed = closeInfo.enclosingEmbed } - depth := VertexDepth(arc) - relDepth - - // TODO: or should we always insert the wrapper (for errors)? - ci, dc := closeInfo.spawnCloseContext(n.ctx, mode) - closeInfo = ci - dc.incDependent(n.ctx, DEFER, nil) // decrement deferred below - defer dc.decDependent(n.ctx, DEFER, nil) + key := arcKey{arc, ciKey} + if slices.Contains(n.arcMap, key) { + return + } + n.arcMap = append(n.arcMap, key) - if !n.node.nonRooted || n.node.IsDynamic { - if state := arc.getBareState(n.ctx); state != nil { + if arc.Parent != nil && (!n.node.nonRooted || n.node.IsDynamic) { + // If the arc has a parent that for which the field conjuncts are not + // fully known yet, we may not have collected all conjuncts yet. In that + // case we need ot add n to the notification list of arc to ensure + // we will get the notifications in the future. + pState := arc.Parent.getState(n.ctx) + state := arc.getBareState(n.ctx) + if pState != nil && state != nil && + !pState.meets(allAncestorsProcessed|fieldConjunctsKnown) { state.addNotify2(n.node, closeInfo) } } @@ -461,7 +395,7 @@ func (n *nodeContext) scheduleVertexConjuncts(c Conjunct, arc *Vertex, closeInfo // Use explicit index in case Conjuncts grows during iteration. for i := 0; i < len(arc.Conjuncts); i++ { c := arc.Conjuncts[i] - n.insertAndSkipConjuncts(c, closeInfo, depth) + n.scheduleConjunct(c, closeInfo) } if state := arc.getBareState(n.ctx); state != nil { @@ -469,63 +403,7 @@ func (n *nodeContext) scheduleVertexConjuncts(c Conjunct, arc *Vertex, closeInfo } } -// insertAndSkipConjuncts cuts the conjunct tree at the given relative depth. -// The CUE spec defines references to be closed if they cross definition -// boundaries. The conjunct tree tracks the origin of conjuncts, for instance, -// whether they originate from a definition or embedding. This allows these -// properties to hold even if a conjunct was referred indirectly. -// -// However, references within a referred Vertex, even though their conjunct -// tree reflects the full history, should exclude any of the tops of this -// tree that were not "crossed". -// -// TODO(evalv3): Consider this example: -// -// #A: { -// b: {} -// c: b & { -// d: 1 -// } -// } -// x: #A -// x: b: g: 1 -// -// Here, x.b is set to contain g. This is disallowed by #A and this will fail. -// However, if we were to leave out x.b.g, x.b.c would still reference x.b -// through #A. Even though, x.b is closed and empty, this should not cause an -// error, as the reference should not apply to fields that were added within -// #A itself. Just because #A is reference should not alter its correctness. -// -// The algorithm to detect this keeps track of the relative depth of references. -// Whenever a reference is resolved, all conjuncts that correspond to a given -// depth less than the depth of the referred node are skipped. -// -// Note that the relative depth of references can be applied to any node, -// even if this reference was defined in another struct. -func (n *nodeContext) insertAndSkipConjuncts(c Conjunct, id CloseInfo, depth int) { - if c.CloseInfo.cc == nil { - n.scheduleConjunct(c, id) - return - } - - if c.CloseInfo.cc.depth <= depth { - if x, ok := c.Elem().(*ConjunctGroup); ok { - for _, c := range *x { - n.insertAndSkipConjuncts(c, id, depth) - } - return - } - } - - n.scheduleConjunct(c, id) -} - func (n *nodeContext) addNotify2(v *Vertex, c CloseInfo) { - // scheduleConjunct should ensure that the closeContext of of c is aligned - // with v. We rely on this to be the case here. We enforce this invariant - // here for clarity and to ensure correctness. - n.ctx.Assertf(token.NoPos, c.cc.src == v, "close context not aligned with vertex") - // No need to do the notification mechanism if we are already complete. switch { case n.node.isFinal(): @@ -535,62 +413,54 @@ func (n *nodeContext) addNotify2(v *Vertex, c CloseInfo) { return } - // Create a "root" closeContext to reflect the entry point of the - // reference into n.node relative to cc within v. After that, we can use - // assignConjunct to add new conjuncts. - - // TODO: dedup: only add if t does not already exist. First check if this - // is even possible by adding a panic. - root := n.node.rootCloseContext(n.ctx) - if root.isDecremented { - return - } - for _, r := range n.notify { - if r.cc == c.cc { + if r.v == v { + // TODO: might need to add replacement here. return } } - cc := c.cc + // TODO(mem): keeping track of notifications seems to be unnecessary. Still + // consider it when we are reclaiming Vertex as well. + // s := v.getBareState(n.ctx) s.notifyCount++ // TODO: it should not be necessary to register for notifications for // let expressions, so we could also filter for !n.node.Label.IsLet(). // However, somehow this appears to result in slightly better error // messages. - if root.addNotifyDependency(n.ctx, cc) { - // TODO: this is mostly identical to the slice in the root closeContext. - // Use only one once V2 is removed. - n.notify = append(n.notify, receiver{cc.src, cc}) - } + n.ctx.stats.Notifications++ + + n.notify = append(n.notify, receiver{v, c}) } // Literal conjuncts -// NoSharingSentinel is a sentinel value that is used to disable sharing of +// NoShareSentinel is a sentinel value that is used to disable sharing of // nodes. We make this an error to make it clear that we discard the value. var NoShareSentinel = &Bottom{ Err: errors.Newf(token.NoPos, "no sharing"), } func (n *nodeContext) insertValueConjunct(env *Environment, v Value, id CloseInfo) { - n.updateCyclicStatusV3(id) - ctx := n.ctx + n.updateConjunctInfo(TopKind, id, 0) + switch x := v.(type) { case *Vertex: if x.ClosedNonRecursive { n.node.ClosedNonRecursive = true - var cc *closeContext - id, cc = id.spawnCloseContext(n.ctx, 0) - cc.incDependent(n.ctx, DEFER, nil) - defer cc.decDependent(n.ctx, DEFER, nil) - cc.isClosedOnce = true - if v, ok := x.BaseValue.(*Vertex); ok { - n.insertValueConjunct(env, v, id) - return + // If this is a definition, it will be repeated in the evaluation. + if !x.IsFromDisjunction() { + id = n.addResolver(v, x, id, false) + } + } else if x.ClosedRecursive { + n.node.ClosedRecursive = true + + // If this is a definition, it will be repeated in the evaluation. + if !x.IsFromDisjunction() { + id = n.addResolver(v, x, id, false) } } if _, ok := x.BaseValue.(*StructMarker); ok { @@ -599,6 +469,8 @@ func (n *nodeContext) insertValueConjunct(env *Environment, v Value, id CloseInf } if !x.IsData() { + n.updateCyclicStatusV3(id) + c := MakeConjunct(env, x, id) n.scheduleVertexConjuncts(c, x, id) return @@ -626,6 +498,7 @@ func (n *nodeContext) insertValueConjunct(env *Environment, v Value, id CloseInf c := MakeConjunct(nil, a, id) n.insertArc(a.Label, a.ArcType, c, id, true) } + n.node.Structs = append(n.node.Structs, x.Structs...) case Value: n.insertValueConjunct(env, v, id) @@ -634,16 +507,15 @@ func (n *nodeContext) insertValueConjunct(env *Environment, v Value, id CloseInf return case *Bottom: + n.unshare() if x == NoShareSentinel { - n.unshare() return } - id.cc.hasNonTop = true n.addBottom(x) return case *Builtin: - id.cc.hasNonTop = true + n.unshare() if v := x.BareValidator(); v != nil { n.insertValueConjunct(env, v, id) return @@ -656,6 +528,9 @@ func (n *nodeContext) insertValueConjunct(env *Environment, v Value, id CloseInf switch x := v.(type) { case *Disjunction: + n.updateCyclicStatusV3(id) + n.unshare() + // TODO(perf): reuse envDisjunct values so that we can also reuse the // disjunct slice. id := id @@ -667,13 +542,11 @@ func (n *nodeContext) insertValueConjunct(env *Environment, v Value, id CloseInf cloneID: id, holeID: n.ctx.holeID, src: x, - value: x, } for i, dv := range x.Values { d.disjuncts = append(d.disjuncts, disjunct{ - expr: dv, - isDefault: i < x.NumDefaults, - mode: mode(x.HasDefaults, i < x.NumDefaults), + expr: dv, + mode: mode(x.HasDefaults, i < x.NumDefaults), }) } n.scheduleDisjunction(d) @@ -687,44 +560,47 @@ func (n *nodeContext) insertValueConjunct(env *Environment, v Value, id CloseInf } case *Top: + n.updateCyclicStatusV3(id) + n.hasTop = true - id.cc.hasTop = true + n.updateConjunctInfo(TopKind, id, cHasTop) case *BasicType: - id.cc.hasNonTop = true + n.unshare() + n.updateCyclicStatusV3(id) + if x.K != TopKind { + n.updateConjunctInfo(TopKind, id, cHasTop) + } case *BoundValue: - id.cc.hasNonTop = true + n.unshare() + n.updateCyclicStatusV3(id) + switch x.Op { - case LessThanOp, LessEqualOp: - if y := n.upperBound; y != nil { - v := SimplifyBounds(ctx, n.kind, x, y) - if err := valueError(v); err != nil { - err.AddPosition(v) - err.AddPosition(n.upperBound) - err.AddClosedPositions(id) - } - n.upperBound = nil - n.insertValueConjunct(env, v, id) - return + case LessThanOp, LessEqualOp, GreaterThanOp, GreaterEqualOp: + bound := &n.upperBound + if x.Op == GreaterThanOp || x.Op == GreaterEqualOp { + bound = &n.lowerBound } - n.upperBound = x - - case GreaterThanOp, GreaterEqualOp: - if y := n.lowerBound; y != nil { + if y := *bound; y != nil { v := SimplifyBounds(ctx, n.kind, x, y) if err := valueError(v); err != nil { err.AddPosition(v) - err.AddPosition(n.lowerBound) - err.AddClosedPositions(id) + err.AddPosition(*bound) + err.AddClosedPositions(n.ctx, id) } - n.lowerBound = nil + *bound = nil n.insertValueConjunct(env, v, id) return } - n.lowerBound = x + *bound = x - case EqualOp, NotEqualOp, MatchOp, NotMatchOp: + case EqualOp, NotEqualOp: + // We treat equality as an open validator. + n.updateConjunctInfo(TopKind, id, cHasOpenValidator|cHasTop) + fallthrough + + case MatchOp, NotMatchOp: // This check serves as simplifier, but also to remove duplicates. k := 0 match := false @@ -741,13 +617,17 @@ func (n *nodeContext) insertValueConjunct(env *Environment, v Value, id CloseInf k++ } n.checks = n.checks[:k] + // TODO(perf): do an early check to be able to prune further + // processing. if !match { n.checks = append(n.checks, MakeConjunct(env, x, id)) } + return } case Validator: + n.unshare() // This check serves as simplifier, but also to remove duplicates. cx := MakeConjunct(env, x, id) kind := x.Kind() @@ -757,12 +637,21 @@ func (n *nodeContext) insertValueConjunct(env *Environment, v Value, id CloseInf // only associated with a validator, we leave it to the validator to // decide what fields are allowed. if kind&(ListKind|StructKind) != 0 { - id.cc.hasTop = true + if b, ok := x.(*BuiltinValidator); ok && b.Builtin.NonConcrete { + n.updateConjunctInfo(TopKind, id, cHasOpenValidator|cHasTop) + } else { + n.updateConjunctInfo(TopKind, id, cHasTop) + } } for i, y := range n.checks { if b, ok := SimplifyValidator(ctx, cx, y); ok { - n.checks[i] = b + // It is possible that simplification process triggered further + // evaluation, finalizing this node and clearing the checks + // slice. In that case it is safe to ignore the result. + if len(n.checks) > 0 { + n.checks[i] = b + } return } } @@ -777,6 +666,8 @@ func (n *nodeContext) insertValueConjunct(env *Environment, v Value, id CloseInf k := x.Kind() if k == TopKind { n.hasTop = true + // TODO: should we set this here? Does not seem necessary. + // n.updateConjunctInfo(TopKind, id, cHasTop) } n.updateNodeType(k, x, id) @@ -784,14 +675,35 @@ func (n *nodeContext) insertValueConjunct(env *Environment, v Value, id CloseInf // handled above. case Value: // *NullLit, *BoolLit, *NumLit, *StringLit, *BytesLit, *Builtin + n.unshare() + if p, isData := pos(v).Priority(); isData { + id.Priority = p + } + + n.updateCyclicStatusV3(id) + if y := n.scalar; y != nil { - if b, ok := BinOp(ctx, EqualOp, x, y).(*Bool); !ok || !b.B { + p1 := n.scalarID.Priority + p2 := id.Priority + if p1 != 0 && p2 != 0 { + if p1 > p2 { + // all good + break + } else if p1 < p2 { + goto patchConjunct + } + } + if b, ok := BinOp(ctx, errOnDiffType, EqualOp, x, y).(*Bool); !ok || !b.B { n.reportConflict(x, y, x.Kind(), y.Kind(), n.scalarID, id) } break } + patchConjunct: n.scalar = x n.scalarID = id + // TODO: only set "scalarKnown" if there are no other high priority + // conjuncts. Alternatively, we should process high priority conjuncts + // in the scheduler first. n.signal(scalarKnown) default: @@ -803,7 +715,7 @@ func (n *nodeContext) insertValueConjunct(env *Environment, v Value, id CloseInf if err := valueError(u); err != nil { err.AddPosition(n.lowerBound) err.AddPosition(n.upperBound) - err.AddClosedPositions(id) + err.AddClosedPositions(n.ctx, id) } n.lowerBound = nil n.upperBound = nil diff --git a/vendor/cuelang.org/go/internal/core/adt/constraints.go b/vendor/cuelang.org/go/internal/core/adt/constraints.go index 07b3bc8eb2..cbf037bf19 100644 --- a/vendor/cuelang.org/go/internal/core/adt/constraints.go +++ b/vendor/cuelang.org/go/internal/core/adt/constraints.go @@ -71,10 +71,6 @@ func (n *nodeContext) insertListEllipsis(offset int, ellipsis Conjunct) { // closeContext will be collated properly in fields to which these constraints // are applied. func (n *nodeContext) insertConstraint(pattern Value, c Conjunct) bool { - if c.CloseInfo.cc == nil { - panic("constraint conjunct must have closeContext associated with it") - } - ctx := n.ctx v := n.node @@ -102,17 +98,19 @@ func (n *nodeContext) insertConstraint(pattern Value, c Conjunct) bool { Constraint: constraint, }) } else { - found := false - constraint.VisitLeafConjuncts(func(x Conjunct) bool { - if c.CloseInfo.cc == x.CloseInfo.cc && c.x == x.x { - found = true + for x := range constraint.LeafConjuncts() { + if x.x == c.x && x.Env.Up == c.Env.Up && x.Env.Vertex == c.Env.Vertex { + if c.CloseInfo.opID == n.ctx.opID { + // TODO: do we need this replacement? + src := x.CloseInfo.defID + dst := c.CloseInfo.defID + n.addReplacement(replaceID{from: dst, to: src}) + } else { + n.ctx.stats.MisalignedConstraint++ + } + // The constraint already existed and the conjunct was already added. return false } - return true - }) - // The constraint already existed and the conjunct was already added. - if found { - return false } } @@ -150,7 +148,7 @@ func matchPattern(ctx *OpContext, pattern Value, f Feature) bool { // for the majority of cases where pattern constraints are used. func matchPatternValue(ctx *OpContext, pattern Value, f Feature, label Value) (result bool) { if v, ok := pattern.(*Vertex); ok { - v.unify(ctx, scalarKnown, finalize) + v.unify(ctx, Flags{condition: scalarKnown, mode: finalize, checkTypos: false}) } pattern = Unwrap(pattern) label = Unwrap(label) @@ -173,10 +171,9 @@ func matchPatternValue(ctx *OpContext, pattern Value, f Feature, label Value) (r // TODO: hoist and reuse with the identical code in optional.go. if x == cycle { err := ctx.NewPosf(pos(pattern), "cyclic pattern constraint") - ctx.vertex.VisitLeafConjuncts(func(c Conjunct) bool { - addPositions(err, c) - return true - }) + for c := range ctx.vertex.LeafConjuncts() { + addPositions(ctx, err, c) + } ctx.AddBottom(&Bottom{ Err: err, Node: ctx.vertex, diff --git a/vendor/cuelang.org/go/internal/core/adt/context.go b/vendor/cuelang.org/go/internal/core/adt/context.go index 93b402063a..dc5fb08c58 100644 --- a/vendor/cuelang.org/go/internal/core/adt/context.go +++ b/vendor/cuelang.org/go/internal/core/adt/context.go @@ -16,8 +16,10 @@ package adt import ( "fmt" + "iter" "reflect" "regexp" + "sync/atomic" "github.com/cockroachdb/apd/v3" "golang.org/x/text/encoding/unicode" @@ -58,6 +60,8 @@ type Config struct { Format func(Runtime, Node) string } +var contextGeneration atomic.Uint64 + // New creates an operation context. func New(v *Vertex, cfg *Config) *OpContext { if cfg.Runtime == nil { @@ -65,6 +69,7 @@ func New(v *Vertex, cfg *Config) *OpContext { } ctx := &OpContext{ + opID: contextGeneration.Add(1), Runtime: cfg.Runtime, Format: cfg.Format, vertex: v, @@ -75,33 +80,64 @@ func New(v *Vertex, cfg *Config) *OpContext { if v != nil { ctx.e = &Environment{Up: nil, Vertex: v} } + if ctx.LogEval > 0 { + ctx.Logf(v, "New context at opID %d", ctx.opID) + } return ctx } -// See also: [unreachableForDev] func (c *OpContext) isDevVersion() bool { - if c.Version == internal.EvalVersionUnset { - panic("OpContext was not provided with an evaluator version") - } return c.Version == internal.DevVersion } -// An OpContext implements CUE's unification operation. It only -// operates on values that are created with the Runtime with which an OpContext -// is associated. An OpContext is not goroutine safe and only one goroutine may -// use an OpContext at a time. +// An OpContext holds context associated with an on-going CUE +// evaluation. It functions both as an optimized memory store, +// amortizing allocations during an evaluation, and as a record of the +// current state within an evaluation. +// +// It should only be used on values that are created with the Runtime +// with which an OpContext is created. +// +// An OpContext is not goroutine safe and only one goroutine may use an +// OpContext at a time. +// +// An OpContext is typically used for an entire operation involving CUE +// values that are derived from the same [cue.Context], such as any call +// to exported Go APIs like methods on [cue.Value]. +// +// An OpContext stores: +// - errors encountered during the evaluation +// - the current vertex and its parents +// - statistics on evaluation operations +// +// The recorded set of errors is added to by calls to [OpContext.AddErr], +// [OpContext.AddErr], [OpContext.AddErrf], and in general +// any other operation that encounters an error. +// +// The current vertex is modified by calling [OpContext.PushArc], which +// must be balanced by a corresponding call to [OpContext.PopArc]. +// +// The entire state, including recorded errors and the current vertex, can be +// reset by calling [OpContext.PushState], which must be balanced by a +// corresponding call to [OpContext.PopState], causing the original +// errors and vertex to be restored. type OpContext struct { Runtime Format func(Runtime, Node) string cuedebug.Config - Version internal.EvaluatorVersion // Copied from Runtime - TopoSort bool // Copied from Runtime + Version internal.EvaluatorVersion // Copied from Runtime + SimplifyValidators bool // Copied from Runtime taskContext nest int + // used in typocheck.go + nextDefID defID // next available defID + containments []containment // parent relations + redirectsBuf []replaceID // reusable buffer used in containsDefID + stats stats.Counts freeListNode *nodeContext @@ -120,7 +156,17 @@ type OpContext struct { // TODO: remove this again once we have a proper way of detecting references // across optional boundaries in hasAncestorV3. We can probably do this // with an optional depth counter. - toFinalize []*Vertex + // See the TODO in unify.go for toFinalize. + // toFinalize []*Vertex + + // freeScope tracks the nodeContexts that are currently responsible for + // allocating new inlined vertices. Only nodes within the current scope can + // refer to any values allocated within an inline node, which means it is + // safe to reuse the nodeContext when all values have been processed. + // + // TODO(mem): we can mark Vertex nodes as being used in sharing and then + // free them too if they are not used. + freeScope []*nodeContext // These fields are used associate scratch fields for computing closedness // of a Vertex. These fields could have been included in StructInfo (like @@ -130,41 +176,16 @@ type OpContext struct { // TODO(perf): have two generations: one for each pass of the closedness // algorithm, so that the results of the first pass can be reused for all // features of a node. - generation int - closed map[*closeInfo]*closeStats - todo *closeStats + opID uint64 // evalDepth indicates the current depth of evaluation. It is used to // detect structural cycles and their severity.s evalDepth int - // optionalMark indicates the evalDepth at which the last optional field, - // pattern constraint or other construct that may contain errors was - // encountered. A value of 0 indicates we are not within such field. - optionalMark int - // holdID is a unique identifier for the current "hole", a choice of // disjunct to be made when processing disjunctions. holeID int - // inDisjunct indicates that non-monotonic checks should be skipped. - // This is used if we want to do some extra work to eliminate disjunctions - // early. The result of unification should be thrown away if this check is - // used. - // - // TODO: replace this with a mechanism to determine the correct set (per - // conjunct) of StructInfos to include in closedness checking. - inDisjunct int - - // inConstaint overrides inDisjunct as field matching should always be - // enabled. - inConstraint int - - // inLiteralSelectee indicates that we are evaluating a literal struct - // as the receiver of a selector. This is used to turn off closedness - // checking in compatibility mode. - inLiteralSelectee int - // inDetached indicates that inline structs evaluated in the current context // should never be shared. This is the case, for instance, with the source // for the for clause in a comprehension. @@ -181,6 +202,8 @@ type OpContext struct { // TODO: strictly separate validators and functions. IsValidator bool + overlays []overlayFrame + // ==== Debugging ==== logID int // sequence number for log messages @@ -191,21 +214,15 @@ type OpContext struct { currentDisjunctionID int // sequence number for call to processDisjunctions disjunctStack []disjunctInfo // stack of disjunct IDs -} - -func (c *OpContext) CloseInfo() CloseInfo { return c.ci } -func (n *nodeContext) skipNonMonotonicChecks() bool { - if n.ctx.inConstraint > 0 { - return false - } - return n.ctx.inDisjunct > 0 + // altPath, if non-empty, provides an alternative path for errors. This is + // necessary to get the right path for incomplete errors in the presence of + // structure sharing. + altPath []*Vertex // stack of selectors } -// Impl is for internal use only. This will go. -func (c *OpContext) Impl() Runtime { - return c.Runtime -} +func (c *OpContext) CloseInfo() CloseInfo { return c.ci } +func (c *OpContext) UpdateCloseInfo(ci CloseInfo) { c.ci = ci } func (c *OpContext) Pos() token.Pos { if c.src == nil { @@ -247,7 +264,11 @@ func (c *OpContext) Env(upCount int32) *Environment { func (c *OpContext) relNode(upCount int32) *Vertex { e := c.e.up(c, upCount) - c.unify(e.Vertex, oldOnly(partial)) + c.unify(e.Vertex, Flags{ + status: partial, + condition: allKnown, + mode: ignore, + }) return e.Vertex } @@ -267,7 +288,7 @@ func (c *OpContext) concreteIsPossible(op Op, x Expr) bool { return true } -// Assert that the given expression can evaluate to a concrete value. +// AssertConcreteIsPossible reports whether the given expression can evaluate to a concrete value. func AssertConcreteIsPossible(op Op, x Expr) bool { switch v := x.(type) { case *Bottom: @@ -346,6 +367,12 @@ type frame struct { ci CloseInfo } +// PushState resets c as if it was a newly created context +// with the same configuration c was created with, +// returning a value which should be used to restore the current +// state by passing it to a matching call to [OpContext.PopState]. +// +// If src is nil, c will still refer to the same source node. func (c *OpContext) PushState(env *Environment, src ast.Node) (saved frame) { saved.env = c.e saved.err = c.errs @@ -379,6 +406,7 @@ func (c *OpContext) PushConjunct(x Conjunct) (saved frame) { return saved } +// PopState restores a state pushed by [OpContext.PushState]. func (c *OpContext) PopState(s frame) *Bottom { err := c.errs c.e = s.env @@ -395,21 +423,46 @@ func (c *OpContext) PushArc(v *Vertex) (saved *Vertex) { c.vertex, saved = v, c.vertex return saved } +func (c *OpContext) PushArcAndLabel(v *Vertex) (saved *Vertex) { + + c.vertex, saved = v, c.vertex + c.altPath = append(c.altPath, v) + return saved +} // PopArc signals completion of processing the current arc. func (c *OpContext) PopArc(saved *Vertex) { c.vertex = saved } +func (c *OpContext) PopArcAndLabel(saved *Vertex) { + c.vertex = saved + c.altPath = c.altPath[:len(c.altPath)-1] +} + // Resolve finds a node in the tree. // // Should only be used to insert Conjuncts. TODO: perhaps only return Conjuncts // and error. -func (c *OpContext) Resolve(x Conjunct, r Resolver) (*Vertex, *Bottom) { - return c.resolveState(x, r, final(finalized, allKnown)) +func (c *OpContext) Resolve(x Conjunct, r Resolver) (v *Vertex, b *Bottom) { + defer func() { + x := recover() + switch x.(type) { + case nil: + case *scheduler: + b = c.NewErrf("unresolved value %s", r) + default: + panic(x) + } + }() + return c.resolveState(x, r, Flags{ + status: finalized, + condition: allKnown, + mode: finalize, + }) } -func (c *OpContext) resolveState(x Conjunct, r Resolver, state combinedFlags) (*Vertex, *Bottom) { +func (c *OpContext) resolveState(x Conjunct, r Resolver, state Flags) (*Vertex, *Bottom) { s := c.PushConjunct(x) arc := r.resolve(c, state) @@ -434,16 +487,14 @@ func (c *OpContext) resolveState(x Conjunct, r Resolver, state combinedFlags) (* func (c *OpContext) Lookup(env *Environment, r Resolver) (*Vertex, *Bottom) { s := c.PushState(env, r.Source()) - arc := r.resolve(c, oldOnly(partial)) + arc := r.resolve(c, Flags{ + status: partial, + condition: allKnown, + mode: ignore, + }) err := c.PopState(s) - if arc != nil && !c.isDevVersion() { - // TODO(deref): lookup should probably not use DerefValue, but - // rather only dereference disjunctions. - arc = arc.DerefValue() - } - return arc, err } @@ -461,13 +512,16 @@ func (c *OpContext) Validate(check Conjunct, value Value) *Bottom { src := c.src ci := c.ci + env := c.e c.src = check.Source() c.ci = check.CloseInfo + c.e = check.Env err := check.x.(Validator).validate(c, value) c.src = src c.ci = ci + c.e = env return err } @@ -477,7 +531,11 @@ func (c *OpContext) Validate(check Conjunct, value Value) *Bottom { func (c *OpContext) concrete(env *Environment, x Expr, msg interface{}) (result Value, complete bool) { s := c.PushState(env, x.Source()) - state := require(partial, concreteKnown) + state := Flags{ + status: partial, + condition: concreteKnown, + mode: yield, + } w := c.evalState(x, state) _ = c.PopState(s) @@ -538,7 +596,11 @@ func (c *OpContext) getDefault(v Value) (result Value, ok bool) { func (c *OpContext) Evaluate(env *Environment, x Expr) (result Value, complete bool) { s := c.PushState(env, x.Source()) - val := c.evalState(x, final(partial, concreteKnown)) + val := c.evalState(x, Flags{ + status: partial, + condition: concreteKnown, + mode: finalize, + }) complete = true @@ -565,13 +627,17 @@ func (c *OpContext) Evaluate(env *Environment, x Expr) (result Value, complete b return val, true } -// EvaluateKeepState does an evaluate, but leaves any errors an cycle info +// EvaluateKeepState does an evaluate, but leaves any errors and cycle info // within the context. func (c *OpContext) EvaluateKeepState(x Expr) (result Value) { src := c.src c.src = x.Source() - result, ci := c.evalStateCI(x, final(partial, concreteKnown)) + result, ci := c.evalStateCI(x, Flags{ + status: partial, + condition: concreteKnown, + mode: finalize, + }) c.src = src c.ci = ci @@ -579,29 +645,11 @@ func (c *OpContext) EvaluateKeepState(x Expr) (result Value) { return result } -func (c *OpContext) evaluateRec(v Conjunct, state combinedFlags) Value { - x := v.Expr() - s := c.PushConjunct(v) - - val := c.evalState(x, state) - if val == nil { - // Be defensive: this never happens, but just in case. - Assertf(c, false, "nil return value: unspecified error") - val = &Bottom{ - Code: IncompleteError, - Err: c.Newf("UNANTICIPATED ERROR"), - Node: c.vertex, - } - } - _ = c.PopState(s) - - return val -} - // value evaluates expression v within the current environment. The result may // be nil if the result is incomplete. value leaves errors untouched to that // they can be collected by the caller. -func (c *OpContext) value(x Expr, state combinedFlags) (result Value) { +func (c *OpContext) value(x Expr, state Flags) (result Value) { + state.concrete = true v := c.evalState(x, state) v, _ = c.getDefault(v) @@ -609,12 +657,12 @@ func (c *OpContext) value(x Expr, state combinedFlags) (result Value) { return v } -func (c *OpContext) evalState(v Expr, state combinedFlags) (result Value) { +func (c *OpContext) evalState(v Expr, state Flags) (result Value) { result, _ = c.evalStateCI(v, state) return result } -func (c *OpContext) evalStateCI(v Expr, state combinedFlags) (result Value, ci CloseInfo) { +func (c *OpContext) evalStateCI(v Expr, state Flags) (result Value, ci CloseInfo) { savedSrc := c.src c.src = v.Source() err := c.errs @@ -631,10 +679,7 @@ func (c *OpContext) evalStateCI(v Expr, state combinedFlags) (result Value, ci C switch b.Code { case IncompleteError: case CycleError: - if state.vertexStatus() == partial || c.isDevVersion() { - break - } - fallthrough + break default: result = b } @@ -664,6 +709,11 @@ func (c *OpContext) evalStateCI(v Expr, state combinedFlags) (result Value, ci C case Value: return x, c.ci + case *OpenExpr: + v, ci := c.evalStateCI(x.X, state) + ci.Opened = true + return v, ci + case Evaluator: v := x.evaluate(c, state) return v, c.ci @@ -676,6 +726,14 @@ func (c *OpContext) evalStateCI(v Expr, state combinedFlags) (result Value, ci C if arc == nil { return nil, c.ci } + // TODO(3977): register internal nodes for later verifications. The + // following limits the possibility of some common and useful cycles. + // + // if arc.Internal() { + // mode := state.conditions() + // state = final(partial, mode|allTasksCompleted) + // } + orig := arc // TODO(deref): what is the right level of dereferencing here? // DerefValue seems to work too. arc = arc.DerefNonShared() @@ -685,52 +743,63 @@ func (c *OpContext) evalStateCI(v Expr, state combinedFlags) (result Value, ci C // TODO: is this indirect necessary? // arc = arc.Indirect() - n := arc.state - if c.isDevVersion() { - n = arc.getState(c) - if n != nil { - c.ci, _ = n.detectCycleV3(arc, nil, x, c.ci) - } - } else { - if n != nil { - c.ci, _ = n.markCycle(arc, nil, x, c.ci) - } + if n := arc.getState(c); n != nil { + c.ci, _ = n.detectCycleV3(arc, nil, x, c.ci) } - c.ci.Inline = true - - if c.isDevVersion() { - if s := arc.getState(c); s != nil { - needs := state.conditions() | arcTypeKnown - runMode := state.runMode() - - if runMode == finalize { - arc.unify(c, needs, attemptOnly) // to set scalar - arc.state.freeze(needs) - } else { - arc.unify(c, needs, runMode) // to set scalar + + if s := arc.getState(c); s != nil { + defer s.retainProcess().releaseProcess() + + origNeeds := state.condition + needs := origNeeds | arcTypeKnown + runMode := state.mode + + switch runMode { + case finalize: + arc.unify(c, Flags{condition: needs, mode: attemptOnly, checkTypos: true}) // to set scalar + s.freeze(needs) + case attemptOnly: + arc.unify(c, Flags{condition: needs, mode: attemptOnly, checkTypos: true}) // to set scalar + + case yield: + arc.unify(c, Flags{condition: needs, mode: runMode, checkTypos: true}) // to set scalar + + evaluating := arc.status == evaluating + if state.concrete && orig != arc && orig.state != nil && orig.state.meets(scalarKnown) && IsRecursivelyConcrete(arc) { + evaluating = false } - v := arc - if v.ArcType == ArcPending { - if v.status == evaluating { - for ; v.Parent != nil && v.ArcType == ArcPending; v = v.Parent { - } - err := c.Newf("cycle with field %v", x) - b := &Bottom{Code: CycleError, Err: err} - s.setBaseValue(b) - return b, c.ci - // TODO: use this instead, as is usual for incomplete errors, - // and also move this block one scope up to also apply to - // defined arcs. In both cases, though, doing so results in - // some errors to be misclassified as evaluation error. - // c.AddBottom(b) - // return nil + // We cannot resolve a value that represents an unresolved + // disjunction. + if evaluating && orig != arc && arc.IsDisjunct { + task := c.current() + if origNeeds == scalarKnown && !orig.state.meets(scalarKnown) { + orig.state.defaultAttemptInCycle = task.node.node + task.waitFor(&orig.state.scheduler, needs) + s.yield() + panic("unreachable") } - c.undefinedFieldError(v, IncompleteError) - return nil, c.ci + err := c.Newf("unresolved disjunction: %v", x) + b := &Bottom{Code: CycleError, Err: err} + return b, c.ci } + + hasCycleBreakingValue := s.hasFieldValue || + !isCyclePlaceholder(arc.BaseValue) + + if evaluating && !hasCycleBreakingValue { + err := c.Newf("cycle with field: %v", x) + b := &Bottom{Code: CycleError, Err: err} + c.AddBottom(b) + break + } + + v := c.evaluate(arc, x, state) + + return v, c.ci } } + arc = arc.DerefValue() v := c.evaluate(arc, x, state) return v, c.ci @@ -757,9 +826,9 @@ func (c *OpContext) wrapCycleError(src ast.Node, b *Bottom) *Bottom { // unifyNode returns a possibly partially evaluated node value. // // TODO: maybe return *Vertex, *Bottom -func (c *OpContext) unifyNode(v Expr, state combinedFlags) (result Value) { +func (c *OpContext) unifyNode(expr Expr, state Flags) (result Value) { savedSrc := c.src - c.src = v.Source() + c.src = expr.Source() err := c.errs c.errs = nil @@ -790,203 +859,65 @@ func (c *OpContext) unifyNode(v Expr, state combinedFlags) (result Value) { c.src = savedSrc }() - switch x := v.(type) { + var v *Vertex + + switch x := expr.(type) { case Value: return x case Evaluator: - v := x.evaluate(c, state) - return v + return x.evaluate(c, state) case Resolver: - v := x.resolve(c, state) - if c.HasErr() { - return nil - } - if v == nil { - return nil - } - v = v.DerefValue() - - // TODO: consider moving this after markCycle, depending on how we - // implement markCycle, or whether we need it at all. - // TODO: is this indirect necessary? - // v = v.Indirect() - - if c.isDevVersion() { - if n := v.getState(c); n != nil { - // A lookup counts as new structure. See the commend in Section - // "Lookups in inline cycles" in cycle.go. - n.hasNonCycle = true - - // Always yield to not get spurious errors. - n.process(arcTypeKnown, yield) - // It is possible that the node is only midway through - // evaluating a disjunction. In this case, we want to ensure - // that disjunctions are finalized, so that disjunction shows - // up in BaseValue. - if len(n.disjuncts) > 0 { - n.node.unify(c, arcTypeKnown, yield) - } - } - } else { - if v.isUndefined() || state.vertexStatus() > v.Status() { - c.unify(v, state) - } - } - - return v + v = x.resolve(c, state) default: // This can only happen, really, if v == nil, which is not allowed. - panic(fmt.Sprintf("unexpected Expr type %T", v)) + panic(fmt.Sprintf("unexpected Expr type %T", expr)) } -} -func (c *OpContext) lookup(x *Vertex, pos token.Pos, l Feature, flags combinedFlags) *Vertex { - if c.isDevVersion() { - return x.lookup(c, pos, l, flags) + if c.HasErr() { + return nil } - - state := flags.vertexStatus() - - if l == InvalidLabel || x == nil { - // TODO: is it possible to have an invalid label here? Maybe through the - // API? - return &Vertex{} + if v == nil { + return nil } + v = v.DerefValue() - // var kind Kind - // if x.BaseValue != nil { - // kind = x.BaseValue.Kind() - // } - - switch x.BaseValue.(type) { - case *StructMarker: - if l.Typ() == IntLabel { - c.addErrf(0, pos, "invalid struct selector %v (type int)", l) - return nil - } - - case *ListMarker: - switch { - case l.Typ() == IntLabel: - switch { - case l.Index() < 0: - c.addErrf(0, pos, "invalid list index %v (index must be non-negative)", l) - return nil - case l.Index() > len(x.Arcs): - c.addErrf(0, pos, "invalid list index %v (out of bounds)", l) - return nil - } + // TODO: consider moving this after markCycle, depending on how we + // implement markCycle, or whether we need it at all. + // TODO: is this indirect necessary? + // v = v.Indirect() - case l.IsDef(), l.IsHidden(), l.IsLet(): + if n := v.getState(c); n != nil { + defer n.retainProcess().releaseProcess() - default: - c.addErrf(0, pos, "invalid list index %v (type string)", l) - return nil + // A lookup counts as new structure. See the commend in Section + // "Lookups in inline cycles" in cycle.go. + if !c.ci.IsCyclic || v.Label.IsLet() { + // TODO: fix! Setting this when we are not structure sharing can + // cause some hangs. We are conservative and not set this in + // this case, with the potential that some configurations will + // break. It is probably related to let. + n.hasNonCycle = true } - case nil: - // c.addErrf(IncompleteError, pos, "incomplete value %s", x) - // return nil - - case *Bottom: - - default: - kind := x.BaseValue.Kind() - if kind&(ListKind|StructKind) != 0 { - // c.addErrf(IncompleteError, pos, - // "cannot look up %s in incomplete type %s (type %s)", - // l, x.Source(), kind) - // return nil - } else if !l.IsDef() && !l.IsHidden() && !l.IsLet() { - c.addErrf(0, pos, - "invalid selector %v for value of type %s", l, kind) - return nil + // Always yield to not get spurious errors. + n.process(arcTypeKnown, yield) + // It is possible that the node is only midway through + // evaluating a disjunction. In this case, we want to ensure + // that disjunctions are finalized, so that disjunction shows + // up in BaseValue. + if len(n.disjuncts) > 0 { + n.node.unify(c, Flags{condition: arcTypeKnown, mode: yield, checkTypos: false}) } } - a := x.Lookup(l) - - var hasCycle bool - - if a != nil { - // Ensure that a's status is at least of the required level. Otherwise, - // ensure that any remaining unprocessed conjuncts are processed by - // calling c.Unify(a, Partial). The ensures that need to rely on - // hasAllConjuncts, but that are finalized too early, get conjuncts - // processed beforehand. - if state > a.status { - c.unify(a, deprecated(c, state)) - } else if a.state != nil { - c.unify(a, deprecated(c, partial)) - } - - // TODO(refRequired): see comment in unify.go:Vertex.lookup near the - // namesake TODO. - if a.ArcType == ArcOptional { - code := IncompleteError - if hasCycle { - code = CycleError - } - label := l.SelectorString(c.Runtime) - c.AddBottom(&Bottom{ - Code: code, - Permanent: x.status >= conjuncts, - Err: c.NewPosf(pos, - "cannot reference optional field: %s", label), - Node: x, - }) - } - } else { - if x.state != nil { - x.state.assertInitialized() + return v +} - for _, e := range x.state.exprs { - if isCyclePlaceholder(e.err) { - hasCycle = true - } - } - } - code := IncompleteError - // As long as we have incomplete information, we cannot mark the - // inability to look up a field as "final", as it may resolve down the - // line. - permanent := x.status >= conjuncts - if m, _ := x.BaseValue.(*ListMarker); m != nil && !m.IsOpen { - permanent = true - } - if (state > partial || permanent) && !x.Accept(c, l) { - code = 0 - } else if hasCycle { - code = CycleError - } - // TODO: if the struct was a literal struct, we can also treat it as - // closed and make this a permanent error. - label := l.SelectorString(c.Runtime) - - // TODO(errors): add path reference and make message - // "undefined field %s in %s" - var err *ValueError - switch { - case isCyclePlaceholder(x.BaseValue): - err = c.NewPosf(pos, "cycle error referencing %s", label) - permanent = false - case l.IsInt(): - err = c.NewPosf(pos, "index out of range [%d] with length %d", - l.Index(), len(x.Elems())) - default: - err = c.NewPosf(pos, "undefined field: %s", label) - } - c.AddBottom(&Bottom{ - Code: code, - Permanent: permanent, - Err: err, - Node: x, - }) - } - return a +func (c *OpContext) lookup(x *Vertex, pos token.Pos, l Feature, flags Flags) *Vertex { + return x.lookup(c, pos, l, flags) } func (c *OpContext) undefinedFieldError(v *Vertex, code ErrorCode) { @@ -1025,7 +956,7 @@ func (c *OpContext) typeErrorAs(v Value, k Kind, as interface{}) { } } -var emptyNode = &Vertex{} +var emptyNode = &Vertex{status: finalized} func pos(x Node) token.Pos { if x.Source() == nil { @@ -1035,13 +966,13 @@ func pos(x Node) token.Pos { } // node is called by SelectorExpr.resolve and IndexExpr.resolve. -func (c *OpContext) node(orig Node, x Expr, scalar bool, state combinedFlags) *Vertex { - if c.OpenInline { - if _, ok := x.(Resolver); !ok { - c.ci.FromEmbed = true - c.inLiteralSelectee++ - defer func() { c.inLiteralSelectee-- }() - } +func (c *OpContext) node(orig Node, x Expr, scalar bool, state Flags) *Vertex { + // Do not treat inline structs as closed by default if within a schema. + // See comment at top of scheduleVertexConjuncts. + if _, ok := x.(Resolver); !ok { + saved := c.ci.FromDef + c.ci.FromDef = false + defer func() { c.ci.FromDef = saved }() } // TODO: always get the vertex. This allows a whole bunch of trickery @@ -1091,7 +1022,7 @@ func (c *OpContext) node(orig Node, x Expr, scalar bool, state combinedFlags) *V // while traversing values. Not evaluating the node here could lead // to a lookup in an unevaluated node, resulting in erroneously failing // lookups. - if c.isDevVersion() && nv.nonRooted { + if nv.nonRooted { nv.CompleteArcsOnly(c) } default: @@ -1112,14 +1043,14 @@ func (c *OpContext) node(orig Node, x Expr, scalar bool, state combinedFlags) *V } // Elems returns the evaluated elements of a list. -func (c *OpContext) Elems(v Value) []*Vertex { +func (c *OpContext) Elems(v Value) iter.Seq[*Vertex] { list := c.list(v) list.Finalize(c) return list.Elems() } // RawElems returns the elements of the list without evaluating them. -func (c *OpContext) RawElems(v Value) []*Vertex { +func (c *OpContext) RawElems(v Value) iter.Seq[*Vertex] { list := c.list(v) return list.Elems() } @@ -1138,16 +1069,6 @@ func (c *OpContext) list(v Value) *Vertex { return x } -func (c *OpContext) scalar(v Value) Value { - v = Unwrap(v) - switch v.(type) { - case *Null, *Bool, *Num, *String, *Bytes: - default: - c.typeError(v, ScalarKinds) - } - return v -} - var zero = &Num{K: NumberKind} func (c *OpContext) Num(v Value, as interface{}) *Num { @@ -1371,10 +1292,26 @@ func (c *OpContext) newBytes(b []byte) Value { return &Bytes{Src: c.src, B: b} } +var ( + boolFalseNoSrc = &Bool{B: false} + boolTrueNoSrc = &Bool{B: true} +) + func (c *OpContext) newBool(b bool) Value { if c.HasErr() { return c.Err() } + // Creating boolean values is a very common operation, + // such as when evaluating unary and binary operators. + // A significant portion of the time, no source is attached + // to the operation, so we can reuse Bool allocations. + if c.src == nil { + if b { + return boolTrueNoSrc + } else { + return boolFalseNoSrc + } + } return &Bool{Src: c.src, B: b} } @@ -1382,14 +1319,42 @@ func (c *OpContext) newList(src ast.Node, parent *Vertex) *Vertex { return c.newInlineVertex(parent, &ListMarker{}) } -// Str reports a debug string of x. -func (c *OpContext) Str(x Node) string { +// String reports a string of x, for use in errors or debugging. +// Use [OpContext.Str] instead for %s format arguments, as it delays the work. +func (c *OpContext) String(x Node) string { if c.Format == nil { return fmt.Sprintf("%T", x) } return c.Format(c.Runtime, x) } +// Formatter wraps an adt.Node with the necessary information to print it. +// +// TODO: we could eliminate the need for this by ensuring that errors are +// _always_ formatted with a printer. We are not far off from this goal, but +// we need to verify several things. +// This is mainly possible because we intend to have a global string index +// using weak references. It also assumes that errors are always printed +// equally. +type Formatter struct { + X Node + + // F formats Node, resolving references as needed.using Runtime. + // TODO: only used for cases where the debug printer is somehow + // circumvented. Verify this no longer happens. + F func(Runtime, Node) string + + // TODO: is runtime needed? Probably not if we have a global string index. + R Runtime +} + +func (f Formatter) String() string { return f.F(f.R, f.X) } + +// Str reports a string of x via a [fmt.Stringer], for use in errors or debugging. +func (c *OpContext) Str(x Node) fmt.Stringer { + return Formatter{X: x, F: c.Format, R: c.Runtime} +} + // NewList returns a new list for the given values. func (c *OpContext) NewList(values ...Value) *Vertex { // TODO: consider making this a literal list instead. diff --git a/vendor/cuelang.org/go/internal/core/adt/cycle.go b/vendor/cuelang.org/go/internal/core/adt/cycle.go index ceead75356..1302e86c4b 100644 --- a/vendor/cuelang.org/go/internal/core/adt/cycle.go +++ b/vendor/cuelang.org/go/internal/core/adt/cycle.go @@ -221,8 +221,31 @@ package adt // and evaluated before doing a lookup in such structs to be correct. For the // purpose of this algorithm, this especially pertains to structural cycles. // -// TODO: implement: current handling of inline still loosly based on old -// algorithm. +// Note that the scope in which scope the "helper" field is defined may +// determine whether or not there is a structural cycle. Consider, for instance, +// +// X: {in: a, out: in} +// a: b: (X & {in: a}).out +// +// Two possible rewrites are: +// +// X: {in: a, out: in} +// a: b: _a.out +// _a: X & {in: a} +// +// and +// +// X: {in: a, out: in} +// a: { +// b: _b.out +// _b: X & {in: a} +// } +// +// The former prevents a structural cycle, the later results in a structural +// cycle. +// +// The current implementation takes the former approach, which more closely +// mimics the V2 implementation. Note that other approaches are possible. // // ### Examples // @@ -559,10 +582,6 @@ type CycleInfo struct { // TODO: make this a method and use CycleType == IsCyclic after V2 is removed. IsCyclic bool - // Inline is used to detect expressions referencing themselves, for instance: - // {x: out, out: x}.out - Inline bool - // TODO(perf): pack this in with CloseInfo. Make an uint32 pointing into // a buffer maintained in OpContext, using a mark-release mechanism. Refs *RefNode @@ -604,7 +623,7 @@ type cyclicConjunct struct { arc *Vertex // cached Vertex } -// CycleType indicates the type of cycle detected. The CyclicType is associated +// CyclicType indicates the type of cycle detected. The CyclicType is associated // with a conjunct and may only increase in value for child conjuncts. type CyclicType uint8 @@ -643,11 +662,6 @@ func (n *nodeContext) detectCycleV3(arc *Vertex, env *Environment, x Resolver, c for r := ci.Refs; r != nil; r = r.Next { if equalDeref(r.Arc, arc) { - if n.node.IsDynamic || ci.Inline { - n.reportCycleError() - return ci, true - } - if equalDeref(r.Node, n.node) { // reference cycle return ci, true @@ -666,13 +680,20 @@ func (n *nodeContext) detectCycleV3(arc *Vertex, env *Environment, x Resolver, c // c: a: int // // This is equivalent to a reference cycle. - if r.Depth == n.node.state.depth { + if r.Depth == n.depth { return ci, true } ci.Refs = nil return ci, false } + if n.hasNonCycle && n.hasNonCyclic && r.Depth != n.depth { + return ci, false + } + + return n.markCyclicPathV3(arc, env, x, ci) + } + if equalDeref(r.Node, n.node) && r.Ref == x && arc.nonRooted { return n.markCyclicPathV3(arc, env, x, ci) } } @@ -688,6 +709,14 @@ func (n *nodeContext) detectCycleV3(arc *Vertex, env *Environment, x Resolver, c return ci, false } +// markNonCyclic records when a non-cyclic conjunct is processed. +func (n *nodeContext) markNonCyclic(id CloseInfo) { + switch id.CycleType { + case NoCycle, IsOptional: + n.hasNonCyclic = true + } +} + // markCyclicV3 marks a conjunct as being cyclic. Also, it postpones processing // the conjunct in the absence of evidence of a non-cyclic conjunct. func (n *nodeContext) markCyclicV3(arc *Vertex, env *Environment, x Resolver, ci CloseInfo) (CloseInfo, bool) { @@ -701,7 +730,6 @@ func (n *nodeContext) markCyclicV3(arc *Vertex, env *Environment, x Resolver, ci // TODO: investigate if we can get rid of cyclicConjuncts in the new // evaluator. v := Conjunct{env, x, ci} - n.node.cc().incDependent(n.ctx, DEFER, nil) n.cyclicConjuncts = append(n.cyclicConjuncts, cyclicConjunct{v, arc}) return ci, true } @@ -718,13 +746,23 @@ func (n *nodeContext) markCyclicPathV3(arc *Vertex, env *Environment, x Resolver // TODO: investigate if we can get rid of cyclicConjuncts in the new // evaluator. v := Conjunct{env, x, ci} - n.node.cc().incDependent(n.ctx, DEFER, nil) n.cyclicConjuncts = append(n.cyclicConjuncts, cyclicConjunct{v, arc}) return ci, true } return ci, false } +// combineCycleInfo merges the cycle information collected in the context into +// the given CloseInfo. Note that it only merges the cycle information in its +// entirety, if present, to avoid getting unrelated data. +func (c *OpContext) combineCycleInfo(ci CloseInfo) CloseInfo { + cc := c.ci.CycleInfo + if cc.IsCyclic { + ci.CycleInfo = cc + } + return ci +} + // hasDepthCycle uses depth counters to keep track of cycles: // - it allows detecting reference cycles as well (state evaluating is // no longer used in v3) @@ -777,358 +815,25 @@ func (c *CloseInfo) setOptionalV3(n *nodeContext) { } } -// markCycle checks whether the reference x is cyclic. There are two cases: -// 1. it was previously used in this conjunct, and -// 2. it directly references a parent node. -// -// Other inputs: -// -// arc the reference to which x points -// env, ci the components of the Conjunct from which x originates -// -// A cyclic node is added to a queue for later processing if no evidence of a -// non-cyclic node has so far been found. updateCyclicStatus processes delayed -// nodes down the line once such evidence is found. -// -// If a cycle is the result of "inline" processing (an expression referencing -// itself), an error is reported immediately. -// -// It returns the CloseInfo with tracked cyclic conjuncts updated, and -// whether or not its processing should be skipped, which is the case either if -// the conjunct seems to be fully cyclic so far or if there is a valid reference -// cycle. -func (n *nodeContext) markCycle(arc *Vertex, env *Environment, x Resolver, ci CloseInfo) (_ CloseInfo, skip bool) { - unreachableForDev(n.ctx) - - n.assertInitialized() - - // TODO(perf): this optimization can work if we also check for any - // references pointing to arc within arc. This can be done with compiler - // support. With this optimization, almost all references could avoid cycle - // checking altogether! - // if arc.status == Finalized && arc.cyclicReferences == nil { - // return v, false - // } - - // Check whether the reference already occurred in the list, signaling - // a potential cycle. - found := false - depth := int32(0) - for r := ci.Refs; r != nil; r = r.Next { - if r.Ref != x { - // TODO(share): this is a bit of a hack. We really should implement - // (*Vertex).cyclicReferences for the new evaluator. However, - // implementing cyclicReferences is somewhat tricky, as it requires - // referenced nodes to be evaluated, which is a guarantee we may not - // want to give. Moreover, it seems we can find a simpler solution - // based on structure sharing. So punt on this solution for now. - if r.Arc != arc || !n.ctx.isDevVersion() { - continue - } - found = true - } - - // A reference that is within a graph that is being evaluated - // may repeat with a different arc and will point to a - // non-finalized arc. A repeating reference that points outside the - // graph will always be the same address. Hence, if this is a - // finalized arc with a different address, it resembles a reference that - // is included through a different path and is not a cycle. - if !equalDeref(r.Arc, arc) && arc.status == finalized { - continue - } - - // For dynamically created structs we mark this as an error. Otherwise - // there is only an error if we have visited the arc before. - if ci.Inline && (arc.IsDynamic || equalDeref(r.Arc, arc)) { - n.reportCycleError() - return ci, true - } - - // We have a reference cycle, as distinguished from a structural - // cycle. Reference cycles represent equality, and thus are equal - // to top. We can stop processing here. - // var nn1, nn2 *Vertex - // if u := r.Node.state.underlay; u != nil { - // nn1 = u.node - // } - // if u := n.node.state.underlay; u != nil { - // nn2 = u.node - // } - if equalDeref(r.Node, n.node) { - return ci, true - } - - depth = r.Depth - found = true - - // Mark all conjuncts of this Vertex that refer to the same node as - // cyclic. This is an extra safety measure to ensure that two conjuncts - // cannot work in tandom to circumvent a cycle. It also tightens - // structural cycle detection in some cases. Late detection of cycles - // can result in a lot of redundant work. - // - // TODO: this loop is not on a critical path, but it may be evaluated - // if it is worthy keeping at some point. - for i, c := range n.node.Conjuncts { - if c.CloseInfo.IsCyclic { - continue - } - for rr := c.CloseInfo.Refs; rr != nil; rr = rr.Next { - // TODO: Is it necessary to find another way to find - // "parent" conjuncts? This mechanism seems not entirely - // accurate. Maybe a pointer up to find the root and then - // "spread" downwards? - if r.Ref == x && equalDeref(r.Arc, rr.Arc) { - n.node.Conjuncts[i].CloseInfo.IsCyclic = true - break - } - } - } - - break - } - - if arc.state != nil { - if d := arc.state.evalDepth; d > 0 && d >= n.ctx.optionalMark { - arc.IsCyclic = true - } - } - - // The code in this switch statement registers structural cycles caught - // through EvaluatingArcs to the root of the cycle. This way, any node - // referencing this value can track these nodes early. This is mostly an - // optimization to shorten the path for which structural cycles are - // detected, which may be critical for performance. -outer: - switch arc.status { - case evaluatingArcs: // also Evaluating? - if arc.state.evalDepth < n.ctx.optionalMark { - break - } - - // The reference may already be there if we had no-cyclic structure - // invalidating the cycle. - for r := arc.cyclicReferences; r != nil; r = r.Next { - if r.Ref == x { - break outer - } - } - - arc.cyclicReferences = &RefNode{ - Arc: deref(arc), - Ref: x, - Next: arc.cyclicReferences, - } - - case finalized: - // Insert cyclic references from found arc, if any. - for r := arc.cyclicReferences; r != nil; r = r.Next { - if r.Ref == x { - // We have detected a cycle, with the only exception if arc is - // a disjunction, as evaluation always stops at unresolved - // disjunctions. - if _, ok := arc.BaseValue.(*Disjunction); !ok { - found = true - } - } - ci.Refs = &RefNode{ - Arc: deref(r.Arc), - Node: deref(n.node), - - Ref: x, - Next: ci.Refs, - Depth: n.depth, - } - } - } - - // NOTE: we need to add a tracked reference even if arc is not cyclic: it - // may still cause a cycle that does not refer to a parent node. For - // instance: - // - // y: [string]: b: y - // x: y - // x: c: x - // - // -> - // - in conjuncts - // - out conjuncts: these count for cycle detection. - // x: { - // [string]: <1: y> b: y - // c: x - // } - // x.c: { - // <1: y> b: y - // <2: x> y - // [string]: <3: x, y> b: y - // <2: x> c: x - // } - // x.c.b: { - // <1: y> y - // [string]: <4: y; Cyclic> b: y - // <3: x, y> b: y - // } - // x.c.b.b: { - // <3: x, y> y - // [string]: <5: x, y, Cyclic> b: y - // <4: y, Cyclic> y - // [string]: <5: x, y, Cyclic> b: y - // } - // x.c.c: { // structural cycle - // <3: x, y> b: y - // <2: x> x - // <6: x, Cyclic>: y - // [string]: <8: x, y; Cyclic> b: y - // <7: x, Cyclic>: c: x - // } - // x.c.c.b: { // structural cycle - // <3: x, y> y - // [string]: <3: x, y; Cyclic> b: y - // <8: x, y; Cyclic> y - // } - // -> - // x: [string]: b: y - // x: c: b: y - // x: c: [string]: b: y - // x: c: b: b: y - // x: c: b: [string]: b: y - // x: c: b: b: b: y - // .... // structural cycle 1 - // x: c: c: x // structural cycle 2 - // - // Note that in this example there is a structural cycle at x.c.c, but we - // would need go guarantee that cycle is detected before the algorithm - // descends into x.c.b. - if !found || depth != n.depth { - // Adding this in case there is a definite cycle is unnecessary, but - // gives somewhat better error messages. - // We also need to add the reference again if the depth differs, as - // the depth is used for tracking "new structure". - // var nn *Vertex - // if u := n.node.state.underlay; u != nil { - // nn = u.node - // } - ci.Refs = &RefNode{ - Arc: deref(arc), - Ref: x, - Node: deref(n.node), - Next: ci.Refs, - Depth: n.depth, - } - } - - if !found && arc.status != evaluatingArcs { - // No cycle. - return ci, false - } - - // TODO: consider if we should bail if a cycle is detected using this - // mechanism. Ultimately, especially when the old evaluator is removed - // and the status field purged, this should be used instead of the above. - // if !found && arc.state.evalDepth < n.ctx.optionalMark { - // // No cycle. - // return ci, false - // } - - alreadyCycle := ci.IsCyclic - ci.IsCyclic = true - - // TODO: depth might legitimately be 0 if it is a root vertex. - // In the worst case, this may lead to a spurious cycle. - // Fix this by ensuring the root vertex starts with a depth of 1, for - // instance. - if depth > 0 { - // Look for evidence of "new structure" to invalidate the cycle. - // This is done by checking for non-cyclic conjuncts between the - // current vertex up to the ancestor to which the reference points. - // Note that the cyclic conjunct may not be marked as such, so we - // look for at least one other non-cyclic conjunct if this is the case. - upCount := n.depth - depth - for p := n.node.Parent; p != nil; p = p.Parent { - if upCount--; upCount <= 0 { - break - } - a := p.Conjuncts - count := 0 - for _, c := range a { - count += getNonCyclicCount(c) - } - if !alreadyCycle { - count-- - } - if count > 0 { - return ci, false - } - } - } - - n.hasAnyCyclicConjunct = true - if !n.hasNonCycle && env != nil { - // TODO: investigate if we can get rid of cyclicConjuncts in the new - // evaluator. - v := Conjunct{env, x, ci} - if n.ctx.isDevVersion() { - n.node.cc().incDependent(n.ctx, DEFER, nil) - } - n.cyclicConjuncts = append(n.cyclicConjuncts, cyclicConjunct{v, arc}) - return ci, true - } - - return ci, false -} - -func getNonCyclicCount(c Conjunct) int { - switch a, ok := c.x.(*ConjunctGroup); { - case ok: - count := 0 - for _, c := range *a { - count += getNonCyclicCount(c) - } - return count - - case !c.CloseInfo.IsCyclic: - return 1 - - default: - return 0 - } -} - // updateCyclicStatusV3 looks for proof of non-cyclic conjuncts to override // a structural cycle. func (n *nodeContext) updateCyclicStatusV3(c CloseInfo) { + n.hasFieldValue = true if !c.IsCyclic { n.hasNonCycle = true for _, c := range n.cyclicConjuncts { ci := c.c.CloseInfo - ci.cc = n.node.rootCloseContext(n.ctx) - n.scheduleVertexConjuncts(c.c, c.arc, ci) - n.node.cc().decDependent(n.ctx, DEFER, nil) - } - n.cyclicConjuncts = n.cyclicConjuncts[:0] - } -} - -// updateCyclicStatus looks for proof of non-cyclic conjuncts to override -// a structural cycle. -func (n *nodeContext) updateCyclicStatus(c CloseInfo) { - unreachableForDev(n.ctx) - - if !c.IsCyclic { - n.hasNonCycle = true - for _, c := range n.cyclicConjuncts { - n.addVertexConjuncts(c.c, c.arc, false) + if c.arc != nil { + n.scheduleVertexConjuncts(c.c, c.arc, ci) + } else { + n.scheduleConjunct(c.c, ci) + } } n.cyclicConjuncts = n.cyclicConjuncts[:0] } } func assertStructuralCycleV3(n *nodeContext) bool { - // TODO: is this the right place to put it? - for range n.cyclicConjuncts { - n.node.cc().decDependent(n.ctx, DEFER, nil) - } n.cyclicConjuncts = n.cyclicConjuncts[:0] if n.hasOnlyCyclicConjuncts() { @@ -1138,14 +843,6 @@ func assertStructuralCycleV3(n *nodeContext) bool { return false } -func assertStructuralCycle(n *nodeContext) bool { - if n.hasAnyCyclicConjunct && !n.hasNonCycle { - n.reportCycleError() - return true - } - return false -} - func (n *nodeContext) reportCycleError() { b := &Bottom{ Code: StructuralCycleError, @@ -1155,6 +852,9 @@ func (n *nodeContext) reportCycleError() { // TODO: probably, this should have the referenced arc. } n.setBaseValue(CombineErrors(nil, n.node.Value(), b)) + // TODO(mem): might still be processing, so only use this when we + // exclude processed nodes. + // n.node.clearArcs(n.ctx) n.node.Arcs = nil } @@ -1166,8 +866,7 @@ func (n *nodeContext) reportCycleError() { func makeAnonymousConjunct(env *Environment, x Expr, refs *RefNode) Conjunct { return Conjunct{ env, x, CloseInfo{CycleInfo: CycleInfo{ - Inline: true, - Refs: refs, + Refs: refs, }}, } } @@ -1184,35 +883,6 @@ func (n *nodeContext) decDepth() { n.ctx.evalDepth-- } -// markOptional marks that we are about to process an "optional element" that -// allows errors. In these cases, structural cycles are not "terminal". -// -// Examples of such constructs are: -// -// Optional fields: -// -// a: b?: a -// -// Pattern constraints: -// -// a: [string]: a -// -// Disjunctions: -// -// a: b: null | a -// -// A call to markOptional should be paired with a call to unmarkOptional. -func (n *nodeContext) markOptional() (saved int) { - saved = n.ctx.evalDepth - n.ctx.optionalMark = n.ctx.evalDepth - return saved -} - -// See markOptional. -func (n *nodeContext) unmarkOptional(saved int) { - n.ctx.optionalMark = saved -} - // markDepth assigns the current evaluation depth to the receiving node. // Any previously assigned depth is saved and returned and should be restored // using unmarkDepth after processing n. diff --git a/vendor/cuelang.org/go/internal/core/adt/debug.go b/vendor/cuelang.org/go/internal/core/adt/debug.go index 9eeab5e7ae..93fe9cb38a 100644 --- a/vendor/cuelang.org/go/internal/core/adt/debug.go +++ b/vendor/cuelang.org/go/internal/core/adt/debug.go @@ -140,10 +140,12 @@ func OpenNodeGraph(title, path, code, out, graph string) { // and all its dependencies that have not completed processing. // DO NOT DELETE: this is used to insert during debugging of the evaluator // to inspect a node. -func openDebugGraph(ctx *OpContext, cc *closeContext, name string) { - v := cc.src +func openDebugGraph(ctx *OpContext, v *Vertex, name string) { + if !OpenGraphs { + return + } graph, _ := CreateMermaidGraph(ctx, v, true) - path := filepath.Join(".debug", "TestX", name, fmt.Sprintf("%p", cc)) + path := filepath.Join(".debug", "TestX", name, fmt.Sprintf("%v", v.Path())) OpenNodeGraph(name, path, "in", "out", graph) } @@ -156,20 +158,8 @@ type mermaidContext struct { hasError bool - // roots maps the root closeContext of any Vertex to the analysis data - // for that Vertex. - roots map[*closeContext]*mermaidVertex - - // processed indicates whether the node in question has been processed - // by the dependency analysis. - processed map[*closeContext]bool - - // inConjuncts indicates whether a node is explicitly referenced by - // a Conjunct. These nodes are visualized with an additional circle. - inConjuncts map[*closeContext]bool - - // ccID maps a closeContext to a unique ID. - ccID map[*closeContext]string + // roots maps a Vertex to the analysis data for that Vertex. + roots map[*Vertex]*mermaidVertex w io.Writer @@ -179,30 +169,25 @@ type mermaidContext struct { } type mermaidVertex struct { - f Feature - w *bytes.Buffer - tasks *bytes.Buffer - intra *bytes.Buffer + vertex *Vertex + f Feature + w *bytes.Buffer + tasks *bytes.Buffer + intra *bytes.Buffer + processed bool } // CreateMermaidGraph creates an analysis of relations and values involved in // nodes with unbalanced increments. The graph is in Mermaid format. func CreateMermaidGraph(ctx *OpContext, v *Vertex, all bool) (graph string, hasError bool) { - if !DebugDeps { - return "", false - } - buf := &strings.Builder{} m := &mermaidContext{ - ctx: ctx, - v: v, - roots: map[*closeContext]*mermaidVertex{}, - processed: map[*closeContext]bool{}, - inConjuncts: map[*closeContext]bool{}, - ccID: map[*closeContext]string{}, - w: buf, - all: all, + ctx: ctx, + v: v, + roots: map[*Vertex]*mermaidVertex{}, + w: buf, + all: all, } io.WriteString(m.w, "graph TD\n") @@ -213,17 +198,32 @@ func CreateMermaidGraph(ctx *OpContext, v *Vertex, all bool) (graph string, hasE fmt.Fprintf(m.w, "style %s stroke-width:5\n\n", m.vertexID(v)) // Trigger descent on first vertex. This may include other vertices when // traversing closeContexts if they have dependencies on such vertices. - m.vertex(v) + m.vertex(v, true) + + // get parent context, if there is relevant closedness information. + root := v.Parent + for p := root; p != nil; p = p.Parent { + n := p.state + if n == nil { + continue + } + if len(n.reqDefIDs) > 0 { + root = p.Parent + } + } + for p := v.Parent; p != root; p = p.Parent { + m.vertex(p, true) // only render relevant child + } // Close and flush all collected vertices. - for i, v := range m.vertices { + for _, v := range m.vertices { v.closeVertex() - if i == 0 || len(m.ccID) > 0 { - m.w.Write(v.w.Bytes()) - } + m.w.Write(v.w.Bytes()) } - return buf.String(), m.hasError + s := buf.String() + + return s, m.hasError } // vertex creates a blob of Mermaid graph representing one vertex. It has @@ -261,24 +261,21 @@ func CreateMermaidGraph(ctx *OpContext, v *Vertex, all bool) (graph string, hasE // A vertex has the following name: path(v); done // // Each closeContext has the following info: ptr(cc); cc.count -func (m *mermaidContext) vertex(v *Vertex) *mermaidVertex { - root := v.rootCloseContext(m.ctx) - - vc := m.roots[root] +func (m *mermaidContext) vertex(v *Vertex, recursive bool) *mermaidVertex { + vc := m.roots[v] if vc != nil { return vc } vc = &mermaidVertex{ - f: v.Label, - w: &bytes.Buffer{}, - intra: &bytes.Buffer{}, + vertex: v, + f: v.Label, + w: &bytes.Buffer{}, + intra: &bytes.Buffer{}, } m.vertices = append(m.vertices, vc) - m.tagReferencedConjuncts(v.Conjuncts) - - m.roots[root] = vc + m.roots[v] = vc w := vc.w var status string @@ -298,21 +295,11 @@ func (m *mermaidContext) vertex(v *Vertex) *mermaidVertex { indentOnNewline(w, 1) fmt.Fprintf(w, "subgraph %s[%s: %s]\n", m.vertexID(v), path, status) - m.cc(root) + m.vertexInfo(vc, recursive) return vc } -func (m *mermaidContext) tagReferencedConjuncts(a []Conjunct) { - for _, c := range a { - m.inConjuncts[c.CloseInfo.cc] = true - - if g, ok := c.x.(*ConjunctGroup); ok { - m.tagReferencedConjuncts([]Conjunct(*g)) - } - } -} - func (v *mermaidVertex) closeVertex() { w := v.w @@ -325,14 +312,11 @@ func (v *mermaidVertex) closeVertex() { // TODO: write all notification sources (or is this just the node?) indent(w, 1) - fmt.Fprintf(w, "end\n") + fmt.Fprintf(w, "\nend\n") } -func (m *mermaidContext) task(d *ccDep) string { - v := d.dependency.src - - // This must already exist. - vc := m.vertex(v) +func (m *mermaidContext) task(vc *mermaidVertex, t *task, id int) string { + v := vc.vertex if vc.tasks == nil { vc.tasks = &bytes.Buffer{} @@ -340,20 +324,20 @@ func (m *mermaidContext) task(d *ccDep) string { fmt.Fprintf(vc.tasks, "subgraph %s_tasks[tasks]\n", m.vertexID(v)) } - if d.task != nil && v != d.task.node.node { + if t != nil && v != t.node.node { panic("inconsistent task") } - taskID := fmt.Sprintf("%s_%d", m.vertexID(v), d.taskID) + taskID := fmt.Sprintf("%s_%d", m.vertexID(v), id) var state string var completes condition var kind string - if d.task != nil { - state = d.task.state.String()[:2] - completes = d.task.completes - kind = d.task.run.name + if t != nil { + state = t.state.String()[:2] + completes = t.completes + kind = t.run.name } indentOnNewline(vc.tasks, 3) - fmt.Fprintf(vc.tasks, "%s(%d", taskID, d.taskID) + fmt.Fprintf(vc.tasks, "%s(%d", taskID, id) indentOnNewline(vc.tasks, 4) io.WriteString(vc.tasks, state) indentOnNewline(vc.tasks, 4) @@ -361,80 +345,127 @@ func (m *mermaidContext) task(d *ccDep) string { indentOnNewline(vc.tasks, 4) fmt.Fprintf(vc.tasks, "%x)\n", completes) - if s := d.task.blockedOn; s != nil { - m.vertex(s.node.node) + if s := t.blockedOn; s != nil { + m.vertex(s.node.node, false) fmt.Fprintf(m.w, "%s_tasks == BLOCKED ==> %s\n", m.vertexID(s.node.node), taskID) } return taskID } -func (m *mermaidContext) cc(cc *closeContext) { - if m.processed[cc] { +func (m *mermaidContext) vertexInfo(vc *mermaidVertex, recursive bool) { + if vc.processed { return } - m.processed[cc] = true + vc.processed = true + + v := vc.vertex // This must already exist. - v := m.vertex(cc.src) // Dependencies at different scope levels. global := m.w - node := v.w - - for _, d := range cc.dependencies { - indentLevel := 2 - var w io.Writer - var name, link string - - switch { - case !d.decremented: - link = fmt.Sprintf(`--%s-->`, d.kind.String()) - case m.all: - link = fmt.Sprintf("-. %s .->", d.kind.String()[0:1]) - default: - continue + node := vc.w + + if s := v.state; s != nil { + for i, t := range s.tasks { + taskID := m.task(vc, t, i) + name := fmt.Sprintf("%s((%d))", taskID, 1) + _ = name + // dst := m.pstr(cc) + // indent(w, indentLevel) + // fmt.Fprintf(w, "%s %s %s\n", name, link, dst) } + } - // Only include still outstanding nodes. - switch d.kind { - case PARENT: - w = node - name = m.pstr(d.dependency) - case EVAL, ARC, NOTIFY, DISJUNCT, COMP: - w = global - indentLevel = 1 - name = m.pstr(d.dependency) - - case TASK: - w = node - taskID := "disjunct" - if d.task != nil { - taskID = m.task(d) + indentOnNewline(node, 2) + if n := v.state; n != nil { + for i, d := range n.reqDefIDs { + indentOnNewline(node, 2) + var id any = d.id + if d.v != nil && d.v.ClosedNonRecursive && d.id == 0 { + id = "once" } - name = fmt.Sprintf("%s((%d))", taskID, d.taskID) - case ROOT, INIT, SHARED: - w = node - src := cc.src - if v.f != src.Label { - panic("incompatible labels") + reqID := fmt.Sprintf("%s_req_%d", m.vertexID(v), i) + arrow := "%s == R ==> %s\n" + format := "%s((%d%s))\n" + if d.ignore { + arrow = "%s -. R .-> %s\n" + format = "%s((%d%si))\n" + } + flags := "" + if d.kind != 0 { + flags += d.kind.String() + } + if d.embed != 0 { + flags += fmt.Sprintf("-%de", d.embed) + } + if d.parent != 0 { + flags += fmt.Sprintf("-%dp", d.parent) } - name = fmt.Sprintf("root_%s", m.vertexID(src)) - } - if w != nil { - dst := m.pstr(cc) - indent(w, indentLevel) - fmt.Fprintf(w, "%s %s %s\n", name, link, dst) + fmt.Fprintf(node, format, reqID, id, flags) + m.vertex(d.v, false) + fmt.Fprintf(global, arrow, reqID, m.vertexID(d.v)) } + indentOnNewline(node, 2) + + // fmt.Fprintf(node, "subgraph %s_conjuncts[conjunctInfo]\n", m.vertexID(v)) + fmt.Fprintf(node, "subgraph %s_conjuncts[conjuncts]\n", m.vertexID(v)) + for i, conj := range n.conjunctInfo { + indentOnNewline(node, 3) + kind := conj.kind.String() + if kind == "_|_" { + kind = "error" + } + x := conj.flags + flags := "" + if x != 0 { + flags = " " + } + if x&cHasTop != 0 { + flags += "_" + } + if x&cHasStruct != 0 { + flags += "s" + } + if x&cHasEllipsis != 0 { + flags += "." + } + if x&cHasOpenValidator != 0 { + flags += "o" + } + var scope string + if conj.embed != 0 { + scope = fmt.Sprintf("-%d", conj.embed) + } + fmt.Fprintf(node, "%s_conj_%d((%v\n%d%s%s))", m.vertexID(v), i, kind, conj.id, scope, flags) + } + indentOnNewline(node, 2) + fmt.Fprintln(node, "end") + + if len(n.replaceIDs) > 0 { + fmt.Fprintf(node, "subgraph %s_drop[replace]\n", m.vertexID(v)) + for i, r := range n.replaceIDs { + indentOnNewline(node, 3) + dropID := fmt.Sprintf("%s_drop_%d", m.vertexID(v), i) + flags := "" + fmt.Fprintf(node, "%s((%d->%d%s))\n", dropID, r.from, r.to, flags) + } + indentOnNewline(node, 2) + // fmt.Fprintf(node, "end\n") + fmt.Fprintln(node, "end") + } + } - // If the references count is 0, all direct dependencies must have - // completed as well. In this case, descending into each of them should - // not end up printing anything. In case of any bugs, these nodes will - // show up as unattached nodes. - - if dep := d.dependency; dep != nil && dep != cc { - m.cc(dep) + if v.Parent != nil { + m.vertex(v.Parent, false) // ensure the arc is also processed + indentOnNewline(node, 2) + fmt.Fprintf(global, "%s --> %s\n", m.vertexID(v.Parent), m.vertexID(v)) + } + if recursive { + for _, arc := range v.Arcs { + m.vertex(arc, true) // ensure the arc is also processed } } } @@ -454,78 +485,6 @@ func (m *mermaidContext) vertexID(v *Vertex) string { return "v" + s[len(s)-sigPtrLen:] } -func (m *mermaidContext) pstr(cc *closeContext) string { - if id, ok := m.ccID[cc]; ok { - return id - } - - ptr := fmt.Sprintf("%p", cc) - ptr = ptr[len(ptr)-sigPtrLen:] - id := fmt.Sprintf("cc%s", ptr) - m.ccID[cc] = id - - v := m.vertex(cc.src) - - w := v.w - - indent(w, 2) - w.WriteString(id) - - var open, close = "((", "))" - if m.inConjuncts[cc] { - open, close = "(((", ")))" - } - - w.WriteString(open) - w.WriteString("cc") - if cc.conjunctCount > 0 { - fmt.Fprintf(w, " c:%d: d:%d", cc.conjunctCount, cc.disjunctCount) - } - indentOnNewline(w, 3) - w.WriteString(ptr) - - flags := &bytes.Buffer{} - addFlag := func(test bool, flag byte) { - if test { - flags.WriteByte(flag) - } - } - addFlag(cc.isDefOrig, '#') - addFlag(cc.isEmbed, 'E') - addFlag(cc.isClosed, 'c') - addFlag(cc.isClosedOnce, 'C') - addFlag(cc.isTotal, 'o') - flags.WriteByte(cc.arcType.String()[0]) - io.Copy(w, flags) - - // Show the origin of the closeContext. - indentOnNewline(w, 3) - fmt.Fprintf(w, "+%d", cc.depth) - if cc.holeID != 0 { - fmt.Fprintf(w, " H%d", cc.holeID) - } - - w.WriteString(close) - - switch { - case cc.conjunctCount == 0: - case cc.conjunctCount <= cc.disjunctCount: - // TODO: Extra checks for disjunctions? - // E.g.: cc.src is not a disjunction - default: - // If cc.conjunctCount > cc.disjunctCount. - // TODO: count the number of non-decremented DISJUNCT dependencies. - fmt.Fprintf(w, ":::err") - if cc.src == m.v { - m.hasError = true - } - } - - w.WriteString("\n") - - return id -} - func indentOnNewline(w io.Writer, level int) { w.Write([]byte{'\n'}) indent(w, level) diff --git a/vendor/cuelang.org/go/internal/core/adt/default.go b/vendor/cuelang.org/go/internal/core/adt/default.go index 7fc0b8a778..d1acfe9274 100644 --- a/vendor/cuelang.org/go/internal/core/adt/default.go +++ b/vendor/cuelang.org/go/internal/core/adt/default.go @@ -14,6 +14,10 @@ package adt +import ( + "slices" +) + // Default returns the default value or itself if there is no default. func Default(v Value) Value { switch x := v.(type) { @@ -131,9 +135,9 @@ func stripNonDefaults(elem Elem) (r Elem, stripped bool) { // NOTE: this code requires allocations unconditional. This should be // mitigated once we optimize conjunct groupings. isNew := false - var a ConjunctGroup = make([]Conjunct, len(*x)) - for i, c := range *x { - a[i].x, ok = stripNonDefaults(c.Expr()) + a := slices.Clone(*x) + for i, c := range a { + a[i].x, ok = stripNonDefaults(c.Elem()) if ok { isNew = true } diff --git a/vendor/cuelang.org/go/internal/core/adt/defidtype_string.go b/vendor/cuelang.org/go/internal/core/adt/defidtype_string.go new file mode 100644 index 0000000000..a00577fa8b --- /dev/null +++ b/vendor/cuelang.org/go/internal/core/adt/defidtype_string.go @@ -0,0 +1,27 @@ +// Code generated by "stringer -type=defIDType -linecomment"; DO NOT EDIT. + +package adt + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[defIDTypeUnknown-0] + _ = x[defEmbedding-1] + _ = x[defReference-2] + _ = x[defStruct-3] +} + +const _defIDType_name = "*EDS" + +var _defIDType_index = [...]uint8{0, 1, 2, 3, 4} + +func (i defIDType) String() string { + idx := int(i) - 0 + if i < 0 || idx >= len(_defIDType_index)-1 { + return "defIDType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _defIDType_name[_defIDType_index[idx]:_defIDType_index[idx+1]] +} diff --git a/vendor/cuelang.org/go/internal/core/adt/dep.go b/vendor/cuelang.org/go/internal/core/adt/dep.go deleted file mode 100644 index 67261d9294..0000000000 --- a/vendor/cuelang.org/go/internal/core/adt/dep.go +++ /dev/null @@ -1,371 +0,0 @@ -// Copyright 2025 CUE Authors -// -// 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 -// -// https://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. - -package adt - -import "fmt" - -// depKind is a type of dependency that is tracked with incDependent and -// decDependent. For each there should be matching pairs passed to these -// functions. The debugger, when used, tracks and verifies that these -// dependencies are balanced. -type depKind int - -//go:generate go run golang.org/x/tools/cmd/stringer -type=depKind - -const ( - // PARENT dependencies are used to track the completion of parent - // closedContexts within the closedness tree. - PARENT depKind = iota + 1 - - // ARC dependencies are used to track the completion of corresponding - // closedContexts in parent Vertices. - ARC - - // NOTIFY dependencies keep a note while dependent conjuncts are collected - NOTIFY // root node of source - - // TASK dependencies are used to track the completion of a task. - TASK - - // DISJUNCT is used to mark an incomplete disjunct. - DISJUNCT - - // EVAL tracks that the conjunct associated with a closeContext has been - // inserted using scheduleConjunct. A closeContext may not be deleted - // as long as the conjunct has not been evaluated yet. - // This prevents a node from being released if an ARC decrement happens - // before a node is evaluated. - EVAL - - // COMP tracks pending arcs in comprehensions. - COMP - - // ROOT dependencies are used to track that all nodes of parents are - // added to a tree. - ROOT // Always refers to self. - - // INIT dependencies are used to hold ownership of a closeContext during - // initialization and prevent it from being finalized when scheduling a - // node's conjuncts. - INIT - - // DEFER is used to track recursive processing of a node. - DEFER // Always refers to self. - - // SHARED is used to track shared nodes. The processing of shared nodes may - // change until all other conjuncts have been processed. - SHARED - - // TEST is used for testing notifications. - TEST // Always refers to self. -) - -// ccDep is used to record counters which is used for debugging only. -// It is purpose is to be precise about matching inc/dec as well as to be able -// to traverse dependency. -type ccDep struct { - dependency *closeContext - kind depKind - decremented bool - - // task keeps a reference to a task for TASK dependencies. - task *task - // taskID indicates the sequence number of a task within a scheduler. - taskID int -} - -func (c *closeContext) addDependent(ctx *OpContext, kind depKind, dependant *closeContext) *ccDep { - if dependant == nil { - dependant = c - } - - if ctx.LogEval > 1 { - ctx.Logf(ctx.vertex, "INC(%s) %v %p parent: %p %d\n", kind, c.Label(), c, c.parent, c.conjunctCount) - } - - dep := &ccDep{kind: kind, dependency: dependant} - c.dependencies = append(c.dependencies, dep) - - return dep -} - -// matchDecrement checks that this decrement matches a previous increment. -func (c *closeContext) matchDecrement(ctx *OpContext, v *Vertex, kind depKind, dependant *closeContext) { - if dependant == nil { - dependant = c - } - - if ctx.LogEval > 1 { - ctx.Logf(ctx.vertex, "DEC(%s) %v %p %d\n", kind, c.Label(), c, c.conjunctCount) - } - - for _, d := range c.dependencies { - if d.kind != kind { - continue - } - if d.dependency != dependant { - continue - } - // Only one typ-dependant pair possible. - if d.decremented { - // There might be a duplicate entry, so continue searching. - continue - } - - d.decremented = true - return - } - - if DebugDeps { - panic(fmt.Sprintf("unmatched decrement: %s", kind)) - } -} - -// A ccDepRef x refers to the x.src.[arcs|notify][x.index] -// -// We use this instead of pointers, because the address may change when -// growing a slice. We use this instead mechanism instead of a pointers so -// that we do not need to maintain separate free buffers once we use pools of -// closeContext. -type ccDepRef struct { - src *closeContext - kind depKind - index int -} - -// addArc adds a dependent arc to c. If child is an arc, child.src == key -func (c *closeContext) addArcDependency(ctx *OpContext, matched bool, child *closeContext) { - root := child.src.cc() - - // NOTE: do not increment - // - either root closeContext or otherwise resulting from sub closeContext - // all conjuncts will be added now, notified, or scheduled as task. - for _, a := range c.arcs { - if a.root == root { - panic("addArc: Label already exists") - } - } - child.incDependent(ctx, ARC, c) // matched in decDependent REF(arcs) - - c.arcs = append(c.arcs, ccArc{ - matched: matched, - root: root, - dst: child, - }) - - root.externalDeps = append(root.externalDeps, ccDepRef{ - src: c, - kind: ARC, - index: len(c.arcs) - 1, - }) -} - -func (c *closeContext) addNotifyDependency(ctx *OpContext, dst *closeContext) bool { - for _, a := range c.notify { - if a.dst == dst { - return false - } - } - dst.incDependent(ctx, NOTIFY, c) // matched in decDependent REF(arcs) - - c.notify = append(c.notify, ccNotify{dst: dst}) - - root := dst.src.cc() - root.externalDeps = append(root.externalDeps, ccDepRef{ - src: c, - kind: NOTIFY, - index: len(c.notify) - 1, - }) - return true -} - -// incDisjunct increases disjunction-related counters. We require kind to be -// passed explicitly so that we can easily find the points where certain kinds -// are used. -func (c *closeContext) incDisjunct(ctx *OpContext, kind depKind) { - if kind != DISJUNCT { - panic("unexpected kind") - } - c.incDependent(ctx, DISJUNCT, nil) - - // TODO: the counters are only used in debug mode and we could skip this - // if debug is disabled. - for ; c != nil; c = c.parent { - c.disjunctCount++ - } -} - -// decDisjunct decreases disjunction-related counters. We require kind to be -// passed explicitly so that we can easily find the points where certain kinds -// are used. -func (c *closeContext) decDisjunct(ctx *OpContext, kind depKind) { - if kind != DISJUNCT { - panic("unexpected kind") - } - c.decDependent(ctx, DISJUNCT, nil) - - // TODO: the counters are only used in debug mode and we could skip this - // if debug is disabled. - for ; c != nil; c = c.parent { - c.disjunctCount-- - } -} - -// incDependent needs to be called for any conjunct or child closeContext -// scheduled for c that is queued for later processing and not scheduled -// immediately. -func (c *closeContext) incDependent(ctx *OpContext, kind depKind, dependant *closeContext) (debug *ccDep) { - if c.src == nil { - panic("incDependent: unexpected nil src") - } - if dependant != nil && c.generation != dependant.generation { - // TODO: enable this check. - - // panic(fmt.Sprintf("incDependent: inconsistent generation: %d %d", c.generation, dependant.generation)) - } - debug = c.addDependent(ctx, kind, dependant) - - if c.done { - openDebugGraph(ctx, c, "incDependent: already checked") - - panic(fmt.Sprintf("incDependent: already closed: %p", c)) - } - - c.conjunctCount++ - return debug -} - -// decDependent needs to be called for any conjunct or child closeContext for -// which a corresponding incDependent was called after it has been successfully -// processed. -func (c *closeContext) decDependent(ctx *OpContext, kind depKind, dependant *closeContext) { - v := c.src - - c.matchDecrement(ctx, v, kind, dependant) - c.decDependentNoMatch(ctx, kind, dependant) -} - -// decDependentNoMatch is like decDependent, but does not check for a matching -// increment. This is useful when a decrement is triggered during creating -// a disjunct overlay, as it obviates the need to create the matching debug -// dependency. -func (c *closeContext) decDependentNoMatch(ctx *OpContext, kind depKind, dependant *closeContext) { - if c.conjunctCount == 0 { - panic(fmt.Sprintf("negative reference counter %d %p", c.conjunctCount, c)) - } - - c.conjunctCount-- - if c.conjunctCount > 0 { - return - } - - c.done = true - - for i, a := range c.arcs { - cc := a.dst - if a.decremented { - continue - } - c.arcs[i].decremented = true - cc.decDependent(ctx, ARC, c) - } - - for i, a := range c.notify { - cc := a.dst - if a.decremented { - continue - } - c.notify[i].decremented = true - cc.decDependent(ctx, NOTIFY, c) - } - - if !c.updateClosedInfo(ctx) { - return - } - - p := c.parent - - p.decDependent(ctx, PARENT, c) // REF(decrement: spawn) - - // If we have started decrementing a child closeContext, the parent started - // as well. If it is still marked as needing an EVAL decrement, which can - // happen if processing started before the node was added, it is safe to - // decrement it now. In this case the NOTIFY and ARC dependencies will keep - // the nodes alive until they can be completed. - if dep := p.needsCloseInSchedule; dep != nil { - p.needsCloseInSchedule = nil - p.decDependent(ctx, EVAL, dep) - } -} - -// breakIncomingNotifications walks over incoming arcs and forces any remaining -// work to be done. -func (n *nodeContext) breakIncomingNotifications(mode runMode) { - v := n.node - // TODO: replace with something more principled that does not piggyback on - // debug information. - for _, r := range v.cc().externalDeps { - if r.kind != NOTIFY { - continue - } - src := r.src - a := &src.notify[r.index] - if a.decremented { - continue - } - if n := src.src.getState(n.ctx); n != nil { - n.completeNodeTasks(mode) - } - } -} - -// breakIncomingDeps breaks all incoming dependencies, which includes arcs and -// pending notifications and attempts all remaining work. -// -// We should only break incoming dependencies if we are finalizing nodes, as -// breaking them earlier can cause a "already closed" panic. To make sure of -// this, we force the caller to pass mode. -func (n *nodeContext) breakIncomingDeps(mode runMode) { - if mode != finalize { - return - } - - // TODO: remove this block in favor of finalizing notification nodes, - // or what have you. We have patched this to skip evaluating when using - // disjunctions, but this is overall a brittle approach. - for _, r := range n.node.cc().externalDeps { - src := r.src - switch r.kind { - case ARC: - a := &src.arcs[r.index] - if a.decremented { - continue - } - a.decremented = true - - src.src.unify(n.ctx, needTasksDone, attemptOnly) - a.dst.decDependent(n.ctx, ARC, src) - case NOTIFY: - a := &src.notify[r.index] - if a.decremented { - continue - } - a.decremented = true - - src.src.unify(n.ctx, needTasksDone, attemptOnly) - a.dst.decDependent(n.ctx, NOTIFY, src) - } - } -} diff --git a/vendor/cuelang.org/go/internal/core/adt/depkind_string.go b/vendor/cuelang.org/go/internal/core/adt/depkind_string.go deleted file mode 100644 index 0308eb57c9..0000000000 --- a/vendor/cuelang.org/go/internal/core/adt/depkind_string.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by "stringer -type=depKind"; DO NOT EDIT. - -package adt - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[PARENT-1] - _ = x[ARC-2] - _ = x[NOTIFY-3] - _ = x[TASK-4] - _ = x[DISJUNCT-5] - _ = x[EVAL-6] - _ = x[COMP-7] - _ = x[ROOT-8] - _ = x[INIT-9] - _ = x[DEFER-10] - _ = x[SHARED-11] - _ = x[TEST-12] -} - -const _depKind_name = "PARENTARCNOTIFYTASKDISJUNCTEVALCOMPROOTINITDEFERSHAREDTEST" - -var _depKind_index = [...]uint8{0, 6, 9, 15, 19, 27, 31, 35, 39, 43, 48, 54, 58} - -func (i depKind) String() string { - i -= 1 - if i < 0 || i >= depKind(len(_depKind_index)-1) { - return "depKind(" + strconv.FormatInt(int64(i+1), 10) + ")" - } - return _depKind_name[_depKind_index[i]:_depKind_index[i+1]] -} diff --git a/vendor/cuelang.org/go/internal/core/adt/dev.go b/vendor/cuelang.org/go/internal/core/adt/dev.go deleted file mode 100644 index 28db747d3c..0000000000 --- a/vendor/cuelang.org/go/internal/core/adt/dev.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2023 CUE Authors -// -// 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. - -package adt - -// This file contains types to help in the transition from the old to new -// evaluation model. - -func unreachableForDev(c *OpContext) { - if c.isDevVersion() { - panic("unreachable for development version") - } -} - -type combinedFlags uint32 - -// oldOnly indicates that a Vertex should only be evaluated for the old -// evaluator. -func oldOnly(state vertexStatus) combinedFlags { - return combinedFlags(state) | - combinedFlags(ignore)<<8 | - combinedFlags(allKnown)<<16 -} - -func combineMode(cond condition, mode runMode) combinedFlags { - return combinedFlags(mode)<<8 | combinedFlags(cond)<<16 -} - -func attempt(state vertexStatus, cond condition) combinedFlags { - return combinedFlags(state) | combineMode(cond, attemptOnly) -} - -func require(state vertexStatus, cond condition) combinedFlags { - return combinedFlags(state) | combineMode(cond, yield) -} - -func final(state vertexStatus, cond condition) combinedFlags { - return combinedFlags(state) | combineMode(cond, finalize) -} - -func deprecated(c *OpContext, state vertexStatus) combinedFlags { - // if c.isDevVersion() { - // panic("calling function may not be used in new evaluator") - // } - return combinedFlags(state) -} - -func (f combinedFlags) vertexStatus() vertexStatus { - return vertexStatus(f & 0xff) -} - -func (f combinedFlags) withVertexStatus(x vertexStatus) combinedFlags { - f &^= 0xff - f |= combinedFlags(x) - return f -} - -func (f combinedFlags) conditions() condition { - return condition(f >> 16) -} - -func (f combinedFlags) runMode() runMode { - return runMode(f>>8) & 0xff -} - -func (f combinedFlags) ignore() bool { - return f&(combinedFlags(ignore)<<8) != 0 -} diff --git a/vendor/cuelang.org/go/internal/core/adt/disjunct.go b/vendor/cuelang.org/go/internal/core/adt/disjunct.go index 4da35fa6a2..72c2ca6a2f 100644 --- a/vendor/cuelang.org/go/internal/core/adt/disjunct.go +++ b/vendor/cuelang.org/go/internal/core/adt/disjunct.go @@ -15,8 +15,6 @@ package adt import ( - "slices" - "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" ) @@ -89,370 +87,10 @@ type envDisjunct struct { cloneID CloseInfo holeID int - // fields for new evaluator - + // TODO: src is set but never used. It seems like it should be used + // in either [nodeContext.crossProduct] or [nodeContext.collectErrors]? src Node disjuncts []disjunct - - // fields for old evaluator - - expr *DisjunctionExpr - value *Disjunction - hasDefaults bool - - // These are used for book keeping, tracking whether any of the - // disjuncts marked with a default marker remains after unification. - // If no default is used, all other elements are treated as "maybeDefault". - // Otherwise, elements are treated as is. - parentDefaultUsed bool - childDefaultUsed bool -} - -func (n *nodeContext) addDisjunction(env *Environment, x *DisjunctionExpr, cloneID CloseInfo) { - - // TODO: precompute - numDefaults := 0 - for _, v := range x.Values { - isDef := v.Default // || n.hasDefaults(env, v.Val) - if isDef { - numDefaults++ - } - } - - n.disjunctions = append(n.disjunctions, envDisjunct{ - env: env, - cloneID: cloneID, - expr: x, - hasDefaults: numDefaults > 0, - }) -} - -func (n *nodeContext) addDisjunctionValue(env *Environment, x *Disjunction, cloneID CloseInfo) { - n.disjunctions = append(n.disjunctions, envDisjunct{ - env: env, - cloneID: cloneID, - value: x, - hasDefaults: x.HasDefaults, - }) - -} - -func (n *nodeContext) expandDisjuncts( - state vertexStatus, - parent *nodeContext, - parentMode defaultMode, // default mode of this disjunct - recursive, last bool) { - - unreachableForDev(n.ctx) - - n.ctx.stats.Disjuncts++ - - // refNode is used to collect cyclicReferences for all disjuncts to be - // passed up to the parent node. Note that because the node in the parent - // context is overwritten in the course of expanding disjunction to retain - // pointer identity, it is not possible to simply record the refNodes in the - // parent directly. - var refNode *RefNode - - node := n.node - defer func() { - n.node = node - }() - - for n.expandOne(partial) { - } - - // save node to snapShot in nodeContex - // save nodeContext. - - if recursive || len(n.disjunctions) > 0 { - n.snapshot = clone(*n.node) - } else { - n.snapshot = *n.node - } - - defaultOffset := len(n.usedDefault) - - switch { - default: // len(n.disjunctions) == 0 - m := *n - n.postDisjunct(state) - - switch { - case n.hasErr(): - // TODO: consider finalizing the node thusly: - // if recursive { - // n.node.Finalize(n.ctx) - // } - x := n.node - err, ok := x.BaseValue.(*Bottom) - if !ok { - err = n.getErr() - } - if err == nil { - // TODO(disjuncts): Is this always correct? Especially for partial - // evaluation it is okay for child errors to have incomplete errors. - // Perhaps introduce an Err() method. - err = x.ChildErrors - } - if err != nil { - parent.disjunctErrs = append(parent.disjunctErrs, err) - } - if recursive { - n.free() - } - return - } - - if recursive { - *n = m - n.result = *n.node // XXX: n.result = snapshotVertex(n.node)? - n.node = &n.result - n.disjuncts = append(n.disjuncts, n) - } - if n.node.BaseValue == nil { - n.setBaseValue(n.getValidators(state)) - } - - n.usedDefault = append(n.usedDefault, defaultInfo{ - parentMode: parentMode, - nestedMode: parentMode, - origMode: parentMode, - }) - - case len(n.disjunctions) > 0: - // Process full disjuncts to ensure that erroneous disjuncts are - // eliminated as early as possible. - state = finalized - - n.disjuncts = append(n.disjuncts, n) - - n.refCount++ - defer n.free() - - for i, d := range n.disjunctions { - a := n.disjuncts - n.disjuncts = n.buffer[:0] - n.buffer = a[:0] - - last := i+1 == len(n.disjunctions) - skipNonMonotonicChecks := i+1 < len(n.disjunctions) - if skipNonMonotonicChecks { - n.ctx.inDisjunct++ - } - - for _, dn := range a { - switch { - case d.expr != nil: - for _, v := range d.expr.Values { - cn := dn.clone() - *cn.node = clone(dn.snapshot) - cn.node.state = cn - - c := MakeConjunct(d.env, v.Val, d.cloneID) - cn.addExprConjunct(c, state) - - newMode := mode(d.hasDefaults, v.Default) - - cn.expandDisjuncts(state, n, newMode, true, last) - - // Record the cyclicReferences of the conjunct in the - // parent list. - // TODO: avoid the copy. It should be okay to "steal" - // this list and avoid the copy. But this change is best - // done in a separate CL. - for r := n.node.cyclicReferences; r != nil; r = r.Next { - s := *r - s.Next = refNode - refNode = &s - } - } - - case d.value != nil: - for i, v := range d.value.Values { - cn := dn.clone() - *cn.node = clone(dn.snapshot) - cn.node.state = cn - - cn.addValueConjunct(d.env, v, d.cloneID) - - newMode := mode(d.hasDefaults, i < d.value.NumDefaults) - - cn.expandDisjuncts(state, n, newMode, true, last) - - // See comment above. - for r := n.node.cyclicReferences; r != nil; r = r.Next { - s := *r - s.Next = refNode - refNode = &s - } - } - } - } - - if skipNonMonotonicChecks { - n.ctx.inDisjunct-- - } - - if len(n.disjuncts) == 0 { - n.makeError() - } - - if recursive || i > 0 { - for _, x := range a { - x.free() - } - } - - if len(n.disjuncts) == 0 { - break - } - } - - // Annotate disjunctions with whether any of the default disjunctions - // was used. - for _, d := range n.disjuncts { - for i, info := range d.usedDefault[defaultOffset:] { - if info.parentMode == isDefault { - n.disjunctions[i].parentDefaultUsed = true - } - if info.origMode == isDefault { - n.disjunctions[i].childDefaultUsed = true - } - } - } - - // Combine parent and child default markers, considering that a parent - // "notDefault" is treated as "maybeDefault" if none of the disjuncts - // marked as default remain. - // - // NOTE for a parent marked as "notDefault", a child is *never* - // considered as default. It may either be "not" or "maybe" default. - // - // The result for each disjunction is conjoined into a single value. - for _, d := range n.disjuncts { - m := maybeDefault - orig := maybeDefault - for i, info := range d.usedDefault[defaultOffset:] { - parent := info.parentMode - - used := n.disjunctions[i].parentDefaultUsed - childUsed := n.disjunctions[i].childDefaultUsed - hasDefaults := n.disjunctions[i].hasDefaults - - orig = combineDefault(orig, info.parentMode) - orig = combineDefault(orig, info.nestedMode) - - switch { - case childUsed: - // One of the children used a default. This is "normal" - // mode. This may also happen when we are in - // hasDefaults/notUsed mode. Consider - // - // ("a" | "b") & (*(*"a" | string) | string) - // - // Here the doubly nested default is called twice, once - // for "a" and then for "b", where the second resolves to - // not using a default. The first does, however, and on that - // basis the "ot default marker cannot be overridden. - m = combineDefault(m, info.parentMode) - m = combineDefault(m, info.origMode) - - case !hasDefaults, used: - m = combineDefault(m, info.parentMode) - m = combineDefault(m, info.nestedMode) - - case hasDefaults && !used: - Assertf(n.ctx, parent == notDefault, "unexpected default mode") - } - } - d.defaultMode = m - - d.usedDefault = d.usedDefault[:defaultOffset] - d.usedDefault = append(d.usedDefault, defaultInfo{ - parentMode: parentMode, - nestedMode: m, - origMode: orig, - }) - - } - - // TODO: this is an old trick that seems no longer necessary for the new - // implementation. Keep around until we finalize the semantics for - // defaults, though. The recursion of nested defaults is not entirely - // proper yet. - // - // A better approach, that avoids the need for recursion (semantically), - // would be to only consider default usage for one level, but then to - // also allow a default to be passed if only one value is remaining. - // This means that a nested subsumption would first have to be evaluated - // in isolation, however, to determine that it is not previous - // disjunctions that cause the disambiguation. - // - // HACK alert: this replaces the hack of the previous algorithm with a - // slightly less worse hack: instead of dropping the default info when - // the value was scalar before, we drop this information when there is - // only one disjunct, while not discarding hard defaults. TODO: a more - // principled approach would be to recognize that there is only one - // default at a point where this does not break commutativity. - // if len(n.disjuncts) == 1 && n.disjuncts[0].defaultMode != isDefault { - // n.disjuncts[0].defaultMode = maybeDefault - // } - } - - // Compare to root, but add to this one. - switch p := parent; { - case p != n: - p.disjunctErrs = append(p.disjunctErrs, n.disjunctErrs...) - n.disjunctErrs = n.disjunctErrs[:0] - - outer: - for _, d := range n.disjuncts { - for k, v := range p.disjuncts { - // As long as a vertex isn't finalized, it may be that potential - // errors are not yet detected. This may lead two structs that - // are identical except for closedness information, - // for instance, to appear identical. - if v.result.status < finalized || d.result.status < finalized { - break - } - // Even if a node is finalized, it may still have an - // "incomplete" component that may change down the line. - if !d.done() || !v.done() { - break - } - flags := CheckStructural - if last { - flags |= IgnoreOptional - } - if Equal(n.ctx, &v.result, &d.result, flags) { - m := maybeDefault - for _, u := range d.usedDefault { - m = combineDefault(m, u.nestedMode) - } - if m == isDefault { - p.disjuncts[k] = d - v.free() - } else { - d.free() - } - continue outer - } - } - - p.disjuncts = append(p.disjuncts, d) - } - - n.disjuncts = n.disjuncts[:0] - } - - // Record the refNodes in the parent. - for r := refNode; r != nil; { - next := r.Next - r.Next = parent.node.cyclicReferences - parent.node.cyclicReferences = r - r = next - } } func (n *nodeContext) makeError() { @@ -488,46 +126,6 @@ func mode(hasDefault, marked bool) defaultMode { return mode } -// clone makes a shallow copy of a Vertex. The purpose is to create different -// disjuncts from the same Vertex under computation. This allows the conjuncts -// of an arc to be reset to a previous position and the reuse of earlier -// computations. -// -// Notes: only Arcs need to be copied recursively. Either the arc is finalized -// and can be used as is, or Structs is assumed to not yet be computed at the -// time that a clone is needed and must be nil. Conjuncts no longer needed and -// can become nil. All other fields can be copied shallowly. -func clone(v Vertex) Vertex { - v.state = nil - if a := v.Arcs; len(a) > 0 { - v.Arcs = make([]*Vertex, len(a)) - for i, arc := range a { - switch arc.status { - case finalized: - v.Arcs[i] = arc - - case unprocessed: - a := *arc - v.Arcs[i] = &a - a.Conjuncts = slices.Clone(arc.Conjuncts) - - default: - a := *arc - a.state = arc.state.clone() - a.state.node = &a - a.state.snapshot = clone(a) - v.Arcs[i] = &a - } - } - } - - if a := v.Structs; len(a) > 0 { - v.Structs = slices.Clone(a) - } - - return v -} - // Default rules from spec: // // U1: (v1, d1) & v2 => (v1&v2, d1&v2) @@ -551,7 +149,7 @@ func clone(v Vertex) Vertex { // not + maybe -> def // not + def -> def -type defaultMode int +type defaultMode uint8 const ( maybeDefault defaultMode = iota @@ -580,6 +178,12 @@ func (n *nodeContext) disjunctError() (errs errors.Error) { ctx := n.ctx disjuncts := selectErrors(n.disjunctErrs) + var pos errors.Error + + if len(n.userErrs) > 0 { + pos = disjuncts + disjuncts = selectErrors(n.userErrs) + } if disjuncts == nil { errs = ctx.Newf("empty disjunction") // XXX: add space to sort first @@ -587,16 +191,28 @@ func (n *nodeContext) disjunctError() (errs errors.Error) { disjuncts = errors.Sanitize(disjuncts) k := len(errors.Errors(disjuncts)) if k == 1 { + if pos != nil { + addDisjunctPositions(disjuncts.(*ValueError), pos) + } return disjuncts } // prefix '-' to sort to top errs = ctx.Newf("%d errors in empty disjunction:", k) + if pos != nil { + addDisjunctPositions(errs.(*ValueError), pos) + } errs = errors.Append(errs, disjuncts) } return errs } +func addDisjunctPositions(dst *ValueError, src errors.Error) { + for _, p := range src.InputPositions() { + dst.AddPos(p) + } +} + func selectErrors(a []*Bottom) (errs errors.Error) { // return all errors if less than a certain number. if len(a) <= 2 { diff --git a/vendor/cuelang.org/go/internal/core/adt/disjunct2.go b/vendor/cuelang.org/go/internal/core/adt/disjunct2.go index 955dc83613..94dd5a33ee 100644 --- a/vendor/cuelang.org/go/internal/core/adt/disjunct2.go +++ b/vendor/cuelang.org/go/internal/core/adt/disjunct2.go @@ -14,6 +14,13 @@ package adt +import ( + "math" + "slices" + + "cuelang.org/go/internal/core/layer" +) + // # Overview // // This files contains the disjunction algorithm of the CUE evaluator. It works @@ -199,18 +206,7 @@ type disjunct struct { expr Expr err *Bottom - isDefault bool - mode defaultMode -} - -// disjunctHole associates a closeContext copy representing a disjunct hole with -// the underlying closeContext from which it originally was branched. -// We could include this information in the closeContext itself, but since this -// is relatively rare, we keep it separate to avoid bloating the closeContext. -type disjunctHole struct { - cc *closeContext - holeID int - underlying *closeContext + mode defaultMode } func (n *nodeContext) scheduleDisjunction(d envDisjunct) { @@ -219,41 +215,22 @@ func (n *nodeContext) scheduleDisjunction(d envDisjunct) { n.scheduleTask(handleDisjunctions, nil, nil, CloseInfo{}) } - // ccHole is the closeContext in which the individual disjuncts are - // scheduled. - ccHole := d.cloneID.cc - - // This counter can be decremented after either a disjunct has been - // scheduled in the clone. Note that it will not be closed in the original - // as the result will either be an error, a single disjunct, in which - // case mergeVertex will override the original value, or multiple disjuncts, - // in which case the original is set to the disjunct itself. - ccHole.incDisjunct(n.ctx, DISJUNCT) - ccHole.holeID = d.holeID - n.disjunctions = append(n.disjunctions, d) - - n.disjunctCCs = append(n.disjunctCCs, disjunctHole{ - cc: ccHole, // this value is cloned in doDisjunct. - holeID: d.holeID, - underlying: ccHole, - }) + n.hasDisjunction = true } func initArcs(ctx *OpContext, v *Vertex) bool { - ok := true for _, a := range v.Arcs { s := a.getState(ctx) if s != nil && s.errs != nil { - ok = false if a.ArcType == ArcMember { - break + return false } } else if !initArcs(ctx, a) { - ok = false + return false } } - return ok + return true } func (n *nodeContext) processDisjunctions() *Bottom { @@ -269,41 +246,14 @@ func (n *nodeContext) processDisjunctions() *Bottom { // disjunction list length. }() - a := n.disjunctions - n.disjunctions = n.disjunctions[:0] - - holes := make([]disjunctHole, len(n.disjunctCCs)) - copy(holes, n.disjunctCCs) + // TODO(perf): check scalar errors so far to avoid unnecessary work. - // Upon completion, decrement the DISJUNCT counters that were incremented - // in scheduleDisjunction. Note that this disjunction may be a copy of the - // original, in which case we need to decrement the copied disjunctCCs, not - // the original. - // - // This is not strictly necessary, but it helps for balancing counters. - // TODO: Consider disabling this when DebugDeps is not set. - defer func() { - // We add a "top" value to disable closedness checking for this - // disjunction to avoid a spurious "field not allowed" error. - // We return the errors below, which will, in turn, be reported as - // the error. - for i, d := range a { - // TODO(perf: prove that holeIDs are always stored in increasing - // order and allow for an incremental search to reduce cost. - for _, h := range holes { - if h.holeID != a[i].holeID { - continue - } - cc := h.cc - id := a[i].cloneID - id.cc = cc - c := MakeConjunct(d.env, top, id) - n.scheduleConjunct(c, d.cloneID) - cc.decDisjunct(n.ctx, DISJUNCT) - break - } - } - }() + // TODO: during processing disjunctions, new disjunctions may be added. + // We copy the slice to prevent the original slice from being overwritten. + // TODO(perf): use some pre-existing buffer or use a persising position + // so that disjunctions can be processed incrementally. + a := slices.Clone(n.disjunctions) + n.disjunctions = n.disjunctions[:0] if !initArcs(n.ctx, n.node) { return n.getError() @@ -319,7 +269,11 @@ func (n *nodeContext) processDisjunctions() *Bottom { var outerRunMode runMode for p := n.node; p != nil; p = p.Parent { if p.IsDisjunct { - outerRunMode = p.state.runMode + if p.state == nil { + outerRunMode = finalize + } else { + outerRunMode = p.state.runMode + } break } } @@ -352,7 +306,7 @@ func (n *nodeContext) processDisjunctions() *Bottom { } // Mark no final in nodeContext and observe later. - results = n.crossProduct(results, cross, d, mode, d.holeID) + results = n.crossProduct(results, cross, d, mode) // TODO: do we unwind only at the end or also intermittently? switch len(results) { @@ -373,6 +327,12 @@ func (n *nodeContext) processDisjunctions() *Bottom { // this for now. } + if i > 0 { + for _, n := range cross { + n.freeDisjunct() + } + } + // switch up buffers. cross, results = results, cross[:0] } @@ -384,7 +344,22 @@ func (n *nodeContext) processDisjunctions() *Bottom { case 1: d := cross[0].node n.setBaseValue(d) - n.defaultMode = cross[0].defaultMode + if n.defaultMode == maybeDefault { + n.defaultMode = cross[0].defaultMode + } + if n.defaultAttemptInCycle != nil && n.defaultMode != isDefault { + c := n.ctx + path := c.PathToString(n.defaultAttemptInCycle.Path()) + + index := c.MarkPositions() + c.AddPosition(n.defaultAttemptInCycle) + err := c.Newf("ambiguous default elimination by referencing %v", path) + c.ReleasePositions(index) + + b := &Bottom{Code: CycleError, Err: err} + n.setBaseValue(b) + return b + } default: // append, rather than assign, to allow reusing the memory of @@ -412,9 +387,17 @@ func (n *nodeContext) processDisjunctions() *Bottom { // crossProduct computes the cross product of the disjuncts of a disjunction // with an existing set of results. -func (n *nodeContext) crossProduct(dst, cross []*nodeContext, dn *envDisjunct, mode runMode, hole int) []*nodeContext { +func (n *nodeContext) crossProduct(dst, cross []*nodeContext, dn *envDisjunct, mode runMode) []*nodeContext { + // TODO: do we still need this? removing it does not break any tests. defer n.unmarkDepth(n.markDepth()) - defer n.unmarkOptional(n.markOptional()) + + // TODO(perf): use a pre-allocated buffer in n.ctx. Note that the actual + // buffer may grow and has a max size of len(cross) * len(dn.disjuncts). + tmp := make([]*nodeContext, 0, len(cross)) + + leftDropsDefault := true + rightDropsDefault := true + priority, _ := pos(dn.src).Priority() for i, p := range cross { ID := n.nextCrossProduct(i, len(cross), p) @@ -427,42 +410,106 @@ func (n *nodeContext) crossProduct(dst, cross []*nodeContext, dn *envDisjunct, m ID.node.nextDisjunct(j, len(dn.disjuncts), d.expr) c := MakeConjunct(dn.env, d.expr, dn.cloneID) - r, err := p.doDisjunct(c, d.mode, mode, hole) + r, err := p.doDisjunct(c, d.mode, mode, n.node) if err != nil { + if err.Code == UserError { + n.userErrs = append(n.userErrs, err) + } // TODO: store more error context dn.disjuncts[j].err = err continue } - // Unroll nested disjunctions. - switch len(r.disjuncts) { - case 0: - // r did not have a nested disjunction. - dst = appendDisjunct(n.ctx, dst, r) + // Promote the priority of defaults. + r.origPriority = priority + r.priority = p.origPriority + if p.defaultMode == isDefault && p.origPriority > priority { + r.origPriority = priority + } + + tmp = append(tmp, r) + if p.defaultMode == isDefault || p.origDefaultMode == isDefault { + leftDropsDefault = false + } + if d.mode == isDefault { + rightDropsDefault = false + } + } + } + + hasNonMaybe := false + for _, r := range tmp { + // Unroll nested disjunctions. + switch len(r.disjuncts) { + case 0: + // If a default is not dropped in a higher priority, allow still to + // become a default, even if other other side has dropped defaults. + if !rightDropsDefault && r.origDefaultMode == notDefault && + priority < r.priority { + r.origDefaultMode = maybeDefault + } + if !leftDropsDefault && r.defaultMode == notDefault && + priority > r.priority { + r.defaultMode = maybeDefault + } - case 1: - panic("unexpected number of disjuncts") + r.defaultMode = combineDefault2(r.defaultMode, r.origDefaultMode, leftDropsDefault, rightDropsDefault) + // r did not have a nested disjunction. + dst = appendDisjunct(n.ctx, dst, r) - default: - for _, x := range r.disjuncts { - dst = appendDisjunct(n.ctx, dst, x) + case 1: + panic("unexpected number of disjuncts") + + default: + for _, x := range r.disjuncts { + m := combineDefault(r.origDefaultMode, x.defaultMode) + + // TODO(defaults): using rightHasDefault instead of false here + // is not according to the spec, but may result in better user + // ergononmics. See Issue #1304. + x.defaultMode = combineDefault2(r.defaultMode, m, leftDropsDefault, false) + if x.defaultMode != maybeDefault { + hasNonMaybe = true } + dst = appendDisjunct(n.ctx, dst, x) } } } + + if hasNonMaybe { + for _, r := range dst { + if r.defaultMode == maybeDefault { + r.defaultMode = notDefault + } + } + } + return dst } +func combineDefault2(a, b defaultMode, dropsDefaultA, dropsDefaultB bool) defaultMode { + if dropsDefaultA { + a = maybeDefault + } + if dropsDefaultB { + b = maybeDefault + } + return combineDefault(a, b) +} + // collectErrors collects errors from a failed disjunctions. func (n *nodeContext) collectErrors(dn *envDisjunct) (errs *Bottom) { code := EvalError for _, d := range dn.disjuncts { if b := d.err; b != nil { - n.disjunctErrs = append(n.disjunctErrs, b) + if b.Code == UserError { + continue + } if b.Code > code { code = b.Code } + n.disjunctErrs = append(n.disjunctErrs, b) } } @@ -474,57 +521,54 @@ func (n *nodeContext) collectErrors(dn *envDisjunct) (errs *Bottom) { return b } -func (n *nodeContext) doDisjunct(c Conjunct, m defaultMode, mode runMode, hole int) (*nodeContext, *Bottom) { - if c.CloseInfo.cc == nil { - panic("nil closeContext during init") - } - +// doDisjunct computes a single disjunct. n is the current disjunct that is +// augmented, whereas orig is the original node where disjunction processing +// started. orig is used to clean up Environments. +func (n *nodeContext) doDisjunct(c Conjunct, m defaultMode, mode runMode, orig *Vertex) (*nodeContext, *Bottom) { ID := n.logDoDisjunct() _ = ID // Do not remove, used for debugging. oc := newOverlayContext(n.ctx) - var ccHole *closeContext - - // TODO(perf): resuse buffer, for instance by keeping a buffer handy in oc - // and then swapping it with disjunctCCs in the new nodeContext. - holes := make([]disjunctHole, 0, len(n.disjunctCCs)) - // Complete as much of the pending work of this node and its parent before // copying. Note that once a copy is made, the disjunct is no longer able // to receive conjuncts from the original. n.completeNodeTasks(mode) + // TODO: we may need to process incoming notifications for all arcs in // the copied disjunct, but only those notifications not coming from // within the arc itself. - // Clone the closeContexts of all open disjunctions and dependencies. - for _, d := range n.disjunctCCs { - // TODO: remove filled holes. - - // Note that the root is already cloned as part of cloneVertex and that - // a closeContext corresponding to a disjunction always has a parent. - // We therefore do not need to check whether x.parent is nil. - o := oc.allocCC(d.cc) - if hole == d.holeID { - ccHole = o - if d.cc.conjunctCount == 0 { - panic("unexpected zero conjunctCount") - } - } - holes = append(holes, disjunctHole{o, d.holeID, d.underlying}) + n.scheduler.blocking = n.scheduler.blocking[:0] + + // TODO(perf): do not set to nil, but rather maintain an index to unwind + // to avoid allocting new arrays. + // TODO: ideally, we move unresolved tasks to the original vertex for + // disambiguated disjuncts. + saved := n.ctx.blocking + n.ctx.blocking = nil + defer func() { n.ctx.blocking = saved }() + + // We forward the original base value to the disjunct. This allows for + // lookups with the disjunct to the original value. + var savedBase BaseValue + if !orig.IsDisjunct { + savedBase = orig.BaseValue + defer func() { orig.BaseValue = savedBase }() } - if ccHole == nil { - panic("expected non-nil overlay closeContext") + d := oc.cloneRoot(n) + + // This mechanism only works if the original is not a disjunct. + if !orig.IsDisjunct { + orig.BaseValue = d.node } - n.scheduler.blocking = n.scheduler.blocking[:0] + n.ctx.pushOverlay(n.node, oc.vertexMap) + defer n.ctx.popOverlay() - d := oc.cloneRoot(n) d.runMode = mode - - d.defaultMode = combineDefault(m, n.defaultMode) + c.Env = oc.derefDisjunctsEnv(c.Env) v := d.node @@ -536,23 +580,25 @@ func (n *nodeContext) doDisjunct(c Conjunct, m defaultMode, mode runMode, hole i // a special mode, or evaluating more aggressively if finalize is not given. v.status = unprocessed - d.overlays = n - d.disjunctCCs = append(d.disjunctCCs, holes...) - d.disjunct = c - c.CloseInfo.cc = ccHole + if m == isDefault { + c.CloseInfo.Priority, _ = pos(c.x).Priority() + } d.scheduleConjunct(c, c.CloseInfo) - ccHole.decDisjunct(n.ctx, DISJUNCT) oc.unlinkOverlay() - v.unify(n.ctx, allKnown, mode) + d.defaultMode = n.defaultMode + d.origDefaultMode = m + + v.unify(n.ctx, Flags{condition: allKnown, mode: mode, checkTypos: true}) if err := d.getErrorAll(); err != nil && !isCyclePlaceholder(err) { - d.free() + d.freeDisjunct() return nil, err } - d = d.node.DerefDisjunct().state + d.node.DerefDisjunct().state.origDefaultMode = d.origDefaultMode + d = d.node.DerefDisjunct().state // TODO: maybe do not unroll at all. return d, nil } @@ -566,21 +612,52 @@ func (n *nodeContext) finalizeDisjunctions() { // This is especially relevant for the API. Ideally, though, we should // update Conjuncts to reflect the actual conjunct that went into the // disjuncts. + numErrs := 0 for _, x := range n.disjuncts { x.node.Conjuncts = nil + + if b := x.getErr(); b != nil { + if b.Code == UserError { + n.userErrs = append(n.userErrs, b) + } else { + n.disjunctErrs = append(n.disjunctErrs, b) + } + numErrs++ + continue + } + } + + if len(n.disjuncts) == numErrs { + n.makeError() + return + } + + // Determine highest priority and if the default exists. + hasDefaults := false + defaultPriority := layer.Priority(math.MinInt8) + for _, x := range n.disjuncts { + if x.defaultMode == isDefault { + hasDefaults = true + if x.origPriority > defaultPriority { + defaultPriority = x.origPriority + } + } } a := make([]Value, len(n.disjuncts)) p := 0 - hasDefaults := false for i, x := range n.disjuncts { + if x.origPriority < defaultPriority && x.defaultMode != isDefault { + x.defaultMode = notDefault + } + switch x.defaultMode { case isDefault: - a[i] = a[p] - a[p] = x.node - p++ - hasDefaults = true - + if x.origPriority == defaultPriority { + a[i] = a[p] + a[p] = x.node + p++ + } case notDefault: hasDefaults = true fallthrough @@ -596,11 +673,25 @@ func (n *nodeContext) finalizeDisjunctions() { } v := n.node - n.setBaseValue(d) + + if n.defaultAttemptInCycle == nil || d.NumDefaults == 1 { + n.setBaseValue(d) + } else { + c := n.ctx + path := c.PathToString(n.defaultAttemptInCycle.Path()) + + index := c.MarkPositions() + c.AddPosition(n.defaultAttemptInCycle) + err := c.Newf("cycle across unresolved disjunction referenced by %v", path) + c.ReleasePositions(index) + + b := &Bottom{Code: CycleError, Err: err} + n.setBaseValue(b) + } // The conjuncts will have too much information. Better have no // information than incorrect information. - v.Arcs = nil + v.clearArcs(n.ctx) v.ChildErrors = nil } @@ -656,28 +747,17 @@ func appendDisjunct(ctx *OpContext, a []*nodeContext, x *nodeContext) []*nodeCon // (overlayed) closeContexts are identical. outer: for _, xn := range a { + // TODO: for some reason, r may already have been added to dst in some + // cases, so we need to check for this. + if xn == x { + return a + } xv := xn.node.DerefValue() if xv.status != finalized || nv.status != finalized { // Partial node - // TODO: we could consider supporting an option here to disable - // the filter. This way, if there is a bug, users could disable - // it, trading correctness for performance. - // If enabled, we would simply "continue" here. - - for i, h := range xn.disjunctCCs { - // TODO(perf): only iterate over completed - // TODO(evalv3): we now have a double loop to match the - // disjunction holes. It should be possible to keep them - // aligned and avoid the inner loop. - for _, g := range x.disjunctCCs { - if h.underlying == g.underlying { - x, y := findIntersections(h.cc, x.disjunctCCs[i].cc) - if !equalPartialNode(xn.ctx, x, y) { - continue outer - } - } - } + if !equalPartialNode(xn.ctx, x.node, xn.node) { + continue outer } if len(xn.tasks) != xn.taskPos || len(x.tasks) != x.taskPos { if len(xn.tasks) != len(x.tasks) { @@ -686,7 +766,7 @@ outer: } for i, t := range xn.tasks[xn.taskPos:] { s := x.tasks[i] - if s.x != t.x || s.id.cc != t.id.cc { + if s.x != t.x { continue outer } } @@ -711,48 +791,21 @@ outer: if x.defaultMode == isDefault { xn.defaultMode = isDefault } - // TODO: x.free() + mergeCloseInfo(xn, x) + x.freeDisjunct() return a } return append(a, x) } -// findIntersections reports the closeContext, relative to the two given -// disjunction holes, that should be used in comparing the arc set. -// x and y MUST both be originating from the same disjunct hole. This ensures -// that the depth of the parent chain is the same and that they have the -// same underlying closeContext. -// -// Currently, we just take the parent. We should investigate if that is always -// sufficient. -// -// Tradeoffs: if we do not go up enough, the two nodes may not be equal and we -// miss the opportunity to filter. On the other hand, if we go up too far, we -// end up comparing more arcs than potentially necessary. -// -// TODO: Add a unit test when this function is fully implemented. -func findIntersections(x, y *closeContext) (cx, cy *closeContext) { - cx = x.parent - cy = y.parent - - // TODO: why could this happen? Investigate. Note that it is okay to just - // return x and y. In the worst case we will just miss some possible - // deduplication. - if cx == nil || cy == nil { - return x, y - } - - return cx, cy -} - -func equalPartialNode(ctx *OpContext, x, y *closeContext) bool { - nx := x.src.getState(ctx) - ny := y.src.getState(ctx) +func equalPartialNode(ctx *OpContext, x, y *Vertex) bool { + nx := x.state + ny := y.state if nx == nil && ny == nil { // Both nodes were finalized. We can compare them directly. - return Equal(ctx, x.src, y.src, CheckStructural) + return Equal(ctx, x, y, CheckStructural) } // TODO: process the nodes with allKnown, attemptOnly. @@ -765,32 +818,35 @@ func equalPartialNode(ctx *OpContext, x, y *closeContext) bool { return false } - if len(x.Patterns) != len(y.Patterns) { + switch cx, cy := x.PatternConstraints, y.PatternConstraints; { + case cx == nil && cy == nil: + case cx == nil || cy == nil: return false - } - // Assume patterns are in the same order. - for i, p := range x.Patterns { - if !Equal(ctx, p, y.Patterns[i], 0) { - return false - } - } - - if !Equal(ctx, x.Expr, y.Expr, 0) { + case len(cx.Pairs) != len(cy.Pairs): return false + default: + // Assume patterns are in the same order. + for i, p := range cx.Pairs { + p.Constraint.Finalize(ctx) + cy.Pairs[i].Constraint.Finalize(ctx) + if !Equal(ctx, p.Constraint, cy.Pairs[i].Constraint, CheckStructural) { + return false + } + } } - if len(x.arcs) != len(y.arcs) { + if len(x.Arcs) != len(y.Arcs) { return false } // TODO(perf): use merge sort outer: - for _, a := range x.arcs { - for _, b := range y.arcs { - if a.root.src.Label != b.root.src.Label { + for _, a := range x.Arcs { + for _, b := range y.Arcs { + if a.Label != b.Label { continue } - if !equalPartialNode(ctx, a.dst, b.dst) { + if !equalPartialNode(ctx, a, b) { return false } continue outer @@ -863,12 +919,6 @@ func isEqualNodeValue(x, y *nodeContext) bool { if s.x != t.x { return false } - if s.id.cc != t.id.cc { - // FIXME: we should compare this too. For this to work we need to - // have access to the underlying closeContext, which we do not - // have at the moment. - // return false - } } return true @@ -891,3 +941,32 @@ func isEqualValue[P ComparableValue](ctx *OpContext, x, y P) bool { return Equal(ctx, x, y, CheckStructural) } + +// IsFromDisjunction reports whether any conjunct of v was a disjunction. +// There are three cases: +// 1. v is a disjunction itself. This happens when the result is an +// unresolved disjunction. +// 2. v is a disjunct. This happens when only a single disjunct remains. In this +// case there will be a forwarded node that is marked with IsDisjunct. +// 3. the disjunction was erroneous and none of the disjuncts failed. +// +// TODO(evalv3): one case that is not covered by this is erroneous disjunctions. +// This is not the worst, but fixing it may lead to better error messages. +func (v *Vertex) IsFromDisjunction() bool { + _, ok := v.BaseValue.(*Disjunction) + return ok || v.isDisjunct() +} + +// TODO: export this instead of IsDisjunct +func (v *Vertex) isDisjunct() bool { + for { + if v.IsDisjunct { + return true + } + arc, ok := v.BaseValue.(*Vertex) + if !ok { + return false + } + v = arc + } +} diff --git a/vendor/cuelang.org/go/internal/core/adt/equality.go b/vendor/cuelang.org/go/internal/core/adt/equality.go index e808f17989..20fc337f95 100644 --- a/vendor/cuelang.org/go/internal/core/adt/equality.go +++ b/vendor/cuelang.org/go/internal/core/adt/equality.go @@ -32,6 +32,10 @@ const ( ) func Equal(ctx *OpContext, v, w Value, flags Flag) bool { + if flags&CheckStructural == 0 { + v = Default(v) + w = Default(w) + } if x, ok := v.(*Vertex); ok { return equalVertex(ctx, x, w, flags) } @@ -71,7 +75,7 @@ func equalVertex(ctx *OpContext, x *Vertex, v Value, flags Flag) bool { return false } - maxArcType := ArcMember + maxArcType := ArcRequired if flags&CheckStructural != 0 { // Do not ignore optional fields // TODO(required): consider making this unconditional @@ -79,16 +83,13 @@ func equalVertex(ctx *OpContext, x *Vertex, v Value, flags Flag) bool { } // TODO: this really should be subsumption. - if flags != 0 { + if flags&CheckStructural != 0 { if x.IsClosedStruct() != y.IsClosedStruct() { return false } if x.IsClosedList() != y.IsClosedList() { return false } - if !equalClosed(ctx, x, y, flags) { - return false - } } skipRegular := flags&RegularOnly != 0 @@ -137,40 +138,6 @@ loop2: return equalTerminal(ctx, v, w, flags) } -// equalClosed tests if x and y have the same set of close information. -// TODO: the following refinements are possible: -// - unify optional fields and equate the optional fields -// - do the same for pattern constraints, where the pattern constraints -// are collated by pattern equality. -// - a further refinement would collate patterns by ranges. -// -// For all these refinements it would be necessary to have well-working -// structure sharing so as to not repeatedly recompute optional arcs. -func equalClosed(ctx *OpContext, x, y *Vertex, flags Flag) bool { - return verifyStructs(x, y, flags) && verifyStructs(y, x, flags) -} - -func verifyStructs(x, y *Vertex, flags Flag) bool { -outer: - for _, s := range x.Structs { - if (flags&IgnoreOptional != 0) && !s.StructLit.HasOptional() { - continue - } - if s.span()&DefinitionSpan == 0 { - if !s.StructLit.HasOptional() { - continue - } - } - for _, t := range y.Structs { - if s.StructLit == t.StructLit { - continue outer - } - } - return false - } - return true -} - func equalTerminal(ctx *OpContext, v, w Value, flags Flag) bool { if v == w { return true @@ -187,7 +154,7 @@ func equalTerminal(ctx *OpContext, v, w Value, flags Flag) bool { return ok case *Num, *String, *Bool, *Bytes, *Null: - if b, ok := BinOp(ctx, EqualOp, v, w).(*Bool); ok { + if b, ok := BinOp(ctx, errOnDiffType, EqualOp, v, w).(*Bool); ok { return b.B } return false diff --git a/vendor/cuelang.org/go/internal/core/adt/errorcode_string.go b/vendor/cuelang.org/go/internal/core/adt/errorcode_string.go index bb1e0da5d9..29030e64a4 100644 --- a/vendor/cuelang.org/go/internal/core/adt/errorcode_string.go +++ b/vendor/cuelang.org/go/internal/core/adt/errorcode_string.go @@ -10,18 +10,20 @@ func _() { var x [1]struct{} _ = x[EvalError-0] _ = x[UserError-1] - _ = x[StructuralCycleError-2] - _ = x[IncompleteError-3] - _ = x[CycleError-4] + _ = x[LegacyUserError-2] + _ = x[StructuralCycleError-3] + _ = x[IncompleteError-4] + _ = x[CycleError-5] } -const _ErrorCode_name = "evaluserstructural cycleincompletecycle" +const _ErrorCode_name = "evaluseruserstructural cycleincompletecycle" -var _ErrorCode_index = [...]uint8{0, 4, 8, 24, 34, 39} +var _ErrorCode_index = [...]uint8{0, 4, 8, 12, 28, 38, 43} func (i ErrorCode) String() string { - if i < 0 || i >= ErrorCode(len(_ErrorCode_index)-1) { + idx := int(i) - 0 + if i < 0 || idx >= len(_ErrorCode_index)-1 { return "ErrorCode(" + strconv.FormatInt(int64(i), 10) + ")" } - return _ErrorCode_name[_ErrorCode_index[i]:_ErrorCode_index[i+1]] + return _ErrorCode_name[_ErrorCode_index[idx]:_ErrorCode_index[idx+1]] } diff --git a/vendor/cuelang.org/go/internal/core/adt/errors.go b/vendor/cuelang.org/go/internal/core/adt/errors.go index 40f5bdccfc..df8138e957 100644 --- a/vendor/cuelang.org/go/internal/core/adt/errors.go +++ b/vendor/cuelang.org/go/internal/core/adt/errors.go @@ -32,25 +32,33 @@ package adt // import ( + "slices" + "cuelang.org/go/cue/ast" "cuelang.org/go/cue/errors" cueformat "cuelang.org/go/cue/format" "cuelang.org/go/cue/token" + "cuelang.org/go/internal/iterutil" ) // ErrorCode indicates the type of error. The type of error may influence // control flow. No other aspects of an error may influence control flow. type ErrorCode int8 -//go:generate go run golang.org/x/tools/cmd/stringer -type=ErrorCode -linecomment +//go:generate go tool stringer -type=ErrorCode -linecomment const ( // An EvalError is a fatal evaluation error. EvalError ErrorCode = iota // eval - // A UserError is a fatal error originating from the user. + // A UserError is a fatal error originating from the user using the error + // builtin. UserError // user + // A LegacyUserError is a fatal error originating from the user using the + // _|_ token, which we intend to phase out. + LegacyUserError // user + // StructuralCycleError means a structural cycle was found. Structural // cycles are permanent errors, but they are not passed up recursively, // as a unification of a value with a structural cycle with one that @@ -83,6 +91,7 @@ type Bottom struct { HasRecursive bool ChildError bool // Err is the error of the child NotExists bool // This error originated from a failed lookup. + CloseCheck bool // This error resulted from a close check. ForCycle bool // this is a for cycle // Value holds the computed value so far in case Value Value @@ -93,9 +102,8 @@ type Bottom struct { Node *Vertex } -func (x *Bottom) Source() ast.Node { return x.Src } -func (x *Bottom) Kind() Kind { return BottomKind } -func (x *Bottom) Specialize(k Kind) Value { return x } // XXX remove +func (x *Bottom) Source() ast.Node { return x.Src } +func (x *Bottom) Kind() Kind { return BottomKind } func (b *Bottom) IsIncomplete() bool { if b == nil { @@ -107,7 +115,7 @@ func (b *Bottom) IsIncomplete() bool { // isLiteralBottom reports whether x is an error originating from a user. func isLiteralBottom(x Expr) bool { b, ok := x.(*Bottom) - return ok && b.Code == UserError + return ok && b.Code == LegacyUserError } // isError reports whether v is an error or nil. @@ -144,12 +152,13 @@ func (n *nodeContext) AddChildError(recursive *Bottom) { } x := v.BaseValue err, _ := x.(*Bottom) - if err == nil { + if err == nil || err.CloseCheck { n.setBaseValue(&Bottom{ Code: recursive.Code, Value: v, HasRecursive: true, ChildError: true, + CloseCheck: recursive.CloseCheck, Err: recursive.Err, Node: n.node, }) @@ -198,13 +207,14 @@ func CombineErrors(src ast.Node, x, y Value) *Bottom { } return &Bottom{ - Src: src, - Err: errors.Append(a.Err, b.Err), - Code: a.Code, + Src: src, + Err: errors.Append(a.Err, b.Err), + Code: a.Code, + CloseCheck: a.CloseCheck || b.CloseCheck, } } -func addPositions(err *ValueError, c Conjunct) { +func addPositions(ctx *OpContext, err *ValueError, c Conjunct) { switch x := c.x.(type) { case *Field: // if x.ArcType == ArcRequired { @@ -212,26 +222,28 @@ func addPositions(err *ValueError, c Conjunct) { // } case *ConjunctGroup: for _, c := range *x { - addPositions(err, c) + addPositions(ctx, err, c) } } - if c.CloseInfo.closeInfo != nil { - err.AddPosition(c.CloseInfo.location) + if p := c.CloseInfo.Location(ctx); p != nil { + err.AddPosition(p) } } -func NewRequiredNotPresentError(ctx *OpContext, v *Vertex) *Bottom { +func NewRequiredNotPresentError(ctx *OpContext, v *Vertex, morePositions ...Node) *Bottom { saved := ctx.PushArc(v) err := ctx.Newf("field is required but not present") - v.VisitLeafConjuncts(func(c Conjunct) bool { + for _, p := range morePositions { + err.AddPosition(p) + } + for c := range v.LeafConjuncts() { if f, ok := c.x.(*Field); ok && f.ArcType == ArcRequired { err.AddPosition(c.x) } - if c.CloseInfo.closeInfo != nil { - err.AddPosition(c.CloseInfo.location) + if p := c.CloseInfo.Location(ctx); p != nil { + err.AddPosition(p) } - return true - }) + } b := &Bottom{ Code: IncompleteError, @@ -245,10 +257,9 @@ func NewRequiredNotPresentError(ctx *OpContext, v *Vertex) *Bottom { func newRequiredFieldInComprehensionError(ctx *OpContext, x *ForClause, v *Vertex) *Bottom { err := ctx.Newf("missing required field in for comprehension: %v", v.Label) err.AddPosition(x.Src) - v.VisitLeafConjuncts(func(c Conjunct) bool { - addPositions(err, c) - return true - }) + for c := range v.LeafConjuncts() { + addPositions(ctx, err, c) + } return &Bottom{ Code: IncompleteError, Err: err, @@ -269,7 +280,10 @@ func (v *Vertex) reportFieldCycleError(c *OpContext, pos token.Pos, f Feature) * func (v *Vertex) reportFieldError(c *OpContext, pos token.Pos, f Feature, intMsg, stringMsg string) *Bottom { code := IncompleteError - if !v.Accept(c, f) { + // If v is an error, we need to adopt the worst error. + if b := v.Bottom(); b != nil && !isCyclePlaceholder(b) { + code = b.Code + } else if !v.Accept(c, f) { code = EvalError } @@ -277,7 +291,7 @@ func (v *Vertex) reportFieldError(c *OpContext, pos token.Pos, f Feature, intMsg var err errors.Error if f.IsInt() { - err = c.NewPosf(pos, intMsg, f.Index(), len(v.Elems())) + err = c.NewPosf(pos, intMsg, f.Index(), iterutil.Count(v.Elems())) } else { err = c.NewPosf(pos, stringMsg, label) } @@ -293,10 +307,11 @@ func (v *Vertex) reportFieldError(c *OpContext, pos token.Pos, f Feature, intMsg // A ValueError is returned as a result of evaluating a value. type ValueError struct { - r Runtime - v *Vertex - pos token.Pos - auxpos []token.Pos + r Runtime + v *Vertex + pos token.Pos + auxpos []token.Pos + altPath []string errors.Message } @@ -304,21 +319,21 @@ func (v *ValueError) AddPosition(n Node) { if n == nil { return } - if p := pos(n); p != token.NoPos { - for _, q := range v.auxpos { - if p == q { - return - } + v.AddPos(pos(n)) +} + +func (v *ValueError) AddPos(p token.Pos) { + if p != token.NoPos { + if slices.Contains(v.auxpos, p) { + return } v.auxpos = append(v.auxpos, p) } } -func (v *ValueError) AddClosedPositions(c CloseInfo) { - for s := c.closeInfo; s != nil; s = s.parent { - if loc := s.location; loc != nil { - v.AddPosition(loc) - } +func (v *ValueError) AddClosedPositions(ctx *OpContext, c CloseInfo) { + for n := range c.AncestorPositions(ctx) { + v.AddPosition(n) } } @@ -351,10 +366,9 @@ func appendNodePositions(a []token.Pos, n Node) []token.Pos { a = append(a, p) } if v, ok := n.(*Vertex); ok { - v.VisitLeafConjuncts(func(c Conjunct) bool { + for c := range v.LeafConjuncts() { a = appendNodePositions(a, c.Elem()) - return true - }) + } } return a } @@ -371,6 +385,21 @@ func (c *OpContext) NewPosf(p token.Pos, format string, args ...interface{}) *Va switch x := arg.(type) { case Node: a = appendNodePositions(a, x) + // Wrap nodes in a [fmt.Stringer] which delays the call to + // [OpContext.Str] until the error needs to be rendered. + // This helps avoid work, as in many cases, + // errors are created but never shown to the user. + // + // A Vertex will set an error as its BaseValue via a Bottom node, + // which might be this error we are creating. + // Using the Vertex directly could then lead to endless recursion. + // Make a shallow copy to avoid that. + if v, ok := x.(*Vertex); ok { + // TODO(perf): we could join this allocation with the creation + // of the stringer below. + vcopy := *v + x = &vcopy + } args[i] = c.Str(x) case ast.Node: // TODO: ideally the core evaluator should not depend on higher @@ -385,15 +414,33 @@ func (c *OpContext) NewPosf(p token.Pos, format string, args ...interface{}) *Va args[i] = x.SelectorString(c.Runtime) } } + return &ValueError{ r: c.Runtime, v: c.errNode(), pos: p, auxpos: a, + altPath: c.makeAltPath(), Message: errors.NewMessagef(format, args...), } } +func (c *OpContext) makeAltPath() (a []string) { + if len(c.altPath) == 0 { + return nil + } + + for _, f := range appendPath(nil, c.altPath[0]) { + a = append(a, f.SelectorString(c)) + } + for _, v := range c.altPath[1:] { + if f := v.Label; f != 0 { + a = append(a, f.SelectorString(c)) + } + } + return a +} + func (e *ValueError) Error() string { return errors.String(e) } @@ -407,6 +454,9 @@ func (e *ValueError) InputPositions() (a []token.Pos) { } func (e *ValueError) Path() (a []string) { + if len(e.altPath) > 0 { + return e.altPath + } if e.v == nil { return nil } diff --git a/vendor/cuelang.org/go/internal/core/adt/eval.go b/vendor/cuelang.org/go/internal/core/adt/eval.go index a0f21332c5..9ecd66551f 100644 --- a/vendor/cuelang.org/go/internal/core/adt/eval.go +++ b/vendor/cuelang.org/go/internal/core/adt/eval.go @@ -12,11 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package eval contains the high level CUE evaluation strategy. -// -// CUE allows for a significant amount of freedom in order of evaluation due to -// the commutativity of the unification operation. This package implements one -// of the possible strategies. package adt // TODO: @@ -25,12 +20,10 @@ package adt // import ( - "fmt" - - "cuelang.org/go/cue/ast" "cuelang.org/go/cue/errors" "cuelang.org/go/cue/stats" "cuelang.org/go/cue/token" + "cuelang.org/go/internal/core/layer" ) // TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO @@ -54,11 +47,6 @@ func (c *OpContext) Stats() *stats.Counts { // return e.NewContext(v) // } -var incompleteSentinel = &Bottom{ - Code: IncompleteError, - Err: errors.Newf(token.NoPos, "incomplete"), -} - // evaluate returns the evaluated value associated with v. It may return a // partial result. That is, if v was not yet unified, it may return a // concrete value that must be the result assuming the configuration has no @@ -71,7 +59,7 @@ var incompleteSentinel = &Bottom{ // error. // // TODO: return *Vertex -func (c *OpContext) evaluate(v *Vertex, r Resolver, state combinedFlags) Value { +func (c *OpContext) evaluate(v *Vertex, r Resolver, state Flags) Value { if v.isUndefined() { // Use node itself to allow for cycle detection. c.unify(v, state) @@ -135,17 +123,6 @@ func (c *OpContext) evaluate(v *Vertex, r Resolver, state combinedFlags) Value { return nil } - if v.status < finalized && v.state != nil && !c.isDevVersion() { - // TODO: errors are slightly better if we always add addNotify, but - // in this case it is less likely to cause a performance penalty. - // See https://cuelang.org/issue/661. It may be possible to - // relax this again once we have proper tests to prevent regressions of - // that issue. - if !v.state.done() || v.state.errs != nil { - v.state.addNotify(c.vertex, nil) - } - } - return v } @@ -154,447 +131,8 @@ func (c *OpContext) evaluate(v *Vertex, r Resolver, state combinedFlags) Value { // state can be used to indicate to which extent processing should continue. // state == finalized means it is evaluated to completion. See vertexStatus // for more details. -func (c *OpContext) unify(v *Vertex, flags combinedFlags) { - if c.isDevVersion() { - requires, mode := flags.conditions(), flags.runMode() - v.unify(c, requires, mode) - return - } - - // defer c.PopVertex(c.PushVertex(v)) - if c.LogEval > 0 { - c.nest++ - c.Logf(v, "Unify") - defer func() { - c.Logf(v, "END Unify") - c.nest-- - }() - } - - // Ensure a node will always have a nodeContext after calling Unify if it is - // not yet Finalized. - n := v.getNodeContext(c, 1) - defer v.freeNode(n) - - state := flags.vertexStatus() - - // TODO(cycle): verify this happens in all cases when we need it. - if n != nil && v.Parent != nil && v.Parent.state != nil { - n.depth = v.Parent.state.depth + 1 - } - - if state <= v.Status() && - state == partial && - v.isDefined() && - n != nil && n.scalar != nil { - return - } - - switch v.Status() { - case evaluating: - n.insertConjuncts(state) - return - - case evaluatingArcs: - Assertf(c, v.status > unprocessed, "unexpected status %d", v.status) - return - - case 0: - if v.Label.IsDef() { - v.ClosedRecursive = true - } - - if v.Parent != nil { - if v.Parent.ClosedRecursive { - v.ClosedRecursive = true - } - } - - defer c.PopArc(c.PushArc(v)) - - v.updateStatus(evaluating) - - if p := v.Parent; p != nil && p.state != nil && v.Label.IsString() { - for _, s := range p.state.node.Structs { - if s.Disable { - continue - } - s.MatchAndInsert(n.ctx, v) - } - } - - c.stats.Unifications++ - - // Set the cache to a cycle error to ensure a cyclic reference will result - // in an error if applicable. A cyclic error may be ignored for - // non-expression references. The cycle error may also be removed as soon - // as there is evidence what a correct value must be, but before all - // validation has taken place. - // - // TODO(cycle): having a more recursive algorithm would make this - // special cycle handling unnecessary. - v.BaseValue = cycle - - if c.HasErr() { - n.addBottom(c.errs) - } - - // NOTE: safeguard against accidentally entering the 'unprocessed' state - // twice. - n.conjuncts = n.conjuncts[:0] - - for i, c := range v.Conjuncts { - n.addConjunction(c, i) - } - if n.insertConjuncts(state) { - n.maybeSetCache() - v.updateStatus(partial) - return - } - - fallthrough - - case partial, conjuncts: - // TODO: remove this optimization or make it correct. - // No need to do further processing when we have errors and all values - // have been considered. - // TODO: is checkClosed really still necessary here? - if v.status == conjuncts && (n.hasErr() || !n.checkClosed(state)) { - if err := n.getErr(); err != nil { - b, _ := v.BaseValue.(*Bottom) - v.BaseValue = CombineErrors(nil, b, err) - } - break - } - - defer c.PopArc(c.PushArc(v)) - - n.insertConjuncts(state) - - v.status = evaluating - - // Use maybeSetCache for cycle breaking - for n.maybeSetCache(); n.expandOne(partial); n.maybeSetCache() { - } - - n.doNotify() - - if !n.done() { - switch { - case state < conjuncts: - n.node.updateStatus(partial) - return - - case state == conjuncts: - if err := n.incompleteErrors(true); err != nil && err.Code < CycleError { - n.node.AddErr(c, err) - } else { - n.node.updateStatus(partial) - } - return - } - } - - // Disjunctions should always be finalized. If there are nested - // disjunctions the last one should be finalized. - disState := state - if len(n.disjunctions) > 0 && disState != finalized { - disState = finalized - } - n.expandDisjuncts(disState, n, maybeDefault, false, true) - - n.finalizeDisjuncts() - - switch len(n.disjuncts) { - case 0: - case 1: - x := n.disjuncts[0].result - x.state = nil - x.cyclicReferences = n.node.cyclicReferences - *v = x - - default: - d := n.createDisjunct() - v.BaseValue = d - // The conjuncts will have too much information. Better have no - // information than incorrect information. - for _, d := range d.Values { - d, ok := d.(*Vertex) - if !ok { - continue - } - // We clear the conjuncts for now. As these disjuncts are for API - // use only, we will fill them out when necessary (using Defaults). - d.Conjuncts = nil - - // TODO: use a more principled form of dereferencing. For instance, - // disjuncts could already be assumed to be the given Vertex, and - // the main vertex could be dereferenced during evaluation. - for _, a := range d.Arcs { - for _, x := range a.Conjuncts { - // All the environments for embedded structs need to be - // dereferenced. - for env := x.Env; env != nil && env.Vertex == v; env = env.Up { - env.Vertex = d - } - } - } - } - v.Arcs = nil - v.ChildErrors = nil - // v.Structs = nil // TODO: should we keep or discard the Structs? - // TODO: how to represent closedness information? Do we need it? - } - - // If the state has changed, it is because a disjunct has been run, or - // because a single disjunct has replaced it. Restore the old state as - // to not confuse memory management. - v.state = n - - // We don't do this in postDisjuncts, as it should only be done after - // completing all disjunctions. - if !n.done() { - if err := n.incompleteErrors(true); err != nil { - b := n.node.Bottom() - if b != err { - err = CombineErrors(n.ctx.src, b, err) - } - n.node.BaseValue = err - } - } - - assertStructuralCycle(n) - - if state != finalized { - return - } - - if v.BaseValue == nil { - v.BaseValue = n.getValidators(finalized) - } - - // Free memory here? - v.updateStatus(finalized) - - case finalized: - } -} - -// insertConjuncts inserts conjuncts previously not inserted. -func (n *nodeContext) insertConjuncts(state vertexStatus) bool { - unreachableForDev(n.ctx) - - // Exit early if we have a concrete value and only need partial results. - if state == partial { - for n.conjunctsPartialPos < len(n.conjuncts) { - c := &n.conjuncts[n.conjunctsPartialPos] - n.conjunctsPartialPos++ - if c.done { - continue - } - if v, ok := c.C.Elem().(Value); ok && IsConcrete(v) { - c.done = true - n.addValueConjunct(c.C.Env, v, c.C.CloseInfo) - } - } - if n.scalar != nil && n.node.isDefined() { - return true - } - } - for n.conjunctsPos < len(n.conjuncts) { - nInfos := len(n.node.Structs) - p := &n.conjuncts[n.conjunctsPos] - n.conjunctsPos++ - if p.done { - continue - } - - // Initially request a Partial state to allow cyclic references to - // resolve more naturally first. This results in better error messages - // and less operations. - n.addExprConjunct(p.C, partial) - p.done = true - - // Record the OptionalTypes for all structs that were inferred by this - // Conjunct. This information can be used by algorithms such as trim. - for i := nInfos; i < len(n.node.Structs); i++ { - n.node.Conjuncts[p.index].CloseInfo.FieldTypes |= n.node.Structs[i].types - } - } - return false -} - -// finalizeDisjuncts: incomplete errors are kept around and not removed early. -// This call filters the incomplete errors and removes them -// -// This also collects all errors of empty disjunctions. These cannot be -// collected during the finalization state of individual disjuncts. Care should -// be taken to only call this after all disjuncts have been finalized. -func (n *nodeContext) finalizeDisjuncts() { - a := n.disjuncts - if len(a) == 0 { - return - } - k := 0 - for i, d := range a { - switch d.finalDone() { - case true: - a[k], a[i] = d, a[k] - k++ - default: - if err := d.incompleteErrors(true); err != nil { - n.disjunctErrs = append(n.disjunctErrs, err) - } - } - d.free() - } - if k == 0 { - n.makeError() - } - n.disjuncts = a[:k] -} - -func (n *nodeContext) doNotify() { - if n.errs == nil || len(n.notify) == 0 { - return - } - for _, rec := range n.notify { - v := rec.v - if v.state == nil { - if b := v.Bottom(); b != nil { - v.BaseValue = CombineErrors(nil, b, n.errs) - } else { - v.BaseValue = n.errs - } - } else { - v.state.addBottom(n.errs) - } - } - n.notify = n.notify[:0] -} - -func (n *nodeContext) postDisjunct(state vertexStatus) { - ctx := n.ctx - unreachableForDev(ctx) - - for { - // Use maybeSetCache for cycle breaking - for n.maybeSetCache(); n.expandOne(state); n.maybeSetCache() { - } - - if !n.addLists(oldOnly(state)) { - break - } - } - - if n.aStruct != nil { - n.updateNodeType(StructKind, n.aStruct, n.aStructID) - } - - if len(n.selfComprehensions) > 0 { - // Up to here all comprehensions with sources other than this node will - // have had a chance to run. We can now run self-referencing - // comprehensions with the restriction that they cannot add new arcs. - // - // Note: we should only set this in case of self-referential - // comprehensions. A comprehension in a parent node may still add - // arcs to this node, even if it has reached AllConjunctsDone status, - // as long as any evaluation did not rely on its specific set of arcs. - // Example: - // - // a: { - // b: _env: c: 1 - // - // // Using dynamic field ("b") prevents the evaluation of the - // // comprehension to be pushed down to env: and instead evaluates - // // it before b is completed. Even though b needs to reach state - // // AllConjunctsDone before evaluating b._env, it is still okay - // // to add arcs to b after this evaluation: only the set of arcs - // // in b._env needs to be frozen after that. - // for k2, v2 in b._env { - // ("b"): env: (k2): v2 - // } - // } - n.node.LockArcs = true - - n.injectSelfComprehensions(state) - } - - for n.expandOne(state) { - } - - switch err := n.getErr(); { - case err != nil: - if err.Code < IncompleteError && n.node.ArcType == ArcPending { - n.node.ArcType = ArcMember - } - n.node.BaseValue = err - n.errs = nil - - default: - if isCyclePlaceholder(n.node.BaseValue) { - if !n.done() { - n.node.BaseValue = n.incompleteErrors(true) - } else { - n.node.BaseValue = nil - } - } - // TODO: this ideally should be done here. However, doing so causes - // a somewhat more aggressive cutoff in disjunction cycles, which cause - // some incompatibilities. Fix in another CL. - // - // else if !n.done() { - // n.expandOne() - // if err := n.incompleteErrors(); err != nil { - // n.node.BaseValue = err - // } - // } - - // We are no longer evaluating. - - n.validateValue(state) - - v := n.node.Value() - - // TODO(perf): only delay processing of actual non-monotonic checks. - skip := n.skipNonMonotonicChecks() - if v != nil && IsConcrete(v) && !skip { - for _, v := range n.checks { - // TODO(errors): make Validate return bottom and generate - // optimized conflict message. Also track and inject IDs - // to determine origin location.s - if b := ctx.Validate(v, n.node); b != nil { - n.addBottom(b) - } - } - } - - if v == nil { - break - } - - switch { - case v.Kind() == ListKind: - for _, a := range n.node.Arcs { - if a.Label.Typ() == StringLabel && a.IsDefined(ctx) { - n.addErr(ctx.Newf("list may not have regular fields")) - // TODO(errors): add positions for list and arc definitions. - - } - } - - // case !isStruct(n.node) && v.Kind() != BottomKind: - // for _, a := range n.node.Arcs { - // if a.Label.IsRegular() { - // n.addErr(errors.Newf(token.NoPos, - // // TODO(errors): add positions of non-struct values and arcs. - // "cannot combine scalar values with arcs")) - // } - // } - } - } - - n.completeArcs(state) +func (c *OpContext) unify(v *Vertex, flags Flags) { + v.unify(c, flags) } // validateValue checks collected bound validators and checks them against @@ -655,28 +193,17 @@ func (n *nodeContext) validateValue(state vertexStatus) { if v != nil && IsConcrete(v) { // Also check when we already have errors as we may find more // serious errors and would like to know about all errors anyway. - - if n.lowerBound != nil { - c := MakeRootConjunct(nil, n.lowerBound) - if b := ctx.Validate(c, v); b != nil { - // TODO(errors): make Validate return boolean and generate - // optimized conflict message. Also track and inject IDs - // to determine origin location.s - if e, _ := b.Err.(*ValueError); e != nil { - e.AddPosition(n.lowerBound) - e.AddPosition(v) - } - n.addBottom(b) + for _, bound := range []*BoundValue{n.lowerBound, n.upperBound} { + if bound == nil { + continue } - } - if n.upperBound != nil { - c := MakeRootConjunct(nil, n.upperBound) + c := MakeRootConjunct(nil, bound) if b := ctx.Validate(c, v); b != nil { // TODO(errors): make Validate return boolean and generate // optimized conflict message. Also track and inject IDs // to determine origin location.s if e, _ := b.Err.(*ValueError); e != nil { - e.AddPosition(n.upperBound) + e.AddPosition(bound) e.AddPosition(v) } n.addBottom(b) @@ -688,264 +215,6 @@ func (n *nodeContext) validateValue(state vertexStatus) { } } -// incompleteErrors reports all errors from uncompleted conjuncts. -// If final is true, errors are permanent and reported to parents. -func (n *nodeContext) incompleteErrors(final bool) *Bottom { - unreachableForDev(n.ctx) - - // collect incomplete errors. - var err *Bottom // n.incomplete - for _, d := range n.dynamicFields { - err = CombineErrors(nil, err, d.err) - } - for _, c := range n.comprehensions { - if c.err == nil { - continue - } - err = CombineErrors(nil, err, c.err) - - // TODO: use this code once possible. - // - // Add comprehension to ensure incomplete error is inserted. This - // ensures that the error is reported in the Vertex where the - // comprehension was defined, and not just in the node below. This, in - // turn, is necessary to support certain logic, like export, that - // expects to be able to detect an "incomplete" error at the first level - // where it is necessary. - // if c.node.status != Finalized { - // n := c.node.getNodeContext(n.ctx) - // n.comprehensions = append(n.comprehensions, c) - // } else { - // n.node.AddErr(n.ctx, err) - // } - // n := d.node.getNodeContext(ctx) - // n.addBottom(err) - if final && c.vertex != nil && c.vertex.status != finalized { - c.vertex.state.assertInitialized() - c.vertex.state.addBottom(err) - c.vertex = nil - } - } - for _, c := range n.selfComprehensions { - if c.err == nil { - continue - } - - err = CombineErrors(nil, err, c.err) - - // TODO: use this code once possible. - // - // Add comprehension to ensure incomplete error is inserted. This - // ensures that the error is reported in the Vertex where the - // comprehension was defined, and not just in the node below. This, in - // turn, is necessary to support certain logic, like export, that - // expects to be able to detect an "incomplete" error at the first level - // where it is necessary. - // if c.node.status != Finalized { - // n := c.node.getNodeContext(n.ctx) - // n.comprehensions = append(n.comprehensions, c) - // } else { - // n.node.AddErr(n.ctx, err) - // } - // n := d.node.getNodeContext(ctx) - // n.addBottom(err) - if c.vertex != nil && c.vertex.status != finalized { - c.vertex.state.addBottom(err) - c.vertex = nil - } - } - for _, x := range n.exprs { - err = CombineErrors(nil, err, x.err) - } - if err == nil { - // safeguard. - err = incompleteSentinel - } - if err.Code < IncompleteError { - n.node.ArcType = ArcMember - } - return err -} - -// TODO(perf): ideally we should always perform a closedness check if -// state is Finalized. This is currently not possible when computing a -// partial disjunction as the closedness information is not yet -// complete, possibly leading to a disjunct to be rejected prematurely. -// It is probably possible to fix this if we could add StructInfo -// structures demarked per conjunct. -// -// In practice this should not be a problem: when disjuncts originate -// from the same disjunct, they will have the same StructInfos, and thus -// Equal is able to equate them even in the presence of optional field. -// In general, combining any limited set of disjuncts will soon reach -// a fixed point where duplicate elements can be eliminated this way. -// -// Note that not checking closedness is irrelevant for disjunctions of -// scalars. This means it also doesn't hurt performance where structs -// have a discriminator field (e.g. Kubernetes). We should take care, -// though, that any potential performance issues are eliminated for -// Protobuf-like oneOf fields. -func (n *nodeContext) checkClosed(state vertexStatus) bool { - unreachableForDev(n.ctx) - - ignore := state != finalized || n.skipNonMonotonicChecks() - - v := n.node - if !v.Label.IsInt() && v.Parent != nil && !ignore && v.ArcType <= ArcRequired { - ctx := n.ctx - // Visit arcs recursively to validate and compute error. - if _, err := verifyArc2(ctx, v.Label, v, v.ClosedRecursive); err != nil { - // Record error in child node to allow recording multiple - // conflicts at the appropriate place, to allow valid fields to - // be represented normally and, most importantly, to avoid - // recursive processing of a disallowed field. - v.SetValue(ctx, err) - return false - } - } - return true -} - -func (n *nodeContext) completeArcs(state vertexStatus) { - unreachableForDev(n.ctx) - - if n.node.hasAllConjuncts || n.node.Parent == nil { - n.node.setParentDone() - } - - // At this point, if this arc is of type arcVoid, it means that the value - // may still be modified by child arcs. So in this case we must now process - // all arcs to be sure we get the correct result. - // For other cases we terminate early as this results in considerably - // better error messages. - if state <= conjuncts && - // Is allowed to go one step back. See Vertex.UpdateStatus. - n.node.status <= state+1 && - (!n.node.hasPendingArc || n.node.ArcType == ArcMember) { - - n.node.updateStatus(conjuncts) - return - } - - n.node.updateStatus(evaluatingArcs) - - ctx := n.ctx - - if !assertStructuralCycle(n) { - k := 0 - // Visit arcs recursively to validate and compute error. - for _, a := range n.node.Arcs { - // Call UpdateStatus here to be absolutely sure the status is set - // correctly and that we are not regressing. - n.node.updateStatus(evaluatingArcs) - - wasVoid := a.ArcType == ArcPending - - ctx.unify(a, oldOnly(finalized)) - - if a.ArcType == ArcPending { - continue - } - - // Errors are allowed in let fields. Handle errors and failure to - // complete accordingly. - if !a.Label.IsLet() && a.ArcType <= ArcRequired { - // Don't set the state to Finalized if the child arcs are not done. - if state == finalized && a.status < finalized { - state = conjuncts - } - - if err := a.Bottom(); err != nil { - n.AddChildError(err) - } - } - - n.node.Arcs[k] = a - k++ - - switch { - case a.ArcType > ArcRequired, !a.Label.IsString(): - case n.kind&StructKind == 0: - if !n.node.IsErr() { - n.reportFieldMismatch(pos(a.Value()), nil, a.Label, n.node.Value()) - } - case !wasVoid: - case n.kind == TopKind: - // Theoretically it may be possible that a "void" arc references - // this top value where it really should have been a struct. One - // way to solve this is to have two passes over the arcs, where - // the first pass additionally analyzes whether comprehensions - // will yield values and "un-voids" an arc ahead of the rest. - // - // At this moment, though, I fail to see a possibility to create - // faulty CUE using this mechanism, though. At most error - // messages are a bit unintuitive. This may change once we have - // functionality to reflect on types. - if !n.node.IsErr() { - n.node.BaseValue = &StructMarker{} - n.kind = StructKind - } - } - } - n.node.Arcs = n.node.Arcs[:k] - - for _, c := range n.postChecks { - f := ctx.PushState(c.env, c.expr.Source()) - - // TODO(errors): make Validate return bottom and generate - // optimized conflict message. Also track and inject IDs - // to determine origin location.s - v := ctx.evalState(c.expr, oldOnly(finalized)) - v, _ = ctx.getDefault(v) - v = Unwrap(v) - - switch _, isError := v.(*Bottom); { - case isError == c.expectError: - default: - n.node.AddErr(ctx, &Bottom{ - Src: c.expr.Source(), - Code: CycleError, - Node: n.node, - Err: ctx.NewPosf(pos(c.expr), - "circular dependency in evaluation of conditionals: %v changed after evaluation", - ctx.Str(c.expr)), - }) - } - - ctx.PopState(f) - } - } - - if err := n.getErr(); err != nil { - n.errs = nil - if b, _ := n.node.BaseValue.(*Bottom); b != nil { - err = CombineErrors(nil, b, err) - } - n.node.BaseValue = err - } - - b, hasErr := n.node.BaseValue.(*Bottom) - if !hasErr && b != cycle { - n.checkClosed(state) - } - - // Strip struct literals that were not initialized and are not part - // of the output. - // - // TODO(perf): we could keep track if any such structs exist and only - // do this removal if there is a change of shrinking the list. - k := 0 - for _, s := range n.node.Structs { - if s.initialized { - n.node.Structs[k] = s - k++ - } - } - n.node.Structs = n.node.Structs[:k] - - n.node.updateStatus(finalized) -} - // TODO: this is now a sentinel. Use a user-facing error that traces where // the cycle originates. var cycle = &Bottom{ @@ -961,40 +230,6 @@ func isCyclePlaceholder(v BaseValue) bool { return v == cycle } -func (n *nodeContext) createDisjunct() *Disjunction { - a := make([]Value, len(n.disjuncts)) - p := 0 - hasDefaults := false - for i, x := range n.disjuncts { - v := new(Vertex) - *v = x.result - v.state = nil - switch x.defaultMode { - case isDefault: - a[i] = a[p] - a[p] = v - p++ - hasDefaults = true - - case notDefault: - hasDefaults = true - fallthrough - case maybeDefault: - a[i] = v - } - } - // TODO: disambiguate based on concrete values. - // TODO: consider not storing defaults. - // if p > 0 { - // a = a[:p] - // } - return &Disjunction{ - Values: a, - NumDefaults: p, - HasDefaults: hasDefaults, - } -} - type arcKey struct { arc *Vertex id CloseInfo @@ -1006,8 +241,26 @@ type arcKey struct { // checks should only be performed once the full value is known. type nodeContext struct { nextFree *nodeContext + + // opID is assigned the opID of the OpContext upon creation. + // This allows checking that we are not using stale nodeContexts. + opID uint64 + + // refCount: + // evalv2: keeps track of all current usages of the node, such that the + // node can be freed when the counter reaches zero. + // evalv3: keeps track of the number points in the code where this + //. nodeContext is used for processing. A nodeContext that is being + //. processed may not be freed yet. refCount int + // isDisjunct indicates whether this nodeContext is used in a disjunction. + // Disjunction cross products may call mergeCloseInfo, which assumes all + // closedness information, which is stored in the nodeContext, is still + // valid. This means that we need to follow a different approach for freeing + // disjunctions. + isDisjunct bool + // Keep node out of the nodeContextState to make them more accessible // for source-level debuggers. node *Vertex @@ -1020,14 +273,15 @@ type nodeContext struct { // set for all Vertex values that were cloned. underlying *Vertex - // overlays is set if this node is the root of a disjunct created in - // doDisjunct. It points to the direct parent nodeContext. - overlays *nodeContext - nodeContextState scheduler + // toFree keeps track of inlined vertices that potentially need to be freed + // after processing the node. This is used to avoid memory leaks when an + // inlined node is only partially processed to obtain a result. + toFree []*Vertex + // Below are slices that need to be managed when cloning and reclaiming // nodeContexts for reuse. We want to ensure that, instead of setting // slices to nil, we truncate the existing buffers so that they do not @@ -1035,6 +289,9 @@ type nodeContext struct { arcMap []arcKey // not copied for cloning + // vertexMap is used to map vertices in disjunctions. + vertexMap vertexMap + // notify is used to communicate errors in cyclic dependencies. // TODO: also use this to communicate increasingly more concrete values. notify []receiver @@ -1046,19 +303,14 @@ type nodeContext struct { // closedness information is correctly computed in such cases. sharedIDs []CloseInfo - // Conjuncts holds a reference to the Vertex Arcs that still need - // processing. It does NOT need to be copied. - conjuncts []conjunct cyclicConjuncts []cyclicConjunct - dynamicFields []envDynamic - comprehensions []envYield - selfComprehensions []envYield // comprehensions iterating over own struct. - - // Expression conjuncts - lists []envList - vLists []*Vertex - exprs []envExpr + // These fields are used to track type checking. + reqDefIDs []refInfo + replaceIDs []replaceID + conjunctInfo []conjunctInfo + reqSets reqSets + containsDefIDCache map[[2]defID]bool // cache for containsDefID results // Checks is a list of conjuncts, as we need to preserve the context in // which it was evaluated. The conjunct is always a validator (and thus @@ -1072,45 +324,16 @@ type nodeContext struct { // Disjunction handling disjunctions []envDisjunct - // disjunctCCs holds the close context that represent "holes" in which - // pending disjuncts are to be inserted for the clone represented by this - // nodeContext. Holes that are not yet filled will always need to be cloned - // when a disjunction branches in doDisjunct. - // - // Holes may accumulate as nested disjunctions get added and filled holes - // may be removed. So the list of disjunctCCs may differ from the number - // of disjunctions. - disjunctCCs []disjunctHole - - // usedDefault indicates the for each of possibly multiple parent - // disjunctions whether it is unified with a default disjunct or not. - // This is then later used to determine whether a disjunction should - // be treated as a marked disjunction. - usedDefault []defaultInfo - // disjuncts holds disjuncts that evaluated to a non-bottom value. // TODO: come up with a better name. disjuncts []*nodeContext - buffer []*nodeContext disjunctErrs []*Bottom - disjunct Conjunct - - // snapshot holds the last value of the vertex before calling postDisjunct. - snapshot Vertex - - // Result holds the last evaluated value of the vertex after calling - // postDisjunct. - result Vertex -} - -type conjunct struct { - C Conjunct + userErrs []*Bottom - // done marks that this conjunct has been inserted. This prevents a - // conjunct from being processed more than once, for instance, when - // insertConjuncts is called more than once for the same node. - done bool - index int // index of the original conjunct in Vertex.Conjuncts + // hasDisjunction marks wither any disjunct was added. It is listed here + // instead of in nodeContextState as it should be cleared when a disjunction + // is split off. TODO: find something more principled. + hasDisjunction bool } type nodeContextState struct { @@ -1123,6 +346,13 @@ type nodeContextState struct { // node after a corresponding task has been completed. toComplete bool + // embedsRecursivelyClosed is used to implement __reclose. It must be set + // when a vertex that is recursively closed is embedded through a spread + // operator. It is okay to set it if it is just unified with a vertex that + // is recursively closed, but not added through a spread operator. The + // result will just be an unnecessary call to __reclose. + embedsRecursivelyClosed bool + // isCompleting > 0 indicates whether a call to completeNodeTasks is in // progress. isCompleting int @@ -1148,6 +378,14 @@ type nodeContextState struct { hasNonCycle bool // has material conjuncts without structural cycle hasNonCyclic bool // has non-cyclic conjuncts at start of field processing + // These simulate the old closeContext logic. TODO: perhaps remove. + hasStruct bool // this node has a struct conjunct + hasOpenValidator bool // this node has an open validator + isDef bool // this node is a definition + + dropParentRequirements bool // used for typo checking + computedCloseInfo bool // used for typo checking + isShared bool // set if we are currently structure sharing noSharing bool // set if structure sharing is not allowed shared Conjunct // the original conjunct that led to sharing @@ -1155,16 +393,72 @@ type nodeContextState struct { origBaseValue BaseValue // the BaseValue that structure sharing replaces shareDecremented bool // counters of sharedIDs have been decremented - depth int32 - defaultMode defaultMode - - // Value info - - kind Kind - kindExpr Expr // expr that adjust last value (for error reporting) - kindID CloseInfo // for error tracing - - // Current value (may be under construction) + depth int32 + defaultMode defaultMode // cumulative default mode + origDefaultMode defaultMode // default mode of the original disjunct + priority layer.Priority // Priority corresponding to defaultMode + origPriority layer.Priority // Priority of the original disjunct + + // has a value filled out before the node splits into a disjunction. Aside + // from detecting a self-reference cycle when there is otherwise just an + // other error, this field is not needed. It greatly helps, however, to + // improve the error messages. + hasFieldValue bool + + // defaultAttemptInCycle indicates that a value relies on the default value + // and that it will be an error to remove the default value from the + // disjunction. It is set to the referring Vertex. Consider for instance: + // + // a: 1 - b + // b: 1 - a + // a: *0 | 1 + // b: *0 | 1 + // + // versus + // + // a: 1 - b + // b: 1 - a + // a: *1 | 0 + // b: *0 | 1 + // + // In both cases there are multiple solutions to the configuration. In the + // first case there is an ambiguity: if we start with evaluating 'a' and + // pick the default for 'b', we end up with a value of '1' for 'a'. If, + // conversely, we start evaluating 'b' and pick the default for 'a', we end + // up with {a: 0, b: 0}. In the seconds case, however, we do _will_ get the + // same answer regardless of order. + // + // In general, we will allow expressions on cyclic paths to be resolved if + // in all cases the default value is taken. In order to do that, we do not + // allow a default value to be removed from a disjunction if such value is + // depended on. + // + // For completeness, note that CUE will NOT solve a solution, even if there + // is only one solution. Consider for instance: + // + // a: 0 | 1 + // a: b + 1 + // b: c - 1 + // c: a - 1 + // c: 1 | 2 + // + // There the only consistent solution is {a: 1, b: 0, c: 1}. CUE, however, + // will not attempt this solve this as, in general, such solving would be NP + // complete. + // + // NOTE(evalv4): note that this would be easier if we got rid of default + // values and had pre-selected overridable values instead. + defaultAttemptInCycle *Vertex + + // Value info + + kind Kind + constraintKind Kind + defaultKind Kind + kindExpr Expr // expr that adjust last value (for error reporting) + kindID CloseInfo // for error tracing + + // Current value (may be under construction) scalar Value // TODO: use Value in node. scalarID CloseInfo @@ -1179,24 +473,14 @@ type nodeContextState struct { lowerBound *BoundValue // > or >= upperBound *BoundValue // < or <= errs *Bottom - - // Slice positions - - // conjunctsPos is an index into conjuncts indicating the next conjunct - // to process. This is used to avoids processing a conjunct twice in some - // cases where there is an evaluation cycle. - conjunctsPos int - // conjunctsPartialPos is like conjunctsPos, but for the 'partial' phase - // of processing where conjuncts are only processed as concrete scalars. - conjunctsPartialPos int } // A receiver receives notifications. // cc is used for V3 and is nil in V2. // v is equal to cc.src._cc in V3. type receiver struct { - v *Vertex - cc *closeContext + v *Vertex + c CloseInfo } // Logf substitutes args in format. Arguments of type Feature, Value, and Expr @@ -1206,154 +490,66 @@ func (n *nodeContext) Logf(format string, args ...interface{}) { n.ctx.Logf(n.node, format, args...) } -type defaultInfo struct { - // parentMode indicates whether this values was used as a default value, - // based on the parent mode. - parentMode defaultMode - - // The result of default evaluation for a nested disjunction. - nestedMode defaultMode - - origMode defaultMode -} - -func (n *nodeContext) addNotify(v *Vertex, cc *closeContext) { - unreachableForDev(n.ctx) - - if v != nil && !n.node.hasAllConjuncts { - n.notify = append(n.notify, receiver{v, cc}) - } -} - -func (n *nodeContext) clone() *nodeContext { - d := n.ctx.newNodeContext(n.node) - - d.refCount++ - - d.ctx = n.ctx - d.node = n.node - - d.nodeContextState = n.nodeContextState - - d.arcMap = append(d.arcMap, n.arcMap...) - d.notify = append(d.notify, n.notify...) - d.sharedIDs = append(d.sharedIDs, n.sharedIDs...) - - n.scheduler.cloneInto(&d.scheduler) - - d.conjuncts = append(d.conjuncts, n.conjuncts...) - d.cyclicConjuncts = append(d.cyclicConjuncts, n.cyclicConjuncts...) - d.dynamicFields = append(d.dynamicFields, n.dynamicFields...) - d.comprehensions = append(d.comprehensions, n.comprehensions...) - d.selfComprehensions = append(d.selfComprehensions, n.selfComprehensions...) - d.lists = append(d.lists, n.lists...) - d.vLists = append(d.vLists, n.vLists...) - d.exprs = append(d.exprs, n.exprs...) - d.checks = append(d.checks, n.checks...) - d.postChecks = append(d.postChecks, n.postChecks...) - - d.usedDefault = append(d.usedDefault, n.usedDefault...) - - // Do not clone other disjunction-related slices, like disjuncts and buffer: - // disjunction slices are managed by disjunction processing directly. - - return d -} - func (c *OpContext) newNodeContext(node *Vertex) *nodeContext { - if n := c.freeListNode; n != nil { + var n *nodeContext + if n = c.freeListNode; n != nil { c.stats.Reused++ c.freeListNode = n.nextFree + n.scheduler.clear() + n.scheduler.ctx = c + *n = nodeContext{ - scheduler: scheduler{ctx: c}, + scheduler: n.scheduler, node: node, nodeContextState: nodeContextState{ - kind: TopKind, + kind: TopKind, + constraintKind: TopKind, + defaultKind: TopKind, }, + toFree: n.toFree[:0], arcMap: n.arcMap[:0], - conjuncts: n.conjuncts[:0], cyclicConjuncts: n.cyclicConjuncts[:0], notify: n.notify[:0], sharedIDs: n.sharedIDs[:0], checks: n.checks[:0], postChecks: n.postChecks[:0], - dynamicFields: n.dynamicFields[:0], - comprehensions: n.comprehensions[:0], - selfComprehensions: n.selfComprehensions[:0], - lists: n.lists[:0], - vLists: n.vLists[:0], - exprs: n.exprs[:0], + reqDefIDs: n.reqDefIDs[:0], + replaceIDs: n.replaceIDs[:0], + conjunctInfo: n.conjunctInfo[:0], + reqSets: n.reqSets[:0], disjunctions: n.disjunctions[:0], - disjunctCCs: n.disjunctCCs[:0], - usedDefault: n.usedDefault[:0], disjunctErrs: n.disjunctErrs[:0], + userErrs: n.userErrs[:0], disjuncts: n.disjuncts[:0], - buffer: n.buffer[:0], + containsDefIDCache: n.containsDefIDCache, // cleared below } + clear(n.containsDefIDCache) n.scheduler.clear() - n.scheduler.node = n - n.underlying = node - - return n - } - c.stats.Allocs++ - - n := &nodeContext{ - scheduler: scheduler{ - ctx: c, - }, - node: node, - - nodeContextState: nodeContextState{kind: TopKind}, - } - n.scheduler.node = n - n.underlying = node - return n -} - -func (v *Vertex) getNodeContext(c *OpContext, ref int) *nodeContext { - unreachableForDev(c) + } else { + c.stats.Allocs++ - if v.state == nil { - if v.status == finalized { - return nil - } - v.state = c.newNodeContext(v) - } else if v.state.node != v { - panic("getNodeContext: nodeContext out of sync") - } - v.state.refCount += ref - return v.state -} + n = &nodeContext{ + scheduler: scheduler{ + ctx: c, + }, + node: node, -func (v *Vertex) freeNode(n *nodeContext) { - if n == nil { - return - } - if n.node != v { - panic("freeNode: unpaired free") - } - if v.state != nil && v.state != n { - panic("freeNode: nodeContext out of sync") - } - if n.refCount--; n.refCount == 0 { - if v.status == finalized { - v.freeNodeState() - } else { - n.ctx.stats.Retained++ + nodeContextState: nodeContextState{ + kind: TopKind, + constraintKind: TopKind, + defaultKind: TopKind, + }, } } -} -func (v *Vertex) freeNodeState() { - if v.state == nil { - return + n.opID = c.opID + n.scheduler.node = n + n.underlying = node + if p := node.Parent; p != nil && p.state != nil { + n.isDisjunct = p.state.isDisjunct } - state := v.state - v.state = nil - - state.ctx.freeNodeContext(state) + return n } func (n *nodeContext) free() { @@ -1362,7 +558,16 @@ func (n *nodeContext) free() { } } +// freeNodeContext unconditionally adds a nodeContext to the free pool. The +// status should only be called for nodes with status finalized. Non-rooted +// vertex values, however, the status may be different. But also unprocessed +// nodes may have an uninitialized nodeContext. TODO(mem): this latter should be +// fixed. +// +// We leave it up to the caller to ensure it is safe to free the nodeContext for +// a given status. func (c *OpContext) freeNodeContext(n *nodeContext) { + n.node.state = nil c.stats.Freed++ n.nextFree = c.freeListNode c.freeListNode = n @@ -1392,7 +597,7 @@ func (n *nodeContext) reportConflict( err.AddPosition(v1) err.AddPosition(v2) for _, id := range ids { - err.AddClosedPositions(id) + err.AddClosedPositions(ctx, id) } n.addErr(err) @@ -1430,13 +635,15 @@ func (n *nodeContext) reportFieldMismatch( } for _, ci := range id { - err.AddClosedPositions(ci) + err.AddClosedPositions(ctx, ci) } n.addErr(err) } func (n *nodeContext) updateNodeType(k Kind, v Expr, id CloseInfo) bool { + n.updateConjunctInfo(k, id, 0) + ctx := n.ctx kind := n.kind & k @@ -1467,31 +674,10 @@ func (n *nodeContext) updateNodeType(k Kind, v Expr, id CloseInfo) bool { n.kindExpr = v } n.kind = kind + n.kindID = id return kind != BottomKind } -func (n *nodeContext) done() bool { - // TODO(v0.7): verify that done() is checking for the right conditions in - // the new evaluator implementation. - return len(n.dynamicFields) == 0 && - len(n.comprehensions) == 0 && - len(n.exprs) == 0 -} - -// finalDone is like done, but allows for cycle errors, which can be ignored -// as they essentially indicate a = a & _. -func (n *nodeContext) finalDone() bool { - // TODO(v0.7): update for new evaluator? - for _, x := range n.exprs { - if x.err.Code != CycleError { - return false - } - } - return len(n.dynamicFields) == 0 && - len(n.comprehensions) == 0 && - len(n.selfComprehensions) == 0 -} - // hasErr is used to determine if an evaluation path, for instance a single // path after expanding all disjunctions, has an error. func (n *nodeContext) hasErr() bool { @@ -1574,42 +760,6 @@ func (n *nodeContext) getValidators(state vertexStatus) BaseValue { return v } -// TODO: this function can probably go as this is now handled in the nodeContext. -func (n *nodeContext) maybeSetCache() { - // Set BaseValue to scalar, but only if it was not set before. Most notably, - // errors should not be discarded. - _, isErr := n.node.BaseValue.(*Bottom) - if n.scalar != nil && (!isErr || isCyclePlaceholder(n.node.BaseValue)) { - n.node.BaseValue = n.scalar - } - // NOTE: this is now handled by associating the nodeContext - // if n.errs != nil { - // n.node.SetValue(n.ctx, Partial, n.errs) - // } -} - -type envExpr struct { - c Conjunct - err *Bottom -} - -type envDynamic struct { - env *Environment - field *DynamicField - id CloseInfo - err *Bottom -} - -type envList struct { - env *Environment - list *ListLit - n int64 // recorded length after evaluator - elipsis *Ellipsis - id CloseInfo - ignore bool // has a self-referencing comprehension and is postponed - self bool // was added as a postponed self-referencing comprehension -} - type envCheck struct { env *Environment expr Expr @@ -1636,461 +786,6 @@ func (n *nodeContext) addErr(err errors.Error) { } } -// addExprConjuncts will attempt to evaluate an Expr and insert the value -// into the nodeContext if successful or queue it for later evaluation if it is -// incomplete or is not value. -func (n *nodeContext) addExprConjunct(v Conjunct, state vertexStatus) { - unreachableForDev(n.ctx) - - env := v.Env - id := v.CloseInfo - - switch x := v.Elem().(type) { - case *Vertex: - if x.IsData() { - n.addValueConjunct(env, x, id) - } else { - n.addVertexConjuncts(v, x, true) - } - - case Value: - n.addValueConjunct(env, x, id) - - case *BinaryExpr: - if x.Op == AndOp { - n.addExprConjunct(MakeConjunct(env, x.X, id), state) - n.addExprConjunct(MakeConjunct(env, x.Y, id), state) - return - } else { - n.evalExpr(v, state) - } - - case *StructLit: - n.addStruct(env, x, id) - - case *ListLit: - childEnv := &Environment{ - Up: env, - Vertex: n.node, - } - n.lists = append(n.lists, envList{env: childEnv, list: x, id: id}) - - case *DisjunctionExpr: - n.addDisjunction(env, x, id) - - case *Comprehension: - // always a partial comprehension. - n.insertComprehension(env, x, id) - return - - default: - // Must be Resolver or Evaluator. - n.evalExpr(v, state) - } - n.ctx.stats.Conjuncts++ -} - -// evalExpr is only called by addExprConjunct. If an error occurs, it records -// the error in n and returns nil. -func (n *nodeContext) evalExpr(v Conjunct, state vertexStatus) { - unreachableForDev(n.ctx) - - // Require an Environment. - ctx := n.ctx - - closeID := v.CloseInfo - - switch x := v.Expr().(type) { - case Resolver: - // We elevate a field evaluated to the Conjuncts state to Finalized - // later. For now we allow partial evaluation so that we can break - // cycles and postpone incomplete evaluations until more information is - // available down the line. - if state == finalized { - state = conjuncts - } - arc, err := ctx.resolveState(v, x, oldOnly(state)) - if err != nil && (!err.IsIncomplete() || err.Permanent) { - n.addBottom(err) - break - } - if arc == nil { - n.exprs = append(n.exprs, envExpr{v, err}) - break - } - - // We complete the evaluation. Some optimizations will only work when an - // arc is already finalized. So this ensures that such optimizations get - // triggered more often. - // - // NOTE(let finalization): aside from being an optimization, this also - // ensures that let arcs that are not contained as fields of arcs, but - // rather are held in the cash, are finalized. This, in turn, is - // necessary to trigger the notification mechanism, where appropriate. - // - // A node should not Finalize itself as it may erase the state object - // which is still assumed to be present down the line - // (see https://cuelang.org/issues/2171). - if arc.status == conjuncts && arc != n.node && arc.hasAllConjuncts { - arc.Finalize(ctx) - } - - ci, skip := n.markCycle(arc, v.Env, x, v.CloseInfo) - if skip { - return - } - v.CloseInfo = ci - - n.addVertexConjuncts(v, arc, false) - - case Evaluator: - // Interpolation, UnaryExpr, BinaryExpr, CallExpr - // Could be unify? - val := ctx.evaluateRec(v, oldOnly(partial)) - if b, ok := val.(*Bottom); ok && - b.IsIncomplete() { - n.exprs = append(n.exprs, envExpr{v, b}) - break - } - - if v, ok := val.(*Vertex); ok { - // Handle generated disjunctions (as in the 'or' builtin). - // These come as a Vertex, but should not be added as a value. - b, ok := v.BaseValue.(*Bottom) - if ok && b.IsIncomplete() && len(v.Conjuncts) > 0 { - for _, c := range v.Conjuncts { - c.CloseInfo = closeID - n.addExprConjunct(c, state) - } - break - } - } - - // TODO: also to through normal Vertex handling here. At the moment - // addValueConjunct handles StructMarker.NeedsClose, as this is always - // only needed when evaluation an Evaluator, and not a Resolver. - // The two code paths should ideally be merged once this separate - // mechanism is eliminated. - // - // if arc, ok := val.(*Vertex); ok && !arc.IsData() { - // n.addVertexConjuncts(v.Env, closeID, v.Expr(), arc) - // break - // } - - // TODO: insert in vertex as well - n.addValueConjunct(v.Env, val, closeID) - - default: - panic(fmt.Sprintf("unknown expression of type %T", x)) - } -} - -func (n *nodeContext) addVertexConjuncts(c Conjunct, arc *Vertex, inline bool) { - unreachableForDev(n.ctx) - - closeInfo := c.CloseInfo - - // We need to ensure that each arc is only unified once (or at least) a - // bounded time, witch each conjunct. Comprehensions, for instance, may - // distribute a value across many values that get unified back into the - // same value. If such a value is a disjunction, than a disjunction of N - // disjuncts will result in a factor N more unifications for each - // occurrence of such value, resulting in exponential running time. This - // is especially common values that are used as a type. - // - // However, unification is idempotent, so each such conjunct only needs - // to be unified once. This cache checks for this and prevents an - // exponential blowup in such case. - // - // TODO(perf): this cache ensures the conjuncts of an arc at most once - // per ID. However, we really need to add the conjuncts of an arc only - // once total, and then add the close information once per close ID - // (pointer can probably be shared). Aside from being more performant, - // this is probably the best way to guarantee that conjunctions are - // linear in this case. - - ckey := closeInfo - ckey.Refs = nil - ckey.Inline = false - key := arcKey{arc, ckey} - for _, k := range n.arcMap { - if key == k { - return - } - } - n.arcMap = append(n.arcMap, key) - - status := arc.status - - switch status { - case evaluating: - // Reference cycle detected. We have reached a fixed point and - // adding conjuncts at this point will not change the value. Also, - // continuing to pursue this value will result in an infinite loop. - - // TODO: add a mechanism so that the computation will only have to - // be done once? - - if arc == n.node { - // TODO: we could use node sharing here. This may avoid an - // exponential blowup during evaluation, like is possible with - // YAML. - return - } - - case evaluatingArcs: - // There is a structural cycle, but values may be processed nonetheless - // if there is a non-cyclic conjunct. See cycle.go. - } - - // Performance: the following if check filters cases that are not strictly - // necessary for correct functioning. Not updating the closeInfo may cause - // some position information to be lost for top-level positions of merges - // resulting form APIs. These tend to be fairly uninteresting. - // At the same time, this optimization may prevent considerable slowdown - // in case an API does many calls to Unify. - x := c.Expr() - if !inline || arc.IsClosedStruct() || arc.IsClosedList() { - isDef, _ := IsDef(x) - closeInfo = closeInfo.SpawnRef(arc, isDef, x) - } - - if arc.status == unprocessed && !inline { - // This is a rare condition, but can happen in certain - // evaluation orders. Unfortunately, adding this breaks - // resolution of cyclic mutually referring disjunctions. But it - // is necessary to prevent lookups in unevaluated structs. - // TODO(cycles): this can probably most easily be fixed with a - // having a more recursive implementation. - n.ctx.unify(arc, oldOnly(partial)) - } - - // Don't add conjuncts if a node is referring to itself. - if n.node == arc { - return - } - - if arc.state != nil { - arc.state.addNotify(n.node, nil) - } - - for _, c := range arc.Conjuncts { - // Note that we are resetting the tree here. We hereby assume that - // closedness conflicts resulting from unifying the referenced arc were - // already caught there and that we can ignore further errors here. - c.CloseInfo = closeInfo - n.addExprConjunct(c, partial) - } -} - -func (n *nodeContext) addValueConjunct(env *Environment, v Value, id CloseInfo) { - n.updateCyclicStatus(id) - - ctx := n.ctx - - if x, ok := v.(*Vertex); ok { - if m, ok := x.BaseValue.(*StructMarker); ok { - n.aStruct = x - n.aStructID = id - if m.NeedClose { - id.IsClosed = true - } - } - - if !x.IsData() { - // TODO: this really shouldn't happen anymore. - if isComplexStruct(ctx, x) { - // This really shouldn't happen, but just in case. - n.addVertexConjuncts(MakeConjunct(env, x, id), x, true) - return - } - - for _, c := range x.Conjuncts { - c.CloseInfo = id - n.addExprConjunct(c, partial) // TODO: Pass from eval - } - return - } - - // TODO: evaluate value? - switch v := x.BaseValue.(type) { - default: - panic(fmt.Sprintf("invalid type %T", x.BaseValue)) - - case *ListMarker: - n.vLists = append(n.vLists, x) - return - - case *StructMarker: - - case Value: - n.addValueConjunct(env, v, id) - } - - if len(x.Arcs) == 0 { - return - } - - s := &StructLit{} - - // Keep ordering of Go struct for topological sort. - n.node.AddStruct(s, env, id) - n.node.Structs = append(n.node.Structs, x.Structs...) - - for _, a := range x.Arcs { - if !a.definitelyExists() { - continue - } - // TODO(errors): report error when this is a regular field. - c := MakeConjunct(nil, a, id) - n.insertField(a.Label, a.ArcType, c) - s.MarkField(a.Label) - } - return - } - - switch b := v.(type) { - case *Bottom: - if b == NoShareSentinel { - return - } - n.addBottom(b) - return - case *Builtin: - if v := b.BareValidator(); v != nil { - n.addValueConjunct(env, v, id) - return - } - } - - if !n.updateNodeType(v.Kind(), v, id) { - return - } - - switch x := v.(type) { - case *Disjunction: - n.addDisjunctionValue(env, x, id) - - case *Conjunction: - for _, x := range x.Values { - n.addValueConjunct(env, x, id) - } - - case *Top: - n.hasTop = true - - case *BasicType: - // handled above - - case *BoundValue: - switch x.Op { - case LessThanOp, LessEqualOp: - if y := n.upperBound; y != nil { - v := SimplifyBounds(ctx, n.kind, x, y) - if err := valueError(v); err != nil { - err.AddPosition(v) - err.AddPosition(n.upperBound) - err.AddClosedPositions(id) - } - n.upperBound = nil - n.addValueConjunct(env, v, id) - return - } - n.upperBound = x - - case GreaterThanOp, GreaterEqualOp: - if y := n.lowerBound; y != nil { - v := SimplifyBounds(ctx, n.kind, x, y) - if err := valueError(v); err != nil { - err.AddPosition(v) - err.AddPosition(n.lowerBound) - err.AddClosedPositions(id) - } - n.lowerBound = nil - n.addValueConjunct(env, v, id) - return - } - n.lowerBound = x - - case EqualOp, NotEqualOp, MatchOp, NotMatchOp: - // This check serves as simplifier, but also to remove duplicates. - k := 0 - match := false - cx := MakeConjunct(env, x, id) - for _, c := range n.checks { - if y, ok := c.x.(*BoundValue); ok { - switch z := SimplifyBounds(ctx, n.kind, x, y); { - case z == y: - match = true - case z == x: - continue - } - } - n.checks[k] = c - k++ - } - n.checks = n.checks[:k] - if !match { - n.checks = append(n.checks, cx) - } - return - } - - case Validator: - // This check serves as simplifier, but also to remove duplicates. - cx := MakeConjunct(env, x, id) - for i, y := range n.checks { - if b, ok := SimplifyValidator(ctx, cx, y); ok { - n.checks[i] = b - return - } - } - n.updateNodeType(x.Kind(), x, id) - n.checks = append(n.checks, cx) - // TODO(validatorType): see namesake TODO in conjunct.go. - k := x.Kind() - if k == TopKind { - n.hasTop = true - } - n.updateNodeType(k, x, id) - - case *Vertex: - // handled above. - - case Value: // *NullLit, *BoolLit, *NumLit, *StringLit, *BytesLit, *Builtin - if y := n.scalar; y != nil { - if b, ok := BinOp(ctx, EqualOp, x, y).(*Bool); !ok || !b.B { - n.reportConflict(x, y, x.Kind(), y.Kind(), n.scalarID, id) - } - // TODO: do we need to explicitly add again? - // n.scalar = nil - // n.addValueConjunct(c, BinOp(c, EqualOp, x, y)) - break - } - n.scalar = x - n.scalarID = id - if n.node.status >= conjuncts { - n.node.BaseValue = x - } - - default: - panic(fmt.Sprintf("unknown value type %T", x)) - } - - if n.lowerBound != nil && n.upperBound != nil { - if u := SimplifyBounds(ctx, n.kind, n.lowerBound, n.upperBound); u != nil { - if err := valueError(u); err != nil { - err.AddPosition(n.lowerBound) - err.AddPosition(n.upperBound) - err.AddClosedPositions(id) - } - n.lowerBound = nil - n.upperBound = nil - n.addValueConjunct(env, u, id) - } - } -} - func valueError(v Value) *ValueError { if v == nil { return nil @@ -2106,462 +801,8 @@ func valueError(v Value) *ValueError { return err } -// addStruct collates the declarations of a struct. -// -// addStruct fulfills two additional pivotal functions: -// 1. Implement vertex unification (this happens through De Bruijn indices -// combined with proper set up of Environments). -// 2. Implied closedness for definitions. -func (n *nodeContext) addStruct( - env *Environment, - s *StructLit, - closeInfo CloseInfo) { - - n.updateCyclicStatus(closeInfo) - - // NOTE: This is a crucial point in the code: - // Unification dereferencing happens here. The child nodes are set to - // an Environment linked to the current node. Together with the De Bruijn - // indices, this determines to which Vertex a reference resolves. - - childEnv := &Environment{ - Up: env, - Vertex: n.node, - } - - s.Init(n.ctx) - - if s.HasEmbed && !s.IsFile() { - closeInfo = closeInfo.SpawnGroup(nil) - } - - parent := n.node.AddStruct(s, childEnv, closeInfo) - closeInfo.IsClosed = false - - parent.Disable = true // disable until processing is done. - - for _, d := range s.Decls { - switch x := d.(type) { - case *Field: - if x.Label.IsString() && x.ArcType == ArcMember { - n.aStruct = s - n.aStructID = closeInfo - } - n.insertField(x.Label, x.ArcType, MakeConjunct(childEnv, x, closeInfo)) - - case *LetField: - arc := n.insertField(x.Label, ArcMember, MakeConjunct(childEnv, x, closeInfo)) - if x.IsMulti { - arc.MultiLet = x.IsMulti - } - - case *DynamicField: - n.aStruct = s - n.aStructID = closeInfo - n.dynamicFields = append(n.dynamicFields, envDynamic{childEnv, x, closeInfo, nil}) - - case *Comprehension: - n.insertComprehension(childEnv, x, closeInfo) - - case Expr: - // add embedding to optional - - // TODO(perf): only do this if addExprConjunct below will result in - // a fieldSet. Otherwise the entry will just be removed next. - id := closeInfo.SpawnEmbed(x) - id.decl = x - - c := MakeConjunct(childEnv, x, id) - n.addExprConjunct(c, partial) - - case *BulkOptionalField, *Ellipsis: - // Nothing to do here. Note that the presence of these fields do not - // excluded embedded scalars: only when they match actual fields - // does it exclude those. - - default: - panic("unreachable") - } - } - - if !s.HasEmbed { - n.aStruct = s - n.aStructID = closeInfo - } - - parent.Disable = false - -} - -// TODO(perf): if an arc is the only arc with that label added to a Vertex, and -// if there are no conjuncts of optional fields to be added, then the arc could -// be added as is until any of these conditions change. This would allow -// structure sharing in many cases. One should be careful, however, to -// recursively track arcs of previously unified evaluated vertices ot make this -// optimization meaningful. -// -// An alternative approach to avoid evaluating optional arcs (if we take that -// route) is to not recursively evaluate those arcs, even for Finalize. This is -// possible as it is not necessary to evaluate optional arcs to evaluate -// disjunctions. -func (n *nodeContext) insertField(f Feature, mode ArcType, x Conjunct) *Vertex { - ctx := n.ctx - if ctx.isDevVersion() { - return n.insertArc(f, mode, x, x.CloseInfo, true) - } - - arc, isNew := n.node.GetArc(ctx, f, mode) - if f.IsLet() && !isNew { - arc.MultiLet = true - return arc - } - if arc.hasConjunct(x) { - return arc - } - - switch { - case arc.state != nil: - arc.state.addConjunctDynamic(x) - - case arc.IsUnprocessed() || arc.status != finalized: - arc.addConjunctUnchecked(x) - - default: - n.addBottom(&Bottom{ - Code: IncompleteError, - Node: n.node, - Err: ctx.NewPosf(pos(x.Field()), - "cannot add field %s: was already used", - f.SelectorString(ctx)), - }) - } - return arc -} - func (n *nodeContext) insertFieldUnchecked(f Feature, mode ArcType, x Conjunct) *Vertex { - ctx := n.ctx - if ctx.isDevVersion() { - return n.insertArc(f, mode, x, x.CloseInfo, false) - } - - arc, isNew := n.node.GetArc(ctx, f, mode) - if f.IsLet() && !isNew { - arc.MultiLet = true - return arc - } - arc.addConjunctUnchecked(x) - return arc -} - -// expandOne adds dynamic fields to a node until a fixed point is reached. -// On each iteration, dynamic fields that cannot resolve due to incomplete -// values are skipped. They will be retried on the next iteration until no -// progress can be made. Note that a dynamic field may add more dynamic fields. -// -// forClauses are processed after all other clauses. A struct may be referenced -// before it is complete, meaning that fields added by other forms of injection -// may influence the result of a for clause _after_ it has already been -// processed. We could instead detect such insertion and feed it to the -// ForClause to generate another entry or have the for clause be recomputed. -// This seems to be too complicated and lead to iffy edge cases. -// TODO(errors): detect when a field is added to a struct that is already used -// in a for clause. -func (n *nodeContext) expandOne(state vertexStatus) (done bool) { - unreachableForDev(n.ctx) - - // Don't expand incomplete expressions if we detected a cycle. - if n.done() || (n.hasAnyCyclicConjunct && !n.hasNonCycle) { - return false - } - - var progress bool - - if progress = n.injectDynamic(); progress { - return true - } - - if progress = n.injectComprehensions(state); progress { - return true - } - - // Do expressions after comprehensions, as comprehensions can never - // refer to embedded scalars, whereas expressions may refer to generated - // fields if we were to allow attributes to be defined alongside - // scalars. - exprs := n.exprs - n.exprs = n.exprs[:0] - for _, x := range exprs { - n.addExprConjunct(x.c, state) - - // collect and or - } - if len(n.exprs) < len(exprs) { - return true - } - - // No progress, report error later if needed: unification with - // disjuncts may resolve this later on. - return false -} - -// injectDynamic evaluates and inserts dynamic declarations. -func (n *nodeContext) injectDynamic() (progress bool) { - unreachableForDev(n.ctx) - - ctx := n.ctx - k := 0 - - a := n.dynamicFields - for _, d := range n.dynamicFields { - var f Feature - x := d.field.Key - // Push state to capture and remove errors. - s := ctx.PushState(d.env, x.Source()) - v := ctx.evalState(x, oldOnly(finalized)) - b := ctx.PopState(s) - - if b != nil && b.IsIncomplete() { - d.err, _ = v.(*Bottom) - a[k] = d - k++ - continue - } - if b, _ := v.(*Bottom); b != nil { - n.addValueConjunct(nil, b, d.id) - continue - } - f = ctx.Label(d.field.Key, v) - if f.IsInt() { - n.addErr(ctx.NewPosf(pos(d.field.Key), "integer fields not supported")) - } - n.insertField(f, d.field.ArcType, MakeConjunct(d.env, d.field, d.id)) - } - - progress = k < len(n.dynamicFields) - - n.dynamicFields = a[:k] - - return progress -} - -// addLists evaluates the queued list conjuncts and inserts its arcs into the -// Vertex. -// -// TODO: association arrays: -// If an association array marker was present in a struct, create a struct node -// instead of a list node. In either case, a node may only have list fields -// or struct fields and not both. -// -// addLists should be run after the fixpoint expansion: -// - it enforces that comprehensions may not refer to the list itself -// - there may be no other fields within the list. -// -// TODO(embeddedScalars): for embedded scalars, there should be another pass -// of evaluation expressions after expanding lists. -func (n *nodeContext) addLists(state combinedFlags) (progress bool) { - if len(n.lists) == 0 && len(n.vLists) == 0 { - return false - } - - var oneOfTheLists Expr - var anID CloseInfo - - isOpen := true - max := 0 - var maxNode Expr - - if m, ok := n.node.BaseValue.(*ListMarker); ok { - isOpen = m.IsOpen - max = len(n.node.Arcs) - } - - c := n.ctx - - for _, l := range n.vLists { - // XXX: set hasNonCycle if appropriate. - - oneOfTheLists = l - - elems := l.Elems() - isClosed := l.IsClosedList() - - switch { - case len(elems) < max: - if isClosed { - n.invalidListLength(len(elems), max, l, maxNode) - continue - } - - case len(elems) > max: - if !isOpen { - n.invalidListLength(max, len(elems), maxNode, l) - continue - } - isOpen = !isClosed - max = len(elems) - maxNode = l - - case isClosed: - isOpen = false - maxNode = l - } - - for _, a := range elems { - if a.Conjuncts == nil { - n.insertField(a.Label, ArcMember, MakeRootConjunct(nil, a)) - continue - } - for _, c := range a.Conjuncts { - n.insertField(a.Label, ArcMember, c) - } - } - } - -outer: - // updateCyclicStatus may grow the list of values, so we cannot use range. - for i := 0; i < len(n.lists); i++ { - l := n.lists[i] - - n.updateCyclicStatus(l.id) - - if l.self { - n.node.LockArcs = true - } - - index := int64(0) - hasComprehension := false - for j, elem := range l.list.Elems { - switch x := elem.(type) { - case *Comprehension: - err := c.yield(nil, l.env, x, state, func(e *Environment) { - label, err := MakeLabel(x.Source(), index, IntLabel) - n.addErr(err) - index++ - c := MakeConjunct(e, x.Value, l.id) - n.insertField(label, ArcMember, c) - }) - hasComprehension = true - if err != nil { - if err.ForCycle && !l.self { - // The list has a comprehension that refers to the list - // itself. This means we should postpone evaluating this - // list until all other lists have been evaluated. - n.lists[i].ignore = true - l.self = true - n.lists = append(n.lists, l) - } else { - n.addBottom(err) - } - continue outer - } - - case *Ellipsis: - if j != len(l.list.Elems)-1 { - n.addErr(c.Newf("ellipsis must be last element in list")) - } - - n.lists[i].elipsis = x - - default: - label, err := MakeLabel(x.Source(), index, IntLabel) - n.addErr(err) - index++ // TODO: don't use insertField. - n.insertField(label, ArcMember, MakeConjunct(l.env, x, l.id)) - } - - // Terminate early in case of runaway comprehension. - if !isOpen && int(index) > max { - n.invalidListLength(max, len(l.list.Elems), maxNode, l.list) - continue outer - } - } - - oneOfTheLists = l.list - anID = l.id - - switch closed := n.lists[i].elipsis == nil; { - case int(index) < max: - if closed { - n.invalidListLength(int(index), max, l.list, maxNode) - continue - } - - case int(index) > max, - closed && isOpen, - (!closed == isOpen) && !hasComprehension: - max = int(index) - maxNode = l.list - isOpen = !closed - } - - n.lists[i].n = index - } - - // add additionalItem values to list and construct optionals. - elems := n.node.Elems() - for _, l := range n.vLists { - if !l.IsClosedList() { - continue - } - - newElems := l.Elems() - if len(newElems) >= len(elems) { - continue // error generated earlier, if applicable. - } - - for _, arc := range elems[len(newElems):] { - l.MatchAndInsert(c, arc) - } - } - - for _, l := range n.lists { - if l.elipsis == nil || l.ignore { - continue - } - - s := l.list.info - if s == nil { - s = &StructLit{Decls: []Decl{l.elipsis}} - s.Init(n.ctx) - l.list.info = s - } - info := n.node.AddStruct(s, l.env, l.id) - - for _, arc := range elems[l.n:] { - info.MatchAndInsert(c, arc) - } - } - - sources := []ast.Expr{} - // Add conjuncts for additional items. - for _, l := range n.lists { - if l.elipsis == nil || l.ignore { - continue - } - if src, _ := l.elipsis.Source().(ast.Expr); src != nil { - sources = append(sources, src) - } - } - - if m, ok := n.node.BaseValue.(*ListMarker); !ok { - n.node.setValue(c, partial, &ListMarker{ - Src: ast.NewBinExpr(token.AND, sources...), - IsOpen: isOpen, - }) - } else { - if m.Src != nil { - sources = append(sources, m.Src) - } - m.Src = ast.NewBinExpr(token.AND, sources...) - m.IsOpen = m.IsOpen && isOpen - } - - n.lists = n.lists[:0] - n.vLists = n.vLists[:0] - - n.updateNodeType(ListKind, oneOfTheLists, anID) - - return true + return n.insertArc(f, mode, x, x.CloseInfo, false) } func (n *nodeContext) invalidListLength(na, nb int, a, b Expr) { diff --git a/vendor/cuelang.org/go/internal/core/adt/expr.go b/vendor/cuelang.org/go/internal/core/adt/expr.go index cf25b71e7e..0a6cf0f3a1 100644 --- a/vendor/cuelang.org/go/internal/core/adt/expr.go +++ b/vendor/cuelang.org/go/internal/core/adt/expr.go @@ -43,26 +43,14 @@ type StructLit struct { // TODO: record the merge order somewhere. - // The below fields are redundant to Decls and are computed with Init. + // IsOpen is kept as it's used by ListMarker and some validations + IsOpen bool // has a ... - // field marks the optional conjuncts of all explicit Fields. - // Required Fields are marked as empty - Fields []FieldInfo - - Dynamic []*DynamicField - - // excluded are all literal fields that already exist. - Bulk []*BulkOptionalField - - Additional []*Ellipsis - HasEmbed bool - IsOpen bool // has a ... + // initialized is kept as it's used in the Init method and unify.go initialized bool - types OptionalType - - // administrative fields like hasreferences. - // hasReferences bool + // isComprehension is kept as it's used in comprehension.go and conjunct.go + isComprehension bool } func (o *StructLit) IsFile() bool { @@ -70,17 +58,9 @@ func (o *StructLit) IsFile() bool { return ok } -type FieldInfo struct { - Label Feature -} - -func (x *StructLit) HasOptional() bool { - return x.types&(HasPattern|HasAdditional) != 0 -} - func (x *StructLit) Source() ast.Node { return x.Src } -func (x *StructLit) evaluate(c *OpContext, state combinedFlags) Value { +func (x *StructLit) evaluate(c *OpContext, state Flags) Value { e := c.Env(0) v := c.newInlineVertex(e.Vertex, nil, Conjunct{e, x, c.ci}) // evaluate may not finalize a field, as the resulting value may be @@ -113,88 +93,11 @@ func (x *StructLit) evaluate(c *OpContext, state combinedFlags) Value { return v } -// TODO: remove this method -func (o *StructLit) MarkField(f Feature) { - o.Fields = append(o.Fields, FieldInfo{Label: f}) -} - func (o *StructLit) Init(ctx *OpContext) { if o.initialized { return } o.initialized = true - - if ctx.isDevVersion() { - return - } - - for _, d := range o.Decls { - switch x := d.(type) { - case *Field: - if o.fieldIndex(x.Label) < 0 { - o.Fields = append(o.Fields, FieldInfo{Label: x.Label}) - } - if x.ArcType > ArcMember { - o.types |= HasField - } - - case *LetField: - if o.fieldIndex(x.Label) >= 0 { - panic("duplicate let identifier") - } - o.Fields = append(o.Fields, FieldInfo{Label: x.Label}) - - case *DynamicField: - o.Dynamic = append(o.Dynamic, x) - o.types |= HasDynamic - - case Expr: - o.HasEmbed = true - - case *Comprehension: - o.HasEmbed = true - - case *LetClause: - o.HasEmbed = true - - case *BulkOptionalField: - o.Bulk = append(o.Bulk, x) - o.types |= HasPattern - switch x.Filter.(type) { - case *BasicType, *Top: - default: - o.types |= HasComplexPattern - } - - case *Ellipsis: - switch x.Value.(type) { - case nil, *Top: - o.IsOpen = true - o.types |= IsOpen - - default: - // TODO: consider only adding for non-top. - o.types |= HasAdditional - } - o.Additional = append(o.Additional, x) - - default: - panic("unreachable") - } - } -} - -func (o *StructLit) fieldIndex(f Feature) int { - for i := range o.Fields { - if o.Fields[i].Label == f { - return i - } - } - return -1 -} - -func (o *StructLit) OptionalTypes() OptionalType { - return o.types } // FIELDS @@ -302,8 +205,6 @@ type ListLit struct { // scalars, comprehensions, ...T Elems []Elem - - info *StructLit // Shared closedness info. } func (x *ListLit) Source() ast.Node { @@ -313,7 +214,7 @@ func (x *ListLit) Source() ast.Node { return x.Src } -func (x *ListLit) evaluate(c *OpContext, state combinedFlags) Value { +func (x *ListLit) evaluate(c *OpContext, state Flags) Value { e := c.Env(0) // Pass conditions but at least set fieldSetKnown. v := c.newInlineVertex(e.Vertex, nil, Conjunct{e, x, c.ci}) @@ -374,17 +275,6 @@ type Num struct { func (x *Num) Source() ast.Node { return x.Src } func (x *Num) Kind() Kind { return x.K } -// TODO: do we still need this? -// func (x *Num) Specialize(k Kind) Value { -// k = k & x.K -// if k == x.K { -// return x -// } -// y := *x -// y.K = k -// return &y -// } - // String is a string value. It can be used as a Value and Expr. type String struct { Src ast.Node @@ -418,12 +308,9 @@ func (x *ListMarker) Kind() Kind { return ListKind } func (x *ListMarker) node() {} type StructMarker struct { - // NeedClose is used to signal that the evaluator should close this struct. - // It is only set by the close builtin. - // TODO(evalv3: remove this field. Once we removed this, and also introduced - // open by default lists, we can get rid of StructMarker and ListMarker + // TODO: once we introduce open by default lists, + // we can get rid of StructMarker and ListMarker // in its entirety in favor of using type bit masks. - NeedClose bool } func (x *StructMarker) Source() ast.Node { return nil } @@ -461,17 +348,6 @@ func (x *BasicType) Source() ast.Node { } func (x *BasicType) Kind() Kind { return x.K } -// TODO: do we still need this? -// func (x *BasicType) Specialize(k Kind) Value { -// k = x.K & k -// if k == x.K { -// return x -// } -// y := *x -// y.K = k -// return &y -// } - // TODO: should we use UnaryExpr for Bound now we have BoundValue? // BoundExpr represents an unresolved unary comparator. @@ -491,20 +367,24 @@ func (x *BoundExpr) Source() ast.Node { return x.Src } -func (x *BoundExpr) evaluate(ctx *OpContext, state combinedFlags) Value { +func (x *BoundExpr) evaluate(ctx *OpContext, state Flags) Value { // scalarKnown is used here to ensure we know the value. The result does // not have to be concrete, though. - v := ctx.value(x.Expr, require(partial, scalarKnown)) + v := ctx.value(x.Expr, Flags{ + status: partial, + condition: scalarKnown, + mode: yield, + }) if isError(v) { return v } switch k := v.Kind(); k { case IntKind, FloatKind, NumberKind, StringKind, BytesKind: - case NullKind: - if x.Op != NotEqualOp { + case NullKind, StructKind, ListKind: + if x.Op != NotEqualOp && x.Op != EqualOp { err := ctx.NewPosf(pos(x.Expr), - "cannot use null for bound %s", x.Op) + "cannot use %s for bound %s", k, x.Op) return &Bottom{ Err: err, Node: ctx.vertex, @@ -512,8 +392,8 @@ func (x *BoundExpr) evaluate(ctx *OpContext, state combinedFlags) Value { } default: mask := IntKind | FloatKind | NumberKind | StringKind | BytesKind - if x.Op == NotEqualOp { - mask |= NullKind + if x.Op == NotEqualOp || x.Op == EqualOp { + mask |= NullKind | StructKind | ListKind } if k&mask != 0 { ctx.addErrf(IncompleteError, token.NoPos, // TODO(errors): use ctx.pos()? @@ -535,6 +415,10 @@ func (x *BoundExpr) evaluate(ctx *OpContext, state combinedFlags) Value { return &BoundValue{x.Src, x.Op, v} } + if !ctx.SimplifyValidators { + goto finalCheck + } + // This simplifies boundary expressions. It is an alternative to an // evaluation strategy that makes nodes increasingly more specific. // @@ -608,6 +492,8 @@ func (x *BoundExpr) evaluate(ctx *OpContext, state combinedFlags) Value { return nil } } + +finalCheck: if v.Concreteness() > Concrete { // TODO(errors): analyze dependencies of x.Expr to get positions. ctx.addErrf(IncompleteError, token.NoPos, // TODO(errors): use ctx.pos()? @@ -645,12 +531,12 @@ func (x *BoundValue) Kind() Kind { func (x *BoundValue) validate(c *OpContext, y Value) *Bottom { a := y // Can be list or struct. - b := c.scalar(x.Value) + b := x.Value if c.HasErr() { return c.Err() } - switch v := BinOp(c, x.Op, a, b).(type) { + switch v := BinOp(c, x, x.Op, a, b).(type) { case *Bottom: return v @@ -737,7 +623,7 @@ func (x *NodeLink) Kind() Kind { } func (x *NodeLink) Source() ast.Node { return x.Node.Source() } -func (x *NodeLink) resolve(c *OpContext, state combinedFlags) *Vertex { +func (x *NodeLink) resolve(c *OpContext, state Flags) *Vertex { return x.Node } @@ -757,7 +643,7 @@ func (x *FieldReference) Source() ast.Node { return x.Src } -func (x *FieldReference) resolve(c *OpContext, state combinedFlags) *Vertex { +func (x *FieldReference) resolve(c *OpContext, state Flags) *Vertex { n := c.relNode(x.UpCount) pos := pos(x) return c.lookup(n, pos, x.Label, state) @@ -771,7 +657,7 @@ func (x *FieldReference) resolve(c *OpContext, state combinedFlags) *Vertex { type ValueReference struct { Src *ast.Ident UpCount int32 - Label Feature // for informative purposes + Label Feature // for informative purposes. } func (x *ValueReference) Source() ast.Node { @@ -781,7 +667,7 @@ func (x *ValueReference) Source() ast.Node { return x.Src } -func (x *ValueReference) resolve(c *OpContext, state combinedFlags) *Vertex { +func (x *ValueReference) resolve(c *OpContext, state Flags) *Vertex { if x.UpCount == 0 { return c.vertex } @@ -808,7 +694,7 @@ func (x *LabelReference) Source() ast.Node { return x.Src } -func (x *LabelReference) evaluate(ctx *OpContext, state combinedFlags) Value { +func (x *LabelReference) evaluate(ctx *OpContext, state Flags) Value { label := ctx.relLabel(x.UpCount) if label == 0 { // There is no label. This may happen if a LabelReference is evaluated @@ -852,15 +738,23 @@ func (x *DynamicReference) Source() ast.Node { func (x *DynamicReference) EvaluateLabel(ctx *OpContext, env *Environment) Feature { env = env.up(ctx, x.UpCount) frame := ctx.PushState(env, x.Src) - v := ctx.value(x.Label, require(partial, scalarKnown)) + v := ctx.value(x.Label, Flags{ + status: partial, + condition: scalarKnown, + mode: yield, + }) ctx.PopState(frame) return ctx.Label(x, v) } -func (x *DynamicReference) resolve(ctx *OpContext, state combinedFlags) *Vertex { +func (x *DynamicReference) resolve(ctx *OpContext, state Flags) *Vertex { e := ctx.Env(x.UpCount) frame := ctx.PushState(e, x.Src) - v := ctx.value(x.Label, require(partial, scalarKnown)) + v := ctx.value(x.Label, Flags{ + status: partial, + condition: scalarKnown, + mode: yield, + }) ctx.PopState(frame) f := ctx.Label(x.Label, v) return ctx.lookup(e.Vertex, pos(x), f, state) @@ -886,7 +780,7 @@ func (x *ImportReference) Source() ast.Node { return x.Src } -func (x *ImportReference) resolve(ctx *OpContext, state combinedFlags) *Vertex { +func (x *ImportReference) resolve(ctx *OpContext, state Flags) *Vertex { path := x.ImportPath.StringValue(ctx) v := ctx.Runtime.LoadImport(path) if v == nil { @@ -914,16 +808,13 @@ func (x *LetReference) Source() ast.Node { return x.Src } -func (x *LetReference) resolve(ctx *OpContext, state combinedFlags) *Vertex { +func (x *LetReference) resolve(ctx *OpContext, state Flags) *Vertex { e := ctx.Env(x.UpCount) n := e.Vertex // No need to Unify n, as Let references can only result from evaluating // an expression within n, in which case evaluation must already have // started. - if n.status < evaluating && !ctx.isDevVersion() { - panic("unexpected node state < Evaluating") - } arc := ctx.lookup(n, pos(x), x.Label, state) if arc == nil { @@ -946,13 +837,17 @@ func (x *LetReference) resolve(ctx *OpContext, state combinedFlags) *Vertex { // In other words, a Vertex is not necessarily erroneous when a let // field contained in that Vertex is erroneous. + // NOTE: eval v2 used to finalize here. // We should only partly finalize the result here as it is not safe to // finalize any references made by the let. - if !ctx.isDevVersion() { - arc.Finalize(ctx) - } + b := arc.Bottom() - if !arc.MultiLet && b == nil { + // Check if the arc is currently being evaluated to prevent infinite + // recursion when a let references itself through a field selector. + // If the arc has a running state, we must use the cache mechanism + // to properly detect and handle cycles. + arcState := arc.getState(ctx) + if !arc.MultiLet && (b == nil || isCyclePlaceholder(b)) && arcState == nil { return arc } @@ -969,6 +864,7 @@ func (x *LetReference) resolve(ctx *OpContext, state combinedFlags) *Vertex { _, isGroup := expr.(*ConjunctGroup) ctx.Assertf(pos(expr), !isGroup, "unexpected number of expressions") + // TODO(mem): add counter for let cache usage. key := cacheKey{expr, arc} v, ok := e.cache[key] if !ok { @@ -988,21 +884,17 @@ func (x *LetReference) resolve(ctx *OpContext, state combinedFlags) *Vertex { } v = n e.cache[key] = n - if ctx.isDevVersion() { - nc := n.getState(ctx) - // TODO: unlike with the old evaluator, we do not allow the first - // cycle to be skipped. Doing so can lead to hanging evaluation. - // As the cycle detection works slightly differently in the new - // evaluator (and is not entirely completed), this can happen. We - // should revisit this once we have completed the structural cycle - // detection. - // nc.hasNonCycle = true - // Allow a first cycle to be skipped. - nc.free() - } else { - nc := n.getNodeContext(ctx, 0) - nc.hasNonCycle = true // Allow a first cycle to be skipped. - } + // TODO(mem): enable again once we implement memory management. + // nc := n.getState(ctx) + // TODO: unlike with the old evaluator, we do not allow the first + // cycle to be skipped. Doing so can lead to hanging evaluation. + // As the cycle detection works slightly differently in the new + // evaluator (and is not entirely completed), this can happen. We + // should revisit this once we have completed the structural cycle + // detection. + // nc.hasNonCycle = true + // Allow a first cycle to be skipped. + // nc.free() // Parents cannot add more conjuncts to a let expression, so set of // conjuncts is always complete. @@ -1034,17 +926,15 @@ func (x *SelectorExpr) Source() ast.Node { return x.Src } -func (x *SelectorExpr) resolve(c *OpContext, state combinedFlags) *Vertex { - n := c.node(x, x.X, x.Sel.IsRegular(), require(partial, needFieldSetKnown)) +func (x *SelectorExpr) resolve(c *OpContext, state Flags) *Vertex { + n := c.node(x, x.X, x.Sel.IsRegular(), Flags{ + status: partial, + condition: needFieldSetKnown, + mode: yield, + }) if n == emptyNode { return n } - if n.status == partial && !c.isDevVersion() { - if b := n.state.incompleteErrors(false); b != nil && b.Code < CycleError { - c.AddBottom(b) - return n - } - } // TODO(eval): dynamic nodes should be fully evaluated here as the result // will otherwise be discarded and there will be no other chance to check // the struct is valid. @@ -1069,19 +959,21 @@ func (x *IndexExpr) Source() ast.Node { return x.Src } -func (x *IndexExpr) resolve(ctx *OpContext, state combinedFlags) *Vertex { +func (x *IndexExpr) resolve(ctx *OpContext, state Flags) *Vertex { // TODO: support byte index. - n := ctx.node(x, x.X, true, require(partial, needFieldSetKnown)) - i := ctx.value(x.Index, require(partial, scalarKnown)) + n := ctx.node(x, x.X, true, Flags{ + status: partial, + condition: needFieldSetKnown, + mode: yield, + }) + i := ctx.value(x.Index, Flags{ + status: partial, + condition: scalarKnown, + mode: yield, + }) if n == emptyNode { return n } - if n.status == partial && !ctx.isDevVersion() { - if b := n.state.incompleteErrors(false); b != nil && b.Code < CycleError { - ctx.AddBottom(b) - return n - } - } // TODO(eval): dynamic nodes should be fully evaluated here as the result // will otherwise be discarded and there will be no other chance to check // the struct is valid. @@ -1118,10 +1010,14 @@ func (x *SliceExpr) Source() ast.Node { return x.Src } -func (x *SliceExpr) evaluate(c *OpContext, state combinedFlags) Value { +func (x *SliceExpr) evaluate(c *OpContext, state Flags) Value { // TODO: strides - v := c.value(x.X, require(partial, fieldSetKnown)) + v := c.value(x.X, Flags{ + status: partial, + condition: fieldSetKnown, + mode: yield, + }) const as = "slice index" switch v := v.(type) { @@ -1138,10 +1034,18 @@ func (x *SliceExpr) evaluate(c *OpContext, state combinedFlags) Value { hi = uint64(len(v.Arcs)) ) if x.Lo != nil { - lo = c.uint64(c.value(x.Lo, require(partial, scalarKnown)), as) + lo = c.uint64(c.value(x.Lo, Flags{ + status: partial, + condition: scalarKnown, + mode: yield, + }), as) } if x.Hi != nil { - hi = c.uint64(c.value(x.Hi, require(partial, scalarKnown)), as) + hi = c.uint64(c.value(x.Hi, Flags{ + status: partial, + condition: scalarKnown, + mode: yield, + }), as) if hi > uint64(len(v.Arcs)) { return c.NewErrf("index %d out of range", hi) } @@ -1182,10 +1086,18 @@ func (x *SliceExpr) evaluate(c *OpContext, state combinedFlags) Value { hi = uint64(len(v.B)) ) if x.Lo != nil { - lo = c.uint64(c.value(x.Lo, require(partial, scalarKnown)), as) + lo = c.uint64(c.value(x.Lo, Flags{ + status: partial, + condition: scalarKnown, + mode: yield, + }), as) } if x.Hi != nil { - hi = c.uint64(c.value(x.Hi, require(partial, scalarKnown)), as) + hi = c.uint64(c.value(x.Hi, Flags{ + status: partial, + condition: scalarKnown, + mode: yield, + }), as) if hi > uint64(len(v.B)) { return c.NewErrf("index %d out of range", hi) } @@ -1218,10 +1130,14 @@ func (x *Interpolation) Source() ast.Node { return x.Src } -func (x *Interpolation) evaluate(c *OpContext, state combinedFlags) Value { +func (x *Interpolation) evaluate(c *OpContext, state Flags) Value { buf := bytes.Buffer{} for _, e := range x.Parts { - v := c.value(e, require(partial, scalarKnown)) + v := c.value(e, Flags{ + status: partial, + condition: scalarKnown, + mode: yield, + }) if x.K == BytesKind { buf.Write(c.ToBytes(v)) } else { @@ -1261,11 +1177,15 @@ func (x *UnaryExpr) Source() ast.Node { return x.Src } -func (x *UnaryExpr) evaluate(c *OpContext, state combinedFlags) Value { +func (x *UnaryExpr) evaluate(c *OpContext, state Flags) Value { if !c.concreteIsPossible(x.Op, x.X) { return nil } - v := c.value(x.X, require(partial, scalarKnown)) + v := c.value(x.X, Flags{ + status: partial, + condition: scalarKnown, + mode: yield, + }) if isError(v) { return v } @@ -1322,7 +1242,7 @@ func (x *BinaryExpr) Source() ast.Node { return x.Src } -func (x *BinaryExpr) evaluate(c *OpContext, state combinedFlags) Value { +func (x *BinaryExpr) evaluate(c *OpContext, state Flags) Value { env := c.Env(0) if x.Op == AndOp { v := c.newInlineVertex(nil, nil, makeAnonymousConjunct(env, x, c.ci.Refs)) @@ -1334,7 +1254,7 @@ func (x *BinaryExpr) evaluate(c *OpContext, state combinedFlags) Value { // to the required state. If the struct is already dynamic, we will // evaluate the struct regardless to ensure that cycle reporting // keeps working. - if env.Vertex.IsDynamic || c.inValidator > 0 { + if (c.inDetached == 0 && env.Vertex.IsDynamic) || c.inValidator > 0 { v.Finalize(c) } else { v.CompleteArcsOnly(c) @@ -1371,22 +1291,46 @@ func (x *BinaryExpr) evaluate(c *OpContext, state combinedFlags) Value { return err } - return BinOp(c, x.Op, left, right) + return BinOp(c, x, x.Op, left, right) +} + +// OpenExpr represents the ... operator to disable typo checking. +// +// #A... +type OpenExpr struct { + Src *ast.PostfixExpr + X Expr +} + +func (x *OpenExpr) Source() ast.Node { + if x.Src == nil { + return nil + } + return x.Src +} + +func (x *OpenExpr) evaluate(c *OpContext, state Flags) Value { + c.ci.Opened = true + return c.evalState(x.X, state) } -func (c *OpContext) validate(env *Environment, src ast.Node, x Expr, op Op, flags combinedFlags) (r Value) { - state := flags.vertexStatus() +func (c *OpContext) validate(env *Environment, src ast.Node, x Expr, op Op, flags Flags) (r Value) { + state := flags.status s := c.PushState(env, src) match := op != EqualOp // non-error case - // Like value(), but retain the original, unwrapped result. c.inValidator++ - req := flags - req = final(state, needTasksDone) + // Note that evalState may call yield, so we need to balance the counter + // with a defer. + defer func() { c.inValidator-- }() + req := Flags{ + status: state, + condition: needTasksDone, + mode: finalize, + } v := c.evalState(x, req) - c.inValidator-- u, _ := c.getDefault(v) u = Unwrap(u) @@ -1410,7 +1354,11 @@ func (c *OpContext) validate(env *Environment, src ast.Node, x Expr, op Op, flag return nil case IncompleteError: - c.evalState(x, oldOnly(finalized)) + c.evalState(x, Flags{ + status: finalized, + condition: allKnown, + mode: ignore, + }) // We have a nonmonotonic use of a failure. Referenced fields should // not be added anymore. @@ -1434,20 +1382,7 @@ func (c *OpContext) validate(env *Environment, src ast.Node, x Expr, op Op, flag match = op == EqualOp break } - if v.status == evaluatingArcs { - unreachableForDev(c) // Eval V2 logic - - // We have a cycle, which may be an error. Cycle errors may occur - // in chains that are themselves not a cycle. It suffices to check - // for non-monotonic results at the end for this particular path. - // TODO(perf): finding the right path through such comprehensions - // may be expensive. Finding a path in a directed graph is O(n), - // though, so we should ensure that the implementation conforms to - // this. - c.verifyNonMonotonicResult(env, x, true) - match = op == EqualOp - break - } + v.Finalize(c) switch { @@ -1483,7 +1418,11 @@ func (c *OpContext) validate(env *Environment, src ast.Node, x Expr, op Op, flag match = op == EqualOp } - c.evalState(x, require(state, needTasksDone)) + c.evalState(x, Flags{ + status: state, + condition: needTasksDone, + mode: yield, + }) } c.PopState(s) @@ -1530,17 +1469,25 @@ func (x *CallExpr) Source() ast.Node { return x.Src } -func (x *CallExpr) evaluate(c *OpContext, state combinedFlags) Value { - fun := c.value(x.Fun, require(partial, concreteKnown)) - var b *Builtin +func (x *CallExpr) evaluate(c *OpContext, state Flags) Value { + call := &CallContext{ + ctx: c, + call: x, + } + + fun := c.value(x.Fun, Flags{ + status: partial, + condition: concreteKnown, + mode: yield, + }) switch f := fun.(type) { case *Builtin: - b = f + call.builtin = f if f.RawFunc != nil { - if !b.checkArgs(c, pos(x), len(x.Args)) { + if !call.builtin.checkArgs(c, pos(x), len(x.Args)) { return nil } - return f.RawFunc(c, x.Args) + return f.RawFunc(call) } case *BuiltinValidator: @@ -1556,24 +1503,39 @@ func (x *CallExpr) evaluate(c *OpContext, state combinedFlags) Value { return &v default: - b = f.Builtin + call.builtin = f.Builtin } default: c.AddErrf("cannot call non-function %s (type %s)", x.Fun, kind(fun)) return nil } + + // Arguments to functions are open. This mostly matters for NonConcrete + // builtins. + saved := c.ci + c.ci.FromDef = false + c.ci.FromEmbed = false + defer func() { + c.ci.FromDef = saved.FromDef + c.ci.FromEmbed = saved.FromEmbed + }() + args := []Value{} for i, a := range x.Args { saved := c.errs c.errs = nil // XXX: XXX: clear id.closeContext per argument and remove from runTask? - runMode := state.runMode() - cond := state.conditions() + runMode := state.mode + cond := state.condition var expr Value - if b.NonConcrete { - state = combineMode(cond, runMode).withVertexStatus(state.vertexStatus()) + if call.builtin.NonConcrete { + state = Flags{ + status: state.status, + condition: cond, + mode: runMode, + } expr = c.evalState(a, state) } else { cond |= fieldSetKnown | concreteKnown @@ -1585,7 +1547,11 @@ func (x *CallExpr) evaluate(c *OpContext, state combinedFlags) Value { if runMode == finalize { cond |= disjunctionTask } - state = combineMode(cond, runMode).withVertexStatus(state.vertexStatus()) + state = Flags{ + status: state.status, + condition: cond, + mode: runMode, + } expr = c.value(a, state) } @@ -1610,14 +1576,15 @@ func (x *CallExpr) evaluate(c *OpContext, state combinedFlags) Value { if c.HasErr() { return nil } - if b.IsValidator(len(args)) { - return &BuiltinValidator{x, b, args} + if call.builtin.IsValidator(len(args)) { + return &BuiltinValidator{x, call.builtin, args} } - result := b.call(c, pos(x), false, args) + call.args = args + result := call.builtin.call(call) if result == nil { return nil } - v, ci := c.evalStateCI(result, state.withVertexStatus(partial)) + v, ci := c.evalStateCI(result, Flags{status: partial, condition: state.condition, mode: state.mode}) c.ci = ci return v } @@ -1632,7 +1599,7 @@ type Builtin struct { // arguments. By default, all arguments are checked to be concrete. NonConcrete bool - Func func(c *OpContext, args []Value) Expr + Func func(call *CallContext) Expr // RawFunc gives low-level control to CUE's internals for builtins. // It should be used when fine control over the evaluation process is @@ -1640,7 +1607,12 @@ type Builtin struct { // gives them fine control over how exactly such value gets evaluated. // A RawFunc may pass CycleInfo, errors and other information through // the Context. - RawFunc func(c *OpContext, args []Expr) Value + // + // TODO: consider merging Func and RawFunc into a single field again. + RawFunc func(call *CallContext) Value + + // Added indicates as of which language version this builtin can be used. + Added string Package Feature Name string @@ -1721,15 +1693,18 @@ func (x *Builtin) checkArgs(c *OpContext, p token.Pos, numArgs int) bool { return true } -func (x *Builtin) call(c *OpContext, p token.Pos, validate bool, args []Value) Expr { +func (x *Builtin) call(call *CallContext) Expr { + c := call.ctx + p := call.Pos() + fun := x // right now always x. - if !x.checkArgs(c, p, len(args)) { + if !x.checkArgs(c, p, len(call.args)) { return nil } - for i := len(args); i < len(x.Params); i++ { - args = append(args, x.Params[i].Default()) + for i := len(call.args); i < len(x.Params); i++ { + call.args = append(call.args, x.Params[i].Default()) } - for i, a := range args { + for i, a := range call.args { if x.Params[i].Kind() == BottomKind { continue } @@ -1738,7 +1713,7 @@ func (x *Builtin) call(c *OpContext, p token.Pos, validate bool, args []Value) E } if k := kind(a); x.Params[i].Kind()&k == BottomKind { code := EvalError - b, _ := args[i].(*Bottom) + b, _ := call.args[i].(*Bottom) if b != nil { code = b.Code } @@ -1759,15 +1734,27 @@ func (x *Builtin) call(c *OpContext, p token.Pos, validate bool, args []Value) E a, v, i+1, fun) return nil } - args[i] = n + call.args[i] = n } } + + // Arguments to functions are open. This mostly matters for NonConcrete + // builtins. saved := c.IsValidator - c.IsValidator = validate - ret := x.Func(c, args) - c.IsValidator = saved + c.IsValidator = call.isValidator + ci := c.ci + c.ci.FromEmbed = false + c.ci.FromDef = false + defer func() { + c.ci.FromDef = ci.FromDef + c.ci.FromEmbed = ci.FromEmbed + c.IsValidator = saved + }() - return ret + if x.RawFunc != nil { + return x.RawFunc(call) + } + return x.Func(call) } func (x *Builtin) Source() ast.Node { return nil } @@ -1805,14 +1792,27 @@ func (x *BuiltinValidator) validate(c *OpContext, v Value) *Bottom { args[0] = v copy(args[1:], x.Args) - return validateWithBuiltin(c, x.Pos(), x.Builtin, args) + call := &CallContext{ + ctx: c, + call: x.Src, + builtin: x.Builtin, + args: args, + isValidator: true, + } + + return validateWithBuiltin(call) } -func validateWithBuiltin(c *OpContext, src token.Pos, b *Builtin, args []Value) *Bottom { +func validateWithBuiltin(call *CallContext) *Bottom { var severeness ErrorCode var err errors.Error - res := b.call(c, src, true, args) + c := call.ctx + b := call.builtin + src := call.Pos() + arg0 := call.Value(0) + + res := call.builtin.call(call) switch v := res.(type) { case nil: return nil @@ -1835,31 +1835,32 @@ func validateWithBuiltin(c *OpContext, src token.Pos, b *Builtin, args []Value) // If the validator returns an error and we already had an error, just // return the original error. - if b, ok := Unwrap(args[0]).(*Bottom); ok { + if b, ok := Unwrap(call.Value(0)).(*Bottom); ok { return b } // failed: + // TODO(mvdan): building this buffer should be part of the error format and arguments, + // e.g. any logic needed here can be wrapped in an [fmt.Stringer]. var buf bytes.Buffer buf.WriteString(b.qualifiedName(c)) // Note: when the builtin accepts non-concrete arguments, omit them because // they can easily be very large. - if !b.NonConcrete && len(args) > 1 { + if !b.NonConcrete && call.NumParams() > 1 { // use NumArgs instead buf.WriteString("(") - for i, a := range args[1:] { + // TODO: use accessor instead of call.arg + for i, a := range call.args[1:] { if i > 0 { _, _ = buf.WriteString(", ") } - buf.WriteString(c.Str(a)) + buf.WriteString(c.String(a)) } buf.WriteString(")") } - vErr := c.NewPosf(src, "invalid value %s (does not satisfy %s)", args[0], buf.String()) + vErr := c.NewPosf(src, "invalid value %s (does not satisfy %s)", arg0, buf.String()) - for _, v := range args { - vErr.AddPosition(v) - } + call.AddPositions(vErr) return &Bottom{ Code: severeness, @@ -1868,7 +1869,7 @@ func validateWithBuiltin(c *OpContext, src token.Pos, b *Builtin, args []Value) } } -// A Disjunction represents a disjunction, where each disjunct may or may not +// A DisjunctionExpr represents a disjunction, where each disjunct may or may not // be marked as a default. type DisjunctionExpr struct { Src *ast.BinaryExpr @@ -1890,7 +1891,7 @@ func (x *DisjunctionExpr) Source() ast.Node { return x.Src } -func (x *DisjunctionExpr) evaluate(c *OpContext, state combinedFlags) Value { +func (x *DisjunctionExpr) evaluate(c *OpContext, state Flags) Value { e := c.Env(0) v := c.newInlineVertex(nil, nil, Conjunct{e, x, c.ci}) v.Finalize(c) // TODO: also partial okay? @@ -1915,8 +1916,8 @@ func (x *Conjunction) Kind() Kind { return k } -// A disjunction is a disjunction of values. It is the result of expanding -// a DisjunctionExpr if the expression cannot be represented as a single value. +// A Disjunction is a disjunction of values. It is the result of expanding +// a [DisjunctionExpr] if the expression cannot be represented as a single value. type Disjunction struct { Src ast.Expr @@ -1956,15 +1957,8 @@ type Comprehension struct { // The type of field as which the comprehension is added. arcType ArcType - // The closeContext into which the comprehension is added. Upon a successful - // completion of the comprehension, the arcType should be updated in this - // closeContext. After this is done, the corresponding parent closeContext - // must be closed. - arcCC *closeContext - - // This is incremented by the Comprehension upon creation, and decremented - // once it is known whether the comprehension succeeded. - cc *closeContext + // Kind indicates the possible kind of Value. + kind Kind // Only used for partial comprehensions. comp *envComprehension @@ -2023,7 +2017,11 @@ func (x *ForClause) Source() ast.Node { } func (c *OpContext) forSource(x Expr) *Vertex { - state := attempt(conjuncts, needFieldSetKnown) + state := Flags{ + status: conjuncts, + condition: needFieldSetKnown, + mode: attemptOnly, + } // TODO: always get the vertex. This allows a whole bunch of trickery // down the line. @@ -2032,14 +2030,14 @@ func (c *OpContext) forSource(x Expr) *Vertex { c.inDetached-- node, ok := v.(*Vertex) - if ok && c.isDevVersion() { + if ok { // We do not request to "yield" here, but rather rely on the // call-by-need behavior in combination with the freezing mechanism. // TODO: this seems a bit fragile. At some point we need to make this // more robust by moving to a pure call-by-need mechanism, for instance. // TODO: using attemptOnly here will remove the cyclic reference error // of comprehension.t1.ok (which also errors in V2), - node.unify(c, state.conditions(), finalize) + node.unify(c, Flags{condition: state.condition, mode: finalize, checkTypos: true}) } v, ok = c.getDefault(v) @@ -2089,16 +2087,14 @@ func (c *OpContext) forSource(x Expr) *Vertex { return emptyNode } } - if c.isDevVersion() { - kind := v.Kind() - // At this point it is possible that the Vertex represents an incomplete - // struct or list, which is the case if it may be struct or list, but - // is also at least some other type, such as is the case with top. - if kind&(StructKind|ListKind) != 0 && kind != StructKind && kind != ListKind { - c.addErrf(IncompleteError, pos(x), - "cannot range over %s (incomplete type %s)", x, kind) - return emptyNode - } + kind := v.Kind() + // At this point it is possible that the Vertex represents an incomplete + // struct or list, which is the case if it may be struct or list, but + // is also at least some other type, such as is the case with top. + if kind&(StructKind|ListKind) != 0 && kind != StructKind && kind != ListKind { + c.addErrf(IncompleteError, pos(x), + "cannot range over %s (incomplete type %s)", x, kind) + return emptyNode } return node @@ -2108,25 +2104,8 @@ func (x *ForClause) yield(s *compState) { c := s.ctx n := c.forSource(x.Src) - if c.isDevVersion() { - if s := n.getState(c); s != nil { - s.freeze(fieldSetKnown) - } - } else { - if n.status == evaluating && !n.LockArcs { - c.AddBottom(&Bottom{ - Code: CycleError, - ForCycle: true, - Value: n, - Node: n, - Err: errors.Newf(pos(x.Src), "comprehension source references itself"), - }) - return - } - if c.HasErr() { - return - } - n.LockArcs = true + if s := n.getState(c); s != nil { + s.freeze(fieldSetKnown) } for _, a := range n.Arcs { @@ -2134,18 +2113,9 @@ func (x *ForClause) yield(s *compState) { continue } - if c.isDevVersion() { - // TODO(evalv3): See comment in StructLit.evaluate. - if state := a.getState(c); state != nil { - state.process(arcTypeKnown, attemptOnly) - } - } else { - if !a.isDefined() { - a.Finalize(c) - } - if !a.definitelyExists() { - continue - } + // See comment in StructLit.evaluate. + if state := a.getState(c); state != nil { + state.process(arcTypeKnown, attemptOnly) } switch a.ArcType { @@ -2217,7 +2187,11 @@ func (x *IfClause) Source() ast.Node { func (x *IfClause) yield(s *compState) { ctx := s.ctx - if ctx.BoolValue(ctx.value(x.Condition, require(s.state, scalarKnown))) { + if ctx.BoolValue(ctx.value(x.Condition, Flags{ + status: s.state, + condition: scalarKnown, + mode: yield, + })) { s.yield(ctx.e) } } diff --git a/vendor/cuelang.org/go/internal/core/adt/feature.go b/vendor/cuelang.org/go/internal/core/adt/feature.go index 5b9528e3a0..5e1749703c 100644 --- a/vendor/cuelang.org/go/internal/core/adt/feature.go +++ b/vendor/cuelang.org/go/internal/core/adt/feature.go @@ -23,7 +23,6 @@ import ( "cuelang.org/go/cue/errors" "cuelang.org/go/cue/literal" "cuelang.org/go/cue/token" - "cuelang.org/go/internal" ) // A Feature is an encoded form of a label which comprises a compact @@ -76,14 +75,14 @@ func (f Feature) SelectorString(index StringIndexer) string { } return strconv.Itoa(int(x)) case StringLabel: - s := index.IndexToString(x) - if ast.IsValidIdent(s) && !internal.IsDefOrHidden(s) { - return s - } if f == AnyString { return "_" } - return literal.Label.Quote(s) + s := index.IndexToString(x) + if ast.StringLabelNeedsQuoting(s) { + return literal.Label.Quote(s) + } + return s default: return f.IdentString(index) } @@ -389,6 +388,3 @@ func (f Feature) safeIndex() int64 { } return int64(x) } - -// TODO: should let declarations be implemented as fields? -// func (f Feature) isLet() bool { return f.typ() == letLabel } diff --git a/vendor/cuelang.org/go/internal/core/adt/fields.go b/vendor/cuelang.org/go/internal/core/adt/fields.go index 6fe06e7f4d..cd098ced21 100644 --- a/vendor/cuelang.org/go/internal/core/adt/fields.go +++ b/vendor/cuelang.org/go/internal/core/adt/fields.go @@ -14,10 +14,6 @@ package adt -import ( - "cuelang.org/go/cue/token" -) - // This file holds the logic for the insertion of fields and pattern // constraints, including tracking closedness. // @@ -153,204 +149,6 @@ import ( // - the data structures could probably be collapsed with Conjunct. and the // Vertex inserted into the Conjuncts could be a special ConjunctGroup. -type closeContext struct { - // Used to recursively insert Vertices. - parent *closeContext - - // depth is the depth from the top following the parent tree. This may be - // relative to an anonymous struct for inline computed values. - depth int - - // overlay is used to temporarily link a closeContext to its "overlay" copy, - // as it is used in a corresponding disjunction. - overlay *closeContext - // generation is used to track the current generation of the closeContext - // in disjunction overlays. This is mostly for debugging. - generation int - - // a non-zero value indicates that the closeContext is part of a disjunction - // and that it is associated with the given Hole Index. - holeID int - - // dependencies is used to track dependencies that need to be copied in - // overlays. It is also use for testing. - dependencies []*ccDep - - // externalDeps lists the closeContexts associated with a root node for - // which there are outstanding decrements (can only be NOTIFY or ARC). This - // is used to break counter cycles, if necessary. - // - // This is only used for root closedContext and only for debugging. - // TODO: move to nodeContext. - externalDeps []ccDepRef - - // child links to a sequence which additional patterns need to be verified - // against (&&). If there are more than one, these additional nodes are - // linked with next. Only closed nodes with patterns are added. Arc sets are - // already merged during processing. - // A child is always done. This means it cannot be modified. - child *closeContext - - // next holds a linked list of nodes to process. - // See comments above and see linkPatterns. - next *closeContext - - // if conjunctCount is 0, pattern constraints can be merged and the - // closedness can be checked. To ensure that this is true, there should - // be an additional increment at the start before any processing is done. - conjunctCount int - - // disjunctCount counts the number of disjunctions that contribute to - // conjunctCount. When a node is unfinished, for instance due to an error, - // we allow disjunctions to not be decremented. This count is then used - // to suppress errors about missing decrements. - disjunctCount int - - src *Vertex - - arcType ArcType - - // isDef is true when isDefOrig is true or when isDef is true for any of its - // child nodes, recursively. - isDef bool - - // isDefOrig indicates whether the closeContext is created as part of a - // definition. This value propagates to itself and parents through isDef. - isDefOrig bool - - // hasTop indicates a node has at least one top conjunct. - hasTop bool - - // hasNonTop indicates a node has at least one conjunct that is not top. - hasNonTop bool - - // isClosedOnce is true if this closeContext is the result of calling the - // close builtin. - isClosedOnce bool - - // isEmbed indicates whether the closeContext is created as part of an - // embedding. - isEmbed bool - - // isClosed is true if a node is a def, it became closed because of a - // reference or if it is closed by the close builtin. - // - // isClosed must only be set to true if all fields and pattern constraints - // that define the domain of the node have been added. - isClosed bool - - // isTotal is true if a node contains an ellipsis and is defined for all - // values. - isTotal bool - - // done is true if all dependencies have been decremented. - done bool - - // isDecremented is used to keep track of whether the evaluator decremented - // a closedContext for the ROOT depKind. - isDecremented bool - - // needsCloseInSchedule is non-nil if a closeContext that was created - // as an arc still needs to be decremented. It points to the creating arc - // for reporting purposes. - needsCloseInSchedule *closeContext - - // parentConjuncts represent the parent of this embedding or definition. - // Any closeContext is represented by a ConjunctGroup in parent of the - // expression tree. - parentConjuncts conjunctGrouper - // TODO: Only needed if more than one conjuncts. - - // arcs represents closeContexts for sub fields and notification targets - // associated with this node that reflect the same point in the expression - // tree as this closeContext. In both cases the are keyed by Vertex. - arcs []ccArc - - // notify represents closeContexts which to notify of updates. - // - // TODO: Note that this slice is very similar to nodeContext.notify and the - // use of these can likely be merged. It may be better to let the notify - // originate from a more specific closeContext, allowing it to stopped - // sooner and possibly even remove the need for breaking dependency - // cycles. - notify []ccNotify - - // parentIndex is the position in the parent's arcs slice that corresponds - // to this closeContext. This is currently unused. The intention is to use - // this to allow groups with single elements (which will be the majority) - // to be represented in place in the parent. - parentIndex int - - group *ConjunctGroup - - // Patterns contains all patterns of the current closeContext. - // It is used in the construction of Expr. - Patterns []Value - - // Expr contains the Expr that is used for checking whether a Feature - // is allowed in this context. It is only complete after the full - // context has been completed, but it can be used for initial checking - // once isClosed is true. - Expr Value - - // decl is the declaration which contains the conjuct which gave - // rise to this closeContext. - decl Decl -} - -// Label is a convenience function to return the label of the associated Vertex. -func (c *closeContext) Label() Feature { - return c.src.Label -} - -// See also Vertex.updateArcType in composite.go. -func (c *closeContext) updateArcType(ctx *OpContext, t ArcType) { - if t == ArcPending { - return - } - for ; c != nil; c = c.parent { - switch { - case t >= c.arcType: - return - case c.arcType == ArcNotPresent: - ctx.notAllowedError(c.src) - return - default: - c.arcType = t - } - } -} - -type ccArc struct { - // decremented indicates whether [decDependant] has been called for this - // dependency. - decremented bool - // matched indicates the arc is only added to track the destination of a - // matched pattern and that it is not explicitly defined as a field. - // This is only used for arcs and not for notify. - matched bool - // root is dst.src.cc(). TODO: remove and use dst directly. - root *closeContext - // dst is the closeContext for which the counters are incremented and - // decremented and which is the actual destination of the dependency. - dst *closeContext -} - -type ccNotify struct { - // decremented indicates whether [decDependant] has been called for this - // dependency. - decremented bool - // dst is the closeContext for which the counters are incremented and - // decremented and which is the actual destination of the dependency. - dst *closeContext -} - -type conjunctGrouper interface { - // Assign conjunct adds the conjunct and returns an arc to represent it, - // along with the position within the group. - assignConjunct(ctx *OpContext, root *closeContext, c Conjunct, mode ArcType, check, checkClosed bool) (arc *closeContext, pos int, added bool) -} - func (n *nodeContext) getArc(f Feature, mode ArcType) (arc *Vertex, isNew bool) { // TODO(disjunct,perf): CopyOnRead v := n.node @@ -369,7 +167,7 @@ func (n *nodeContext) getArc(f Feature, mode ArcType) (arc *Vertex, isNew bool) Parent: v, Label: f, ArcType: mode, - nonRooted: v.IsDynamic || v.Label.IsLet() || v.nonRooted, + nonRooted: v.IsDynamic || v.nonRooted, anonymous: v.anonymous || v.Label.IsLet(), } if n.scheduler.frozen&fieldSetKnown != 0 { @@ -382,245 +180,6 @@ func (n *nodeContext) getArc(f Feature, mode ArcType) (arc *Vertex, isNew bool) return arc, true } -func (v *Vertex) assignConjunct(ctx *OpContext, root *closeContext, c Conjunct, mode ArcType, check, checkClosed bool) (a *closeContext, pos int, added bool) { - - // TODO: consider clearing CloseInfo.cc. - // c.CloseInfo.cc = nil - - arc := root.src - arc.updateArcType(mode) // TODO: probably not necessary: consider removing. - - if &arc.Conjuncts != root.group { - panic("misaligned conjuncts") - } - - pos = -1 - if check { - pos = findConjunct(arc.Conjuncts, c) - } - if pos == -1 { - pos = len(arc.Conjuncts) - c.CloseInfo.cc = root - arc.addConjunctUnchecked(c) - added = true - } - - return root, pos, added -} - -func (cc *closeContext) getKeyedCC(ctx *OpContext, key *closeContext, c CycleInfo, mode ArcType, checkClosed bool) *closeContext { - for i := range cc.arcs { - a := &cc.arcs[i] - if a.root == key { - a.matched = a.matched && !checkClosed - a.dst.updateArcType(ctx, mode) - return a.dst - } - } - - group := &ConjunctGroup{} - - if cc.parentConjuncts == cc { - panic("parent is self") - } - - parent, pos, _ := cc.parentConjuncts.assignConjunct(ctx, key, Conjunct{ - CloseInfo: CloseInfo{ - FromDef: cc.isDef, - FromEmbed: cc.isEmbed, - CycleInfo: c, - }, - x: group, - }, mode, false, checkClosed) - - arc := &closeContext{ - // origin: cc.origin, - depth: cc.depth, - generation: cc.generation, - parent: parent, - parentConjuncts: parent, - parentIndex: pos, - - src: key.src, - arcType: mode, - group: group, - - isDef: cc.isDef, - isDefOrig: cc.isDefOrig, - isEmbed: cc.isEmbed, - needsCloseInSchedule: cc, - } - - arc.parent.incDependent(ctx, PARENT, arc) - - // If the parent, w.r.t. the subfield relation was already processed, - // there is no need to register the notification. - arc.incDependent(ctx, EVAL, cc) // matched in REF(decrement:nodeDone) - - // A let field never depends on its parent. So it is okay to filter here. - if !arc.Label().IsLet() { - // prevent a dependency on self. - if key.src != cc.src { - matched := !checkClosed - cc.addArcDependency(ctx, matched, arc) - } - } - - v := key.src - if checkClosed && v.Parent != nil && v.Parent.state != nil { - v.Parent.state.checkArc(cc, v) - } - - return arc -} - -func (cc *closeContext) assignConjunct(ctx *OpContext, root *closeContext, c Conjunct, mode ArcType, check, checkClosed bool) (arc *closeContext, pos int, added bool) { - arc = cc.getKeyedCC(ctx, root, c.CloseInfo.CycleInfo, mode, checkClosed) - - c.CloseInfo.cc = nil - - var group ConjunctGroup - if arc.group != nil { - group = *arc.group - } - pos = -1 - if check { - pos = findConjunct(group, c) - } - if pos == -1 { - pos = len(group) - added = true - - c.CloseInfo.cc = arc - - if c.CloseInfo.cc.src != arc.src { - panic("Inconsistent src") - } - - group = append(group, c) - if arc.group == nil { - arc.group = &group - } else { - *arc.group = group - } - } - return arc, pos, added -} - -// TODO: cache depth. -func VertexDepth(v *Vertex) int { - depth := 0 - for p := v.Parent; p != nil; p = p.Parent { - depth++ - } - return depth -} - -// spawnCloseContext wraps the closeContext in c with a new one and returns -// this new context along with an updated CloseInfo. The new values reflect -// that the set of fields represented by c are now, for instance, enclosed in -// an embedding or a definition. -// -// This call is used when preparing ADT values for evaluation. -func (c CloseInfo) spawnCloseContext(ctx *OpContext, t closeNodeType) (CloseInfo, *closeContext) { - cc := c.cc - if cc == nil { - panic("nil closeContext") - } - - depth := VertexDepth(cc.src) - - c.cc = &closeContext{ - generation: cc.generation, - parent: cc, - depth: depth, - src: cc.src, - parentConjuncts: cc, - } - - cc.incDependent(ctx, PARENT, c.cc) // REF(decrement: spawn) - - switch t { - case closeDef: - c.cc.isDef = true - c.cc.isDefOrig = true - case closeEmbed: - c.cc.isEmbed = true - } - - return c, c.cc -} - -func (c *closeContext) updateClosedInfo(ctx *OpContext) bool { - p := c.parent - - if c.isDef && !c.isTotal && (!c.hasTop || c.hasNonTop) { - c.isClosed = true - if p != nil { - p.isDef = true - } - } - - if c.isClosedOnce { - c.isClosed = true - if p != nil { - p.isClosedOnce = true - } - } - - c.finalizePattern() - - if p == nil { - v := c.src - // Root pattern, set allowed patterns. - if pcs := v.PatternConstraints; pcs != nil { - if pcs.Allowed != nil { - // This can happen for lists. - // TODO: unify the values. - // panic("unexpected allowed set") - } - pcs.Allowed = c.Expr - return false - } - return false - } - - if c.hasTop { - p.hasTop = true - } - if c.hasNonTop { - p.hasNonTop = true - } - - switch { - case c.isTotal: - if !p.isClosed { - p.isTotal = true - } - case !c.isEmbed && c.isClosed: - // Merge the two closeContexts and ensure that the patterns and fields - // are mutually compatible according to the closedness rules. - injectClosed(ctx, c, p) - p.Expr = mergeConjunctions(p.Expr, c.Expr) - default: - // Do not check closedness of fields for embeddings. - // The pattern constraints of the embedding still need to be added - // to the current context. - p.linkPatterns(c) - } - - return true -} - -// linkPatterns merges the patterns of child into c, if needed. -func (c *closeContext) linkPatterns(child *closeContext) { - // We need to always add the closeContext, as this closeContext may, for - // instance, be an embedding within a definition. In other words, we do - // not know yet if this information will be relevant for closedness. - child.next = c.child - c.child = child -} - // allowedInClosed reports whether a field with label f is allowed in a closed // struct, even when it is not explicitly defined. // @@ -630,67 +189,43 @@ func allowedInClosed(f Feature) bool { return f.IsHidden() || f.IsDef() || f.IsLet() } -// checkArc validates that the node corresponding to cc allows a field with -// label v.Label. -func (n *nodeContext) checkArc(cc *closeContext, v *Vertex) *Vertex { - n.assertInitialized() - - f := v.Label - ctx := n.ctx - - if allowedInClosed(f) { - return v +// insertConjunct inserts conjunct c into cc. +func (v *Vertex) insertConjunct(ctx *OpContext, c Conjunct, id CloseInfo, mode ArcType, check, checkClosed bool) (pos int, added bool) { + n := v.getBareState(ctx) + if n == nil { + return 0, false } - if cc.isClosed && !matchPattern(ctx, cc.Expr, f) { - ctx.notAllowedError(v) - } - if n.scheduler.frozen&fieldSetKnown != 0 { - for _, a := range n.node.Arcs { - if a.Label == f { - return v - } - } - var b *Bottom - // TODO: include cycle data and improve error message. - if f.IsInt() { - b = ctx.NewErrf( - "element at index %v not allowed by earlier comprehension or reference cycle", f) - } else { - b = ctx.NewErrf( - "field %v not allowed by earlier comprehension or reference cycle", f) - } - v.SetValue(ctx, b) - } + n.markNonCyclic(id) - return v -} + v.updateArcType(mode) -// insertConjunct inserts conjunct c into cc. -func (cc *closeContext) insertConjunct(ctx *OpContext, key *closeContext, c Conjunct, id CloseInfo, mode ArcType, check, checkClosed bool) (arc *closeContext, added bool) { - arc, _, added = cc.assignConjunct(ctx, key, c, mode, check, checkClosed) - if key.src != arc.src { - panic("inconsistent src") - } + var c2 Conjunct + pos = -1 + if check { + pos, c2 = findConjunct(v.Conjuncts, c) - if !added { - return } - - n := key.src.getBareState(ctx) - if n == nil { - // already done - return - } - - switch id.CycleType { - case NoCycle, IsOptional: - n.hasNonCyclic = true + if pos == -1 { + pos = len(v.Conjuncts) + v.addConjunctUnchecked(c) + added = true + } else if srcRef := c2.CloseInfo.defID; srcRef != 0 { + if c2.CloseInfo.opID == n.ctx.opID { + // TODO: do we need this replacement? Most duplicates are deduped in + // insertVertexConjuncts by deduping the reference that brings in + // conjuncts in the first place. However, with API calls, and in + // some cases possibly with structure sharing, it may be possible + // that different Vertices refer to the same conjuncts. In this + // case, we need to ensure that the current defID also considers the + // ID associated with the original insertion in its set. + n.addReplacement(replaceID{from: id.defID, to: srcRef}) + } else { + n.ctx.stats.MisalignedConjunct++ + } } - if key.src.isInProgress() { - c.CloseInfo.cc = nil - id.cc = arc + if v.isInProgress() { n.scheduleConjunct(c, id) } @@ -703,22 +238,19 @@ func (cc *closeContext) insertConjunct(ctx *OpContext, key *closeContext, c Conj // TODO: we should probably only notify a conjunct once the root of the // conjunct group is completed. This will make it easier to "stitch" the // conjunct trees together, as its correctness will be guaranteed. - c.CloseInfo.cc = rec.cc - rec.v.state.scheduleConjunct(c, id) + if rec.v.state == nil || rec.v.status == finalized { + // TODO: alternatively prevent nodes from being finalized when they + // still may receive notifications. + ctx.stats.SkippedNotification++ + continue + } + rec.v.state.scheduleConjunct(c, rec.c) } return } func (n *nodeContext) insertArc(f Feature, mode ArcType, c Conjunct, id CloseInfo, check bool) *Vertex { - v, _ := n.insertArcCC(f, mode, c, id, check) - return v -} - -// insertArc inserts conjunct c into n. If check is true it will not add c if it -// was already added. -// Returns the arc of n.node with label f. -func (n *nodeContext) insertArcCC(f Feature, mode ArcType, c Conjunct, id CloseInfo, check bool) (*Vertex, *closeContext) { n.assertInitialized() if n == nil { @@ -727,10 +259,6 @@ func (n *nodeContext) insertArcCC(f Feature, mode ArcType, c Conjunct, id CloseI if n.node == nil { panic("nil node") } - cc := id.cc - if cc == nil { - panic("nil closeContext") - } v, insertedArc := n.getArc(f, mode) @@ -743,22 +271,12 @@ func (n *nodeContext) insertArcCC(f Feature, mode ArcType, c Conjunct, id CloseI // // It was already determined before that this arc may not be present. // // This case can only manifest itself if we have a cycle. // n.node.reportFieldCycleError(n.ctx, pos(c.x), f) - // return v, nil + // return v // } - if v.cc() == nil { - v.rootCloseContext(n.ctx) - // TODO(evalv3): reevaluate need for generation - v._cc.generation = n.node._cc.generation - } - - arc, added := cc.insertConjunct(n.ctx, v.cc(), c, id, mode, check, true) - if !added { - return v, arc - } - - if !insertedArc { - return v, arc + _, added := v.insertConjunct(n.ctx, c, id, mode, check, true) + if !added || !insertedArc { + return v } // Match and insert patterns. @@ -766,18 +284,13 @@ func (n *nodeContext) insertArcCC(f Feature, mode ArcType, c Conjunct, id CloseI for _, pc := range pcs.Pairs { if matchPattern(n.ctx, pc.Pattern, f) { for _, c := range pc.Constraint.Conjuncts { - // TODO: consider using the root cc, but probably does not - // matter. - // This is necessary if we defunct tasks, but otherwise not. - // It breaks the CloseContext tests, though. - // c.CloseInfo.cc = id.cc n.addConstraint(v, mode, c, check) } } } } - return v, arc + return v } // addConstraint adds a constraint to arc of n. @@ -804,38 +317,15 @@ func (n *nodeContext) addConstraint(arc *Vertex, mode ArcType, c Conjunct, check bulkEnv.DynamicLabel = f c.Env = &bulkEnv - // TODO(constraintNode): this should ideally be - // cc := id.cc - // or - // cc := c.CloseInfo.cc.src.cc - // - // Where id is the closeContext corresponding to the field, or the root - // context. But it is a bit hard to figure out how to account for this, as - // either this information is not available or the root context results in - // errors for the other use of addConstraint. For this reason, we keep - // things symmetric for now and will keep things as is, just avoiding the - // closedness check. - cc := c.CloseInfo.cc - // TODO: can go, but do in separate CL. arc, _ = n.getArc(f, mode) - root := arc.rootCloseContext(n.ctx) - - // Note: we are inserting the conjunct int the closeContext corresponding to - // the constraint. This will add an arc to the respective closeContext. In - // order to keep closedness information consistent, we need to ensure that, - // if the arc was otherwise not added in this context, the arc is marked as - // not really present. - cc.insertConjunct(n.ctx, root, c, c.CloseInfo, mode, check, false) + arc.insertConjunct(n.ctx, c, c.CloseInfo, mode, check, false) } func (n *nodeContext) insertPattern(pattern Value, c Conjunct) { n.assertInitialized() - ctx := n.ctx - cc := c.CloseInfo.cc - // Collect patterns in root vertex. This allows comparing disjuncts for // equality as well as inserting new arcs down the line as they are // inserted. @@ -855,19 +345,11 @@ func (n *nodeContext) insertPattern(pattern Value, c Conjunct) { } } - if cc.isTotal { + if n.node.HasEllipsis { return } - // insert pattern in current set. - // TODO: normalize patterns - // TODO: do we only need to do this for closed contexts? - for _, pc := range cc.Patterns { - if Equal(ctx, pc, pattern, 0) { - return - } - } - cc.Patterns = append(cc.Patterns, pattern) + // TODO: we could still try to accumulate patterns. } // isTotal reports whether pattern value p represents a full domain, that is, @@ -882,60 +364,6 @@ func isTotal(p Value) bool { return false } -// injectClosed updates dst so that it only allows fields allowed by closed. -// -// It first ensures that the fields contained in dst are allowed by the fields -// and patterns defined in closed. It reports an error in the nodeContext if -// this is not the case. -func injectClosed(ctx *OpContext, closed, dst *closeContext) { - for _, a := range dst.arcs { - ca := a.dst - switch f := ca.Label(); { - case ca.src.ArcType == ArcOptional, - // Without this continue, an evaluation error may be propagated to - // parent nodes that are otherwise allowed. - // TODO(evalv3): consider using ca.arcType instead. - allowedInClosed(f), - closed.allows(ctx, f): - case ca.arcType == ArcPending: - ca.arcType = ArcNotPresent - default: - ctx.notAllowedError(ca.src) - } - } - - if !dst.isClosed { - // Since dst is not closed, it is safe to take all patterns from - // closed. - // This is only necessary for passing up patterns into embeddings. For - // (the conjunction of) definitions the construction is handled - // elsewhere. - // TODO(perf): reclaim slice memory - dst.Patterns = closed.Patterns - - dst.isClosed = true - } -} - -func (c *closeContext) allows(ctx *OpContext, f Feature) bool { - ctx.Assertf(token.NoPos, c.conjunctCount == 0, "unexpected 0 conjunctCount") - - for _, b := range c.arcs { - cb := b.dst - if b.matched || f != cb.Label() { - continue - } - // TODO: we could potentially remove the check for ArcPending if we - // explicitly set the arcType to ArcNonPresent when a comprehension - // yields no results. - if cb.arcType == ArcNotPresent || cb.arcType == ArcPending { - continue - } - return true - } - return matchPattern(ctx, c.Expr, f) -} - func (ctx *OpContext) addPositions(c Conjunct) { if x, ok := c.x.(*ConjunctGroup); ok { for _, c := range *x { @@ -949,13 +377,7 @@ func (ctx *OpContext) addPositions(c Conjunct) { // notAllowedError reports a field not allowed error in n and sets the value // for arc f to that error. -func (ctx *OpContext) notAllowedError(arc *Vertex) { - // TODO(compat): ultimately we should strive to remove this explicit - // reproduction of a bug to ensure compatibility with the old evaluator. - if ctx.inLiteralSelectee > 0 { - return - } - +func (ctx *OpContext) notAllowedError(arc *Vertex) *Bottom { defer ctx.PopArc(ctx.PushArc(arc)) defer ctx.ReleasePositions(ctx.MarkPositions()) @@ -975,17 +397,19 @@ func (ctx *OpContext) notAllowedError(arc *Vertex) { // We do not know yet whether the arc will be present or not. Checking // this will be deferred until this is known, after the comprehension // has been evaluated. - return + return nil } ctx.Assertf(ctx.pos(), !allowedInClosed(arc.Label), "unexpected disallowed definition, let, or hidden field") if ctx.HasErr() { // The next error will override this error when not run in Strict mode. - return + return nil } // TODO: setting arc instead of n.node eliminates subfields. This may be // desirable or not, but it differs, at least from <=v0.6 behavior. - arc.SetValue(ctx, ctx.NewErrf("field not allowed")) + err := ctx.NewErrf("field not allowed") + err.CloseCheck = true + arc.SetValue(ctx, err) if arc.state != nil { arc.state.kind = 0 } @@ -997,10 +421,15 @@ func (ctx *OpContext) notAllowedError(arc *Vertex) { // TODO: create a special kind of error that gets the positions // of the relevant locations upon request from the arc. + return err } // mergeConjunctions combines two values into one. It never modifies an // existing conjunction. +// +// TODO: this was used in the closeContext code. We can still use it to +// construct pattern constraint conjunction in the future. This is currently +// unimplemented. func mergeConjunctions(a, b Value) Value { if a == nil { return b @@ -1031,53 +460,3 @@ func mergeConjunctions(a, b Value) Value { // TODO: potentially order conjuncts to make matching more likely. return &Conjunction{Values: vs} } - -// finalizePattern updates c.Expr to a CUE Value representing all fields allowed -// by the pattern constraints of c. If this context or any of its direct -// children is closed, the result will be a conjunction of all these closed -// values. Otherwise it will be a disjunction of all its children. A nil value -// represents all values. -func (c *closeContext) finalizePattern() { - switch { - case c.Expr != nil: // Patterns and expression are already set. - // NOTE: this panic check is just to verify using Expr unnecessarily. It - // is not the end of the world to use c.Expr, it is just less efficient. - // If this check causes trouble, it can be removed. - // TODO(openlists): reenable once we support open list semantics. - // if !c.isClosed { - // panic("c.Expr set unexpectedly") - // } - return - case c.isTotal: // All values are allowed always. - return - } - - // As this context is not closed, the pattern is somewhat meaningless. - // It may still be useful for analysis. - or := c.Patterns - - for cc := c.child; cc != nil; cc = cc.next { - if cc.isTotal { - return - } - // Could be closed, in which case it must also be an embedding. - - // TODO: simplify the values. - switch x := cc.Expr.(type) { - case nil: - case *Disjunction: - or = append(or, x.Values...) - default: - or = append(or, x) - } - } - - switch len(or) { - case 0: - case 1: - c.Expr = or[0] - default: - // TODO: potentially order conjuncts to make matching more likely. - c.Expr = &Disjunction{Values: or} - } -} diff --git a/vendor/cuelang.org/go/internal/core/adt/flags.go b/vendor/cuelang.org/go/internal/core/adt/flags.go new file mode 100644 index 0000000000..ccbdfcbf1a --- /dev/null +++ b/vendor/cuelang.org/go/internal/core/adt/flags.go @@ -0,0 +1,41 @@ +// Copyright 2023 CUE Authors +// +// 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. + +package adt + +// Flags describe the mode of evaluation for a vertex. +type Flags struct { + // status is a remnant from evalv2, where it used to request a certain + // state. It is still used here and there. TODO: remove + status vertexStatus + + // condition and runmode indicates properties to satisfy for evalv4 + condition condition + mode runMode + + // concrete indicates whether the result should be concrete. + concrete bool + + // checkTypos indicates whether to check for typos (closedness). + checkTypos bool +} + +var ( + FinalizeWithoutTypoCheck = Flags{ + status: finalized, + condition: allKnown, + mode: finalize, + checkTypos: false, + } +) diff --git a/vendor/cuelang.org/go/internal/core/adt/kind.go b/vendor/cuelang.org/go/internal/core/adt/kind.go index b11112b9a2..290d6ed864 100644 --- a/vendor/cuelang.org/go/internal/core/adt/kind.go +++ b/vendor/cuelang.org/go/internal/core/adt/kind.go @@ -16,13 +16,14 @@ package adt import ( "fmt" + "iter" "math/bits" "strings" ) // Concreteness is a measure of the level of concreteness of a value, where // lower values mean more concrete. -type Concreteness int +type Concreteness uint8 const ( BottomLevel Concreteness = iota @@ -53,6 +54,26 @@ func IsConcrete(v Value) bool { return v.Concreteness() <= Concrete } +// IsRecursivelyConcrete checks that v is a scalar or that all regular fields +// have concrete values, recursively. +func IsRecursivelyConcrete(v *Vertex) bool { + for _, a := range v.Arcs { + if !a.Label.IsRegular() { + continue + } + switch a.ArcType { + case ArcMember: + case ArcRequired: + return false + } + + if !IsRecursivelyConcrete(a) { + return false + } + } + return v.IsConcrete() +} + // Kind reports the Value kind. type Kind uint16 @@ -113,12 +134,37 @@ func (k Kind) String() string { return toString(k, kindStrs) } -// TypeString is like String, but returns a string representation of a valid -// CUE type. +// TypeString is like [Kind.String], +// but returns a string representation of a valid CUE type. func (k Kind) TypeString() string { return toString(k, typeStrs) } +// Kinds returns an iterator over all the individual +// Kinds in k. There will be k.Count() items in the sequence. +func (k Kind) Kinds() iter.Seq[Kind] { + return func(yield func(Kind) bool) { + k := k + for count := 0; ; count++ { + n := bits.TrailingZeros(uint(k)) + if n == bits.UintSize { + break + } + bit := Kind(1 << uint(n)) + k &^= bit + if !yield(bit) { + return + } + } + } +} + +// Count returns the number of individual Kinds +// making up k. +func (k Kind) Count() int { + return bits.OnesCount(uint(k)) +} + func toString(k Kind, m map[Kind]string) string { if k == BottomKind { return "_|_" @@ -130,25 +176,21 @@ func toString(k Kind, m map[Kind]string) string { k = (k &^ NumberKind) | _numberKind } var buf strings.Builder - multiple := bits.OnesCount(uint(k)) > 1 + multiple := k.Count() > 1 if multiple { buf.WriteByte('(') } - for count := 0; ; count++ { - n := bits.TrailingZeros(uint(k)) - if n == bits.UintSize { - break - } - bit := Kind(1 << uint(n)) - k &^= bit + count := 0 + for bit := range k.Kinds() { s, ok := m[bit] if !ok { - s = fmt.Sprintf("bad(%d)", n) + s = fmt.Sprintf("bad(%d)", bits.TrailingZeros(uint(bit))) } if count > 0 { buf.WriteByte('|') } buf.WriteString(s) + count++ } if multiple { buf.WriteByte(')') diff --git a/vendor/cuelang.org/go/internal/core/adt/log.go b/vendor/cuelang.org/go/internal/core/adt/log.go index 946e380136..2852d7b699 100644 --- a/vendor/cuelang.org/go/internal/core/adt/log.go +++ b/vendor/cuelang.org/go/internal/core/adt/log.go @@ -16,13 +16,16 @@ package adt import ( "fmt" + "io" "log" + "path/filepath" + "runtime" "strings" "cuelang.org/go/cue/token" ) -// Assert panics if the condition is false. Assert can be used to check for +// Assertf panics if the condition is false. Assertf can be used to check for // conditions that are considers to break an internal variant or unexpected // condition, but that nonetheless probably will be handled correctly down the // line. For instance, a faulty condition could lead to error being caught @@ -53,9 +56,56 @@ func init() { var pMap = map[*Vertex]int{} +type nestString string + +func (c *OpContext) Un(s nestString, id int) { + c.nest-- + if id != c.logID { + c.Logf(nil, "END %s", string(s)) + } +} + +// Indentf logs a function call and increases the nesting level. +// The first argument must be the function name. +func (c *OpContext) Indentf(v *Vertex, format string, args ...any) (s nestString, id int) { + if c.LogEval == 0 { + // The Go compiler as of 1.24 is not very clever with no-op function calls; + // any arguments passed to ...args above escape to the heap and allocate. + panic("avoid calling OpContext.Indentf when logging is disabled to prevent overhead") + } + name := strings.Split(format, "(")[0] + if name == "" { + name, _ = getCallerFunctionName(1) + format = name + format + } + + caller, line := getCallerFunctionName(2) + args = append(args, caller, line) + + format += " %s:%d" + + c.Logf(v, format, args...) + c.nest++ + + return nestString(name), c.logID +} + +func (c *OpContext) RewriteArgs(args ...interface{}) { + for i, a := range args { + switch x := a.(type) { + case Node: + args[i] = c.Str(x) + case Feature: + args[i] = x.SelectorString(c) + } + } +} + func (c *OpContext) Logf(v *Vertex, format string, args ...interface{}) { if c.LogEval == 0 { - return + // The Go compiler as of 1.24 is not very clever with no-op function calls; + // any arguments passed to ...args above escape to the heap and allocate. + panic("avoid calling OpContext.Logf when logging is disabled to prevent overhead") } w := &strings.Builder{} @@ -74,24 +124,20 @@ func (c *OpContext) Logf(v *Vertex, format string, args ...interface{}) { return } + c.RewriteArgs(args...) + n, _ := fmt.Fprintf(w, format, args...) + if n < 60 { + w.WriteString(strings.Repeat(" ", 60-n)) + } + p := pMap[v] if p == 0 { p = len(pMap) + 1 pMap[v] = p } disjunctInfo := c.disjunctInfo() - fmt.Fprintf(w, "[n:%d/%v %s%s] ", - p, v.Path(), c.PathToString(v.Path()), disjunctInfo) - - for i, a := range args { - switch x := a.(type) { - case Node: - args[i] = c.Str(x) - case Feature: - args[i] = x.SelectorString(c) - } - } - fmt.Fprintf(w, format, args...) + fmt.Fprintf(w, "; n:%d %v %v%s ", + p, c.PathToString(v.Path()), v.Path(), disjunctInfo) _ = log.Output(2, w.String()) } @@ -139,9 +185,6 @@ func (n *nodeContext) pushDisjunctionTask() *disjunctInfo { } c.disjunctStack = append(c.disjunctStack, id) - n.Logf("========= DISJUNCTION %d =========", c.currentDisjunctionID) - c.nest += 1 - return c.currentDisjunct() } @@ -179,17 +222,37 @@ func (n *nodeContext) logDoDisjunct() *disjunctInfo { d.disjunctID = int(c.stats.Disjuncts) - n.Logf("====== Do DISJUNCT %v & %v ======", d.lhs, d.rhs) + if n.ctx.LogEval > 0 { + n.Logf("====== Do DISJUNCT %v & %v ======", d.lhs, d.rhs) + } return d } func (d disjunctInfo) pop() { c := d.node.ctx - c.nest -= 1 c.disjunctStack = c.disjunctStack[:len(c.disjunctStack)-1] } +// Format implements the fmt.Formatter interface for disjunctInfo. +func (d *disjunctInfo) Format(f fmt.State, c rune) { + d.Write(f) +} + +func (d *disjunctInfo) Write(w io.Writer) { + // which disjunct + fmt.Fprintf(w, " D%d:H%d:%d/%d", + d.disjunctionID, d.holeID, d.disjunctionSeq, d.numDisjunctions) + if d.crossProductSeq != 0 { + fmt.Fprintf(w, " P%d/%d", d.crossProductSeq, d.numPrevious) + } + if d.disjunctID != 0 { + fmt.Fprintf(w, " d%d:%d/%d", + d.disjunctID, d.disjunctSeq, d.numDisjuncts, + ) + } +} + // disjunctInfo prints a header for log to indicate the current disjunct. func (c *OpContext) disjunctInfo() string { if len(c.disjunctStack) == 0 { @@ -203,17 +266,24 @@ func (c *OpContext) disjunctInfo() string { if i != 0 { b.WriteString(" =>") } - // which disjunct - fmt.Fprintf(&b, " D%d:H%d:%d/%d", - d.disjunctionID, d.holeID, d.disjunctionSeq, d.numDisjunctions) - if d.crossProductSeq != 0 { - fmt.Fprintf(&b, " P%d/%d", d.crossProductSeq, d.numPrevious) - } - if d.disjunctID != 0 { - fmt.Fprintf(&b, " d%d:%d/%d", - d.disjunctID, d.disjunctSeq, d.numDisjuncts, - ) - } + d.Write(&b) } return b.String() } + +func getCallerFunctionName(i int) (caller string, line int) { + pc, _, line, ok := runtime.Caller(1 + i) + if !ok { + return "unknown", 0 + } + fn := runtime.FuncForPC(pc) + if fn == nil { + return "unknown", 0 + } + fullName := fn.Name() + name := filepath.Base(fullName) + if idx := strings.LastIndex(name, "."); idx != -1 { + name = name[idx+1:] + } + return name, line +} diff --git a/vendor/cuelang.org/go/internal/core/adt/mem.go b/vendor/cuelang.org/go/internal/core/adt/mem.go new file mode 100644 index 0000000000..d6a19fa28a --- /dev/null +++ b/vendor/cuelang.org/go/internal/core/adt/mem.go @@ -0,0 +1,232 @@ +// Copyright 2025 CUE Authors +// +// 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 +// +// https://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. + +package adt + +// The goal of the memory management implemented here is to reuse as many of the +// allocated values as possible. It is currently mostly for nodeContext values, +// but we plan to collect other values as well. +// +// ### nodeContext +// +// One of the main complications with cleaning nodeContext values is that it +// holds closedness information, which is generally referred to by parent nodes +// and recursively by disjuncts (see [mergeCloseInfo]). This means we have to +// delay freeing the nodeContext until we are sure closedness information is no +// longer needed. +// +// Other than that, there are several other cases where nodeContext values +// cannot be freed when a nodeContext is involved in another computation that +// ends up recursively finalizing it. In this case, the nodeContext may only be +// freed when the last computation is finalized. This is tracked by the refCount +// field. +// +// Theoretically we should also not collect nodeContext values if they can still +// be notified about changes. But other mechanisms already preven this from +// being an issue. +// +// TODO(mem): Finally, we need to have a mechanism to collect temporary Vertex +// values that are not part of the output tree. This is done with the +// [nodeContext.toFree] field, which tracks Vertex values that can be cleaned up +// as soon as all processing for a nodeContext has been completed. + +// TODO: Reuse +// - Vertex: Vertex values allocated for failed disjunctions could be reused. +// - tasks: perhaps make them "inline", so as to avoid the need for a free list. +// - Environment: not sure how. Perhaps using a mark and sweep approach. + +func (n *nodeContext) retainProcess() *nodeContext { + n.refCount++ + return n +} + +func (n *nodeContext) releaseProcess() *nodeContext { + n.refCount-- + // TODO: we could consider freeing the node here if it is marked as + // freeable. + return n +} + +// A reclaimer is used to reclaim buffers of a Vertex and its children. +// +// It has several modes to be able to handle different cases. +type reclaimer struct { + ctx *OpContext + + // guard is used to precent reclaiming disjuncts that are still "in flight", + // or if nodeContext information, for instance, is still needed down the + // line, even if a values is finalized. This is the case, for instance, if a + // value is part of a disjunction that is still in flight or if another + // operation is still modify a nodeContext. + guard bool + + // recurse is set if reclaiming should be done for all child arcs + // recursively. + recurse bool + + // force allows a node to be freed if it is not finalized. + // + // TODO(mem): it is currently appears to be safe to free a nodeContext if it + // is not finalized, even for nodes that are part of the output tree. We + // should consider enforcing this though as it seems this could uncover some + // bugs. + force bool +} + +// freeDisjunct frees a node that has been used as a disjunct. We cannot free a +// disjunct while unwinding the evaluation, because the closedness information +// of the result needs to be merged into other disjuncts when deduping. +// The additional advantage of handing disjuncts separately, though, is that +// we can reclaim Vertex nodes, of which many are overallocated. +func (n *nodeContext) freeDisjunct() { + n.ctx.reclaimRecursive(n.node) +} + +// reclaimRecursive reclaims all buffers of.v and its children. It forces +// buffers to be freed even if they are not finalized. +func (c *OpContext) reclaimRecursive(v *Vertex) { + r := reclaimer{ + ctx: c, + force: true, + recurse: true, + } + r.reclaim(v) +} + +// reclaimTempBuffers reclaims the nodeContext of itself and its children, +// if possible, along with other temporary buffers that are no longer needed. +func (c *OpContext) reclaimTempBuffers(v *Vertex) { + r := reclaimer{ + ctx: c, + guard: true, + force: true, + } + if !r.reclaim(v) { + return + } + + for _, arc := range v.Arcs { + n := arc.state + if n == nil || n.refCount > 0 { + continue + } + + if w := arc.DerefDisjunct(); arc != w { + // Reclaim the fields that were already added before starting the + // disjunction. The disjunct itself is reclaimed in [r.reclaim]. + c.reclaimRecursive(arc) + } + if n.node != nil { + // TODO(mem): we could free recursively here, and this will release + // some more nodes. But in this case it is rather rare, so we rather + // prevent having to do a recursive traversal here.s + c.freeNodeContext(n) + } + } +} + +// reclaim is the core function that reclaims buffers for a Vertex and its +// children. +func (r reclaimer) reclaim(v *Vertex) bool { + n := v.state + if n != nil { + for _, v := range n.toFree { + r.ctx.reclaimRecursive(v) + } + n.toFree = n.toFree[:0] + + if !r.guard { + r.reclaimBaseValueBuffers(v) + } else if n.isDisjunct { + // In guard mode we do not collect disjuncts. If this node is part + // of a disjunct it is reclaimed later as part of [freeDisjunct]. + return false + } else { + if n.refCount > 0 { + goto skipRoot + } + + r.reclaimBaseValueBuffers(v) + + if v.Parent != nil && !v.Label.IsLet() { + goto skipRoot + } + } + if n.ctx == r.ctx { + // TODO(mem): it should be fine to just release the nodeContext into + // c unconditionally. But the result is that it can result in + // negative values for 'Leaks'. This is because loading imports + // happens within a different context and currently this does not + // correctly clean up. + r.ctx.freeNodeContext(n) + } + } + + // TODO: this is not generally true. A dereferenced disjunct may already be + // in use to the point it cannot be freed. Mark such disjuncts to prevent + // reclamation or figure out something else. For now we disable to + // optimization as its effect is limited. + // + // See Issue #4055: + // a: "x" + // a: _ | error("a") + // if len(a) > 0 { + // a: _ | error("b") + // } + // + // if w := v.DerefDisjunct(); v != w { + // r.ctx.reclaimRecursive(w) + // } + +skipRoot: + if v.PatternConstraints != nil { + for _, p := range v.PatternConstraints.Pairs { + if n := p.Constraint.state; n != nil { + r.reclaim(p.Constraint) + } + } + } + + if r.recurse { + for _, arc := range v.Arcs { + r.reclaim(arc) + } + } + + return true +} + +func (r reclaimer) reclaimBaseValueBuffers(v *Vertex) { + switch x := v.BaseValue.(type) { + case *Disjunction: + for _, d := range x.Values { + if v, ok := d.(*Vertex); ok { + r.ctx.reclaimRecursive(v) + } + } + case *Conjunction: + for _, d := range x.Values { + if v, ok := d.(*Vertex); ok { + r.ctx.reclaimRecursive(v) + } + } + } +} + +func (v *Vertex) clearArcs(c *OpContext) { + for _, arc := range v.Arcs { + c.reclaimRecursive(arc) + } + v.Arcs = v.Arcs[:0] +} diff --git a/vendor/cuelang.org/go/internal/core/adt/op.go b/vendor/cuelang.org/go/internal/core/adt/op.go index dfa83cbbfe..8c50bd0b94 100644 --- a/vendor/cuelang.org/go/internal/core/adt/op.go +++ b/vendor/cuelang.org/go/internal/core/adt/op.go @@ -20,7 +20,7 @@ import "cuelang.org/go/cue/token" // use to evaluate a value. type Op int -//go:generate go run golang.org/x/tools/cmd/stringer -type=Op -linecomment +//go:generate go tool stringer -type=Op -linecomment // Values of Op. const ( @@ -58,6 +58,8 @@ const ( IntModuloOp // mod InterpolationOp // \() + + SpreadOp // ... ) // OpFromToken converts a token.Token to an Op. diff --git a/vendor/cuelang.org/go/internal/core/adt/op_string.go b/vendor/cuelang.org/go/internal/core/adt/op_string.go index 1fedcaed84..0573f1157e 100644 --- a/vendor/cuelang.org/go/internal/core/adt/op_string.go +++ b/vendor/cuelang.org/go/internal/core/adt/op_string.go @@ -35,15 +35,17 @@ func _() { _ = x[IntDivideOp-24] _ = x[IntModuloOp-25] _ = x[InterpolationOp-26] + _ = x[SpreadOp-27] } -const _Op_name = "NoOp&|.[][:]()&&||==!!=<<=>>==~!~+-*/quoremdivmod\\()" +const _Op_name = "NoOp&|.[][:]()&&||==!!=<<=>>==~!~+-*/quoremdivmod\\()..." -var _Op_index = [...]uint8{0, 4, 5, 6, 7, 9, 12, 14, 16, 18, 20, 21, 23, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, 40, 43, 46, 49, 52} +var _Op_index = [...]uint8{0, 4, 5, 6, 7, 9, 12, 14, 16, 18, 20, 21, 23, 24, 26, 27, 29, 31, 33, 34, 35, 36, 37, 40, 43, 46, 49, 52, 55} func (i Op) String() string { - if i < 0 || i >= Op(len(_Op_index)-1) { + idx := int(i) - 0 + if i < 0 || idx >= len(_Op_index)-1 { return "Op(" + strconv.FormatInt(int64(i), 10) + ")" } - return _Op_name[_Op_index[i]:_Op_index[i+1]] + return _Op_name[_Op_index[idx]:_Op_index[idx+1]] } diff --git a/vendor/cuelang.org/go/internal/core/adt/optional.go b/vendor/cuelang.org/go/internal/core/adt/optional.go deleted file mode 100644 index cb99dd26c4..0000000000 --- a/vendor/cuelang.org/go/internal/core/adt/optional.go +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2020 CUE Authors -// -// 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. - -package adt - -// MatchAndInsert finds matching optional parts for a given Arc and adds its -// conjuncts. Bulk fields are only applied if no fields match, and additional -// constraints are only added if neither regular nor bulk fields match. -func (o *StructInfo) MatchAndInsert(c *OpContext, arc *Vertex) { - env := o.Env - - closeInfo := o.CloseInfo - closeInfo.IsClosed = false - - // Match normal fields - matched := false - // TODO: this could be lookup up more efficiently in the outer Vertex now. - // Keep this logic for now, though. - for _, f := range o.Fields { - if f.Label == arc.Label { - matched = true - break - } - } - - f := arc.Label - if !f.IsRegular() { - return - } - var label Value - - if int64(f.Index()) == MaxIndex { - f = 0 - } else if o.types&HasComplexPattern != 0 && f.IsString() { - label = f.ToValue(c) - } - - if len(o.Bulk) > 0 { - bulkEnv := *env - bulkEnv.DynamicLabel = f - - // match bulk optional fields / pattern properties - for _, b := range o.Bulk { - // if matched && f.additional { - // continue - // } - - // Mark the current arc as cyclic while evaluating pattern - // expressions, but not while adding conjuncts. - // TODO: make MatchAndInsert return a list of conjuncts instead? - // TODO: it could be that we can set the cycle before calling - // MatchAndInsert after the renewed implementation of disjunctions. - saved := arc.BaseValue - arc.BaseValue = cycle - match := matchBulk(c, env, b, f, label) - arc.BaseValue = saved - - if match { - matched = true - info := closeInfo.SpawnSpan(b.Value, ConstraintSpan) - arc.AddConjunct(MakeConjunct(&bulkEnv, b, info)) - } - } - } - - if matched || len(o.Additional) == 0 { - return - } - - // match others - for _, x := range o.Additional { - info := closeInfo - if _, ok := x.expr().(*Top); !ok { - info = info.SpawnSpan(x, ConstraintSpan) - } - // TODO: consider moving in above block (2 lines up). - arc.AddConjunct(MakeConjunct(env, x, info)) - } -} - -// matchBulk reports whether feature f matches the filter of x. It evaluation of -// the filter is erroneous, it returns false and the error will be set in c. -func matchBulk(c *OpContext, env *Environment, p *BulkOptionalField, f Feature, label Value) bool { - unreachableForDev(c) - - v := env.evalCached(c, p.Filter) - v = Unwrap(v) - - // Fast-track certain cases. - switch x := v.(type) { - case *Bottom: - if x == cycle { - err := c.NewPosf(pos(p.Filter), "cyclic pattern constraint") - for _, c := range c.vertex.Conjuncts { - err.AddPosition(c.Elem()) - } - c.AddBottom(&Bottom{ - Err: err, - Node: c.vertex, - }) - } - if c.errs == nil { - c.AddBottom(x) - } - return false - case *Top: - return true - - case *BasicType: - return x.K&StringKind != 0 - - case *BoundValue: - switch x.Kind() { - case StringKind: - if label == nil { - return false - } - str := label.(*String).Str - return x.validateStr(c, str) - - case IntKind: - return x.validateInt(c, int64(f.Index())) - } - } - - if label == nil { - return false - } - - n := Vertex{ - IsDynamic: true, - } - m := MakeConjunct(env, v, c.ci) - n.AddConjunct(m) - n.AddConjunct(MakeConjunct(m.Env, label, c.ci)) - - c.inConstraint++ - n.Finalize(c) - c.inConstraint-- - - b, _ := n.BaseValue.(*Bottom) - return b == nil -} diff --git a/vendor/cuelang.org/go/internal/core/adt/overlay.go b/vendor/cuelang.org/go/internal/core/adt/overlay.go index cd9216153e..62073ba475 100644 --- a/vendor/cuelang.org/go/internal/core/adt/overlay.go +++ b/vendor/cuelang.org/go/internal/core/adt/overlay.go @@ -14,7 +14,10 @@ package adt -import "slices" +import ( + "maps" + "slices" +) // This file implements a Vertex overlay. This is used by the disjunction // algorithm to fork an existing Vertex value without modifying the original. @@ -38,11 +41,13 @@ import "slices" // TODO(perf): implement copy on write: instead of copying the entire tree, we // could get by with only copying arcs to that are modified in the copy. -var nextGeneration int - func newOverlayContext(ctx *OpContext) *overlayContext { - nextGeneration++ - return &overlayContext{ctx: ctx, generation: nextGeneration} + return &overlayContext{ + ctx: ctx, + + // TODO(perf): take a map from a pool of maps and reuse. + vertexMap: make(map[*Vertex]*Vertex), + } } // An overlayContext keeps track of copied vertices, closeContexts, and tasks. @@ -51,73 +56,137 @@ func newOverlayContext(ctx *OpContext) *overlayContext { type overlayContext struct { ctx *OpContext - // generation is used to identify the current overlayContext. All - // closeContexts created by this overlayContext will have this generation. - // Whenever a counter of a closedContext is changed, this may only cause - // a cascade of changes if the generation is the same. - generation int - - // closeContexts holds the allocated closeContexts created by allocCC. - // - // In the first pass, closeContexts are copied using allocCC. This also - // walks the parent tree, and allocates copies for ConjunctGroups. - // - // In the second pass, initCloneCC can be finalized by initializing each - // closeContext in this slice. - // - // Note that after the copy is completed, the overlay pointer should be - // deleted. - closeContexts []*closeContext + // root is the root of the disjunct. + root *Vertex // vertices holds the original, non-overlay vertices. The overlay for a // vertex v can be obtained by looking up v.cc.overlay.src. vertices []*Vertex + + // vertexMap maps Vertex values of an originating node to the ones copied + // for this overlayContext. This is used to update the Vertex values in + // Environment values. + vertexMap vertexMap + + // confMap maps envComprehension values to the ones copied for this + // overlayContext. + compMap map[*envComprehension]*envComprehension +} + +type vertexMap map[*Vertex]*Vertex + +// overlayFrom is used to store overlay information in the OpContext. This +// is used for dynamic resolution of vertices, which prevents data structures +// from having to be copied in the overlay. +// +// TODO(perf): right now this is only used for resolving vertices in +// comprehensions. We could also use this for resolving environments, though. +// Furthermore, we could used the "cleared" vertexMaps on this stack to avoid +// allocating memory. +// +// NOTE: using a stack globally in OpContext is not very principled, as we +// may be evaluating nested evaluations of different disjunctions. However, +// in practice this just results in more work: as the vertices should not +// overlap, there will be no cycles. +type overlayFrame struct { + vertexMap vertexMap + root *Vertex +} + +func (c *OpContext) pushOverlay(v *Vertex, m vertexMap) { + c.overlays = append(c.overlays, overlayFrame{m, v}) +} + +func (c *OpContext) popOverlay() { + c.overlays = c.overlays[:len(c.overlays)-1] +} + +func (c *OpContext) deref(v *Vertex) *Vertex { + for i := len(c.overlays) - 1; i >= 0; i-- { + f := c.overlays[i] + if f.root == v { + continue + } + if x, ok := f.vertexMap[v]; ok { + return x + } + } + return v +} + +// deref reports a replacement of v or v itself if such a replacement does not +// exists. It computes the transitive closure of the replacement graph. +// TODO(perf): it is probably sufficient to only replace one level. But we need +// to prove this to be sure. Until then, we keep the code as is. +// +// This function does a simple cycle check. As every overlayContext adds only +// new Vertex nodes and only entries from old to new nodes are created, this +// should never happen. But just in case we will panic instead of hang in such +// situations. +func (m vertexMap) deref(v *Vertex) *Vertex { + for i := 0; ; i++ { + x, ok := m[v] + if !ok { + break + } + v = x + + if i > len(m) { + panic("cycle detected in vertexMap") + } + } + return v } // cloneRoot clones the Vertex in which disjunctions are defined to allow // inserting selected disjuncts into a new Vertex. func (ctx *overlayContext) cloneRoot(root *nodeContext) *nodeContext { + maps.Copy(ctx.vertexMap, root.vertexMap) + // Clone all vertices that need to be cloned to support the overlay. v := ctx.cloneVertex(root.node) v.IsDisjunct = true + v.state.vertexMap = ctx.vertexMap + ctx.root = v - // At this point we have copied all the mandatory closeContexts. There - // may be derivative closeContexts copied as well. + for _, v := range ctx.vertices { + v = v.overlay - // TODO: patch notifications to any node that is within the disjunct to - // point to the new vertex instead. + n := v.state + if n == nil { + continue + } - // Initialize closeContexts: at this point, all closeContexts that need to - // be cloned have been allocated and stored in closeContexts and can now be - // initialized. - // Use an explicit index as initCloneCC uses allocCC, which MAY allocate a - // new closeContext. It probably does not, but we use an index in case. - for i := 0; i < len(ctx.closeContexts); i++ { - cc := ctx.closeContexts[i] - ctx.initCloneCC(cc) - } + // The group of the root closeContext should point to the Conjuncts field + // of the Vertex. As we already allocated the group, we use that allocation, + // but "move" it to v.Conjuncts. + // TODO: Is this ever necessary? It is certainly necessary to rewrite + // environments from inserted disjunction values, but expressions that + // were already added will typically need to be recomputed and recreated + // anyway. We add this in to be a bit defensive and reinvestigate once we + // have more aggressive structure sharing implemented + for i, c := range v.Conjuncts { + v.Conjuncts[i].Env = ctx.derefDisjunctsEnv(c.Env) + } - for _, cc := range ctx.closeContexts { - ctx.finishDependencies(cc) - } + for _, t := range n.tasks { + ctx.rewriteComprehension(t) - // TODO: walk overlay vertices and decrement counters of non-disjunction - // running tasks? - // TODO: find a faster way to do this. Walking over vertices would - // probably be faster. - for _, cc := range ctx.closeContexts { - for _, d := range cc.dependencies { - if d.task == nil { - // The test case that makes this necessary: - // #A: ["a" | "b"] | {} - // #A: ["a" | "b"] | {} - // b: #A & ["b"] - // - // TODO: invalidate task instead? - continue - } - if d.kind == TASK && d.task.state == taskRUNNING && !d.task.defunct { - cc.overlay.decDependent(ctx.ctx, TASK, nil) + t.node = ctx.vertexMap.deref(t.node.node).state + + if t.blockedOn != nil { + before := t.blockedOn.node.node + after := ctx.vertexMap.deref(before) + // Tasks that are blocked on nodes outside the current scope + // of the disjunction should should be added to blocking queues. + if before == after { + continue + } + s := &after.state.scheduler + t.blockedOn = s + s.blocking = append(s.blocking, t) + s.ctx.blocking = append(s.ctx.blocking, t) + s.needs |= t.blockCondition } } } @@ -133,8 +202,8 @@ func (ctx *overlayContext) cloneRoot(root *nodeContext) *nodeContext { // // TODO(perf): consider using generation counters. func (ctx *overlayContext) unlinkOverlay() { - for _, cc := range ctx.closeContexts { - cc.overlay = nil + for _, v := range ctx.vertices { + v.overlay = nil } } @@ -148,28 +217,19 @@ func (ctx *overlayContext) unlinkOverlay() { // to eliminate disjunctions pre-copy based on discriminator fields and what // have you. This is not unlikely to eliminate func (ctx *overlayContext) cloneVertex(x *Vertex) *Vertex { - xcc := x.rootCloseContext(ctx.ctx) // may be uninitialized for constraints. - if o := xcc.overlay; o != nil && o.src != nil { - // This path could happen with structure sharing or user-constructed - // values. - return o.src + if x.overlay != nil { + return x.overlay } + // TODO(mem-mgmt): use free list for Vertex allocation. v := &Vertex{} *v = *x + ctx.vertexMap[x] = v + x.overlay = v - ctx.vertices = append(ctx.vertices, v) - - v._cc = ctx.allocCC(x.cc()) + ctx.vertices = append(ctx.vertices, x) - v._cc.src = v - v._cc.parentConjuncts = v - - // The group of the root closeContext should point to the Conjuncts field - // of the Vertex. As we already allocated the group, we use that allocation, - // but "move" it to v.Conjuncts. - v.Conjuncts = *v._cc.group - v._cc.group = &v.Conjuncts + v.Conjuncts = slices.Clone(v.Conjuncts) if a := x.Arcs; len(a) > 0 { // TODO(perf): reuse buffer. @@ -207,18 +267,40 @@ func (ctx *overlayContext) cloneVertex(x *Vertex) *Vertex { return v } -func (ctx *overlayContext) cloneNodeContext(n *nodeContext) *nodeContext { - if !n.node.isInitialized() { - panic("unexpected uninitialized node") +// derefDisjunctsEnv creates a new env for each Environment in the Up chain with +// each Environment where Vertex is "from" to one where Vertex is "to". +// +// TODO(perf): we could, instead, just look up the mapped vertex in +// OpContext.Up. This would avoid us having to copy the Environments for each +// disjunct. This requires quite a bit of plumbing, though, so we leave it as +// is until this proves to be a performance issue. +func (ctx *overlayContext) derefDisjunctsEnv(env *Environment) *Environment { + if env == nil { + return nil + } + up := ctx.derefDisjunctsEnv(env.Up) + to := ctx.vertexMap.deref(env.Vertex) + if up != env.Up || env.Vertex != to { + env = &Environment{ + Up: up, + Vertex: to, + DynamicLabel: env.DynamicLabel, + } } + return env +} + +func (ctx *overlayContext) cloneNodeContext(n *nodeContext) *nodeContext { + n.node.getState(ctx.ctx) // ensure state is initialized. + d := n.ctx.newNodeContext(n.node) d.underlying = n.underlying + d.isDisjunct = true + if n.underlying == nil { panic("unexpected nil underlying") } - d.refCount++ - d.ctx = n.ctx d.node = n.node @@ -226,11 +308,11 @@ func (ctx *overlayContext) cloneNodeContext(n *nodeContext) *nodeContext { d.arcMap = append(d.arcMap, n.arcMap...) d.checks = append(d.checks, n.checks...) + d.sharedIDs = append(d.sharedIDs, n.sharedIDs...) - for _, s := range n.sharedIDs { - s.cc = ctx.allocCC(s.cc) - d.sharedIDs = append(d.sharedIDs, s) - } + d.reqDefIDs = append(d.reqDefIDs, n.reqDefIDs...) + d.replaceIDs = append(d.replaceIDs, n.replaceIDs...) + d.conjunctInfo = append(d.conjunctInfo, n.conjunctInfo...) // TODO: do we need to add cyclicConjuncts? Typically, cyclicConjuncts // gets cleared at the end of a unify call. There are cases, however, where @@ -244,262 +326,15 @@ func (ctx *overlayContext) cloneNodeContext(n *nodeContext) *nodeContext { if len(n.disjunctions) > 0 { // Do not clone cc in disjunctions, as it is identified by underlying. // We only need to clone the cc in disjunctCCs. - d.disjunctions = append(d.disjunctions, n.disjunctions...) - for _, h := range n.disjunctCCs { - h.cc = ctx.allocCC(h.cc) - d.disjunctCCs = append(d.disjunctCCs, h) + for _, x := range n.disjunctions { + x.env = ctx.derefDisjunctsEnv(x.env) + d.disjunctions = append(d.disjunctions, x) } } return d } -// cloneConjunct prepares a tree of conjuncts for copying by first allocating -// a clone for each closeContext. -func (ctx *overlayContext) copyConjunct(c Conjunct) Conjunct { - cc := c.CloseInfo.cc - if cc == nil { - return c - } - // TODO: see if we can avoid this allocation. It seems that this should - // not be necessary, and evaluation attains correct results without it. - // Removing this, though, will cause some of the assertions to fail. These - // assertions are overly strict and could be relaxed, but keeping them as - // they are makes reasoning about them easier. - overlay := ctx.allocCC(cc) - c.CloseInfo.cc = overlay - return c -} - -// Phase 1: alloc -func (ctx *overlayContext) allocCC(cc *closeContext) *closeContext { - // TODO(perf): if the original is "done", it can no longer be modified and - // we can use the original, even if the values will not be correct. - if cc.overlay != nil { - return cc.overlay - } - - o := &closeContext{generation: ctx.generation} - cc.overlay = o - o.depth = cc.depth - o.holeID = cc.holeID - - if cc.parent != nil { - o.parent = ctx.allocCC(cc.parent) - } - - // Copy the conjunct group if it exists. - if cc.group != nil { - // Copy the group of conjuncts. - g := make([]Conjunct, len(*cc.group)) - o.group = (*ConjunctGroup)(&g) - for i, c := range *cc.group { - g[i] = ctx.copyConjunct(c) - } - - if o.parent != nil { - // validate invariants. - // TODO: the group can sometimes be empty. Investigate why and - // whether this is valid. - if ca := *cc.parent.group; len(ca) > 0 { - if ca[cc.parentIndex].x != cc.group { - panic("group misaligned") - } - - (*o.parent.group)[cc.parentIndex].x = o.group - } - } - } - - // This must come after allocating the parent so that we can always read - // the src vertex from the parent during initialization. This assumes that - // src is set in the root closeContext when cloning a vertex. - ctx.closeContexts = append(ctx.closeContexts, cc) - - // We only explicitly tag dependencies of type ARC. Notifications that - // point within the disjunct overlay will be tagged elsewhere. - for _, a := range cc.arcs { - ctx.allocCC(a.dst) - } - - return o -} - -func (ctx *overlayContext) initCloneCC(x *closeContext) { - o := x.overlay - - if p := x.parent; p != nil { - o.parent = p.overlay - o.src = o.parent.src - } - - o.depth = x.depth - o.conjunctCount = x.conjunctCount - o.disjunctCount = x.disjunctCount - o.isDef = x.isDef - o.isDefOrig = x.isDefOrig - o.hasTop = x.hasTop - o.hasNonTop = x.hasNonTop - o.isClosedOnce = x.isClosedOnce - o.isEmbed = x.isEmbed - o.isClosed = x.isClosed - o.isTotal = x.isTotal - o.done = x.done - o.isDecremented = x.isDecremented - o.parentIndex = x.parentIndex - o.Expr = x.Expr - o.Patterns = append(o.Patterns, x.Patterns...) - - // needsCloseInSchedule is a separate mechanism to signal nodes that have - // completed that corresponds to the EVAL mechanism. Since we have not - // processed the conjuncts yet, these are inherently initiated outside of - // this conjunct. By now, if a closeContext needs to remain open, other - // counters should have been added. As an example, the parent node of this - // disjunct is still processing. The disjunction will be fully added before - // processing, and thus their will be no direct EVAL dependency. However, - // this disjunct may depend on a NOTIFY that is kept open by an ancestor - // EVAL. - if x.needsCloseInSchedule != nil { - o.needsCloseInSchedule = nil - } - - // child and next always point to completed closeContexts. Moreover, only - // fields that are immutable, such as Expr, are used. It is therefore not - // necessary to use overlays. - o.child = x.child - if x.child != nil && x.child.overlay != nil { - // TODO(evalv3): there seem to be situations where this is possible - // after all. See if this is really true, and we should remove this - // panic, or if this underlies a bug of sorts. - // panic("unexpected overlay in child") - } - o.next = x.next - if x.next != nil && x.next.overlay != nil { - // TODO(evalv3): there seem to be situations where this is possible - // after all. See if this is really true, and we should remove this - // panic, or if this underlies a bug of sorts. - // See Issue #3434. - // panic("unexpected overlay in next") - } - - switch p := x.parentConjuncts.(type) { - case *closeContext: - if p.overlay == nil { - panic("expected overlay") - } - o.parentConjuncts = p.overlay - - case *Vertex: - o.parentConjuncts = o.src - } - - if o.src == nil { - // fall back to original vertex. - // FIXME: this is incorrect, as it may lead to evaluating nodes that - // are not part of the disjunction with values of the disjunction. - // TODO: try eliminating EVAL dependencies of arcs that are the parent - // of the disjunction root. - o.src = x.src - } - - if o.parentConjuncts == nil { - panic("expected parentConjuncts") - } -} - -func (ctx *overlayContext) finishDependencies(x *closeContext) { - o := x.overlay - - for _, a := range x.arcs { - // If an arc does not have an overlay, we should not decrement the - // dependency counter. We simply remove the dependency in that case. - if a.dst.overlay == nil || a.root.overlay == nil { - panic("arcs should always point inwards and thus included in the overlay") - } - if a.decremented { - continue - } - a.root = a.root.overlay // TODO: is this necessary? - a.dst = a.dst.overlay - o.arcs = append(o.arcs, a) - - root := a.dst.src.cc() - root.externalDeps = append(root.externalDeps, ccDepRef{ - src: o, - kind: ARC, - index: len(o.arcs) - 1, - }) - } - - for _, a := range x.notify { - // If a notification does not have an overlay, we should not decrement - // the dependency counter. We simply remove the dependency in that case. - // TODO: however, the original closeContext that it point to now will - // never be "filled". We should insert top in this gat or render it as - // "defunct", for instance, so that it will not leave an nondecremented - // counter. - if a.dst.overlay == nil { - for c := a.dst; c != nil; c = c.parent { - c.disjunctCount++ - } - continue - } - if a.decremented { - continue - } - a.dst = a.dst.overlay - o.notify = append(o.notify, a) - - root := a.dst.src.cc() - root.externalDeps = append(root.externalDeps, ccDepRef{ - src: o, - kind: NOTIFY, - index: len(o.notify) - 1, - }) - } - - for _, d := range x.dependencies { - if d.decremented { - continue - } - - if d.kind == DEFER { - o.decDependentNoMatch(ctx.ctx, DEFER, nil) - continue - } - - // Since have not started processing the disjunct yet, all EVAL - // dependencies will have been initiated outside of this disjunct. - if d.kind == EVAL { - o.decDependentNoMatch(ctx.ctx, EVAL, nil) - continue - } - - if d.dependency.overlay == nil { - // This dependency is irrelevant for the current overlay. We can - // eliminate it as long as we decrement the accompanying counter. - if o.conjunctCount < 2 { - // This node can only be relevant if it has at least one other - // dependency. Check that we are not decrementing the counter - // to 0. - // TODO: this currently panics for some tests. Disabling does - // not seem to harm, though. Reconsider whether this is an issue. - // panic("unexpected conjunctCount: must be at least 2") - } - o.conjunctCount-- - continue - } - - dep := d.dependency - dep = dep.overlay - o.dependencies = append(o.dependencies, &ccDep{ - dependency: dep, - kind: d.kind, - decremented: false, - }) - } -} - func (ctx *overlayContext) cloneScheduler(dst, src *nodeContext) { ss := &src.scheduler ds := &dst.scheduler @@ -515,20 +350,11 @@ func (ctx *overlayContext) cloneScheduler(dst, src *nodeContext) { for _, t := range ss.tasks { switch t.state { case taskWAITING: - // Do not unblock previously blocked tasks, unless they are - // associated with this node. - // TODO: an edge case is when a task is blocked on another node - // within the same disjunction. We could solve this by associating - // each nodeContext with a unique ID (like a generation counter) for - // the disjunction. - if t.node != src || t.blockedOn != ss { - break - } t.defunct = true t := ctx.cloneTask(t, ds, ss) ds.tasks = append(ds.tasks, t) - ds.blocking = append(ds.blocking, t) - ctx.ctx.blocking = append(ctx.ctx.blocking, t) + // We add this task to ds.blocking and ctx.ctx.blocking in + // cloneRoot, after its node references have been rewritten. case taskREADY: t.defunct = true @@ -536,10 +362,8 @@ func (ctx *overlayContext) cloneScheduler(dst, src *nodeContext) { ds.tasks = append(ds.tasks, t) case taskRUNNING: - if t.run != handleResolver && t.run != handleExpr { - // TODO: consider whether this is also necessary for other - // types of tasks. - break + if t.run == handleDisjunctions { + continue } t.defunct = true @@ -556,35 +380,76 @@ func (ctx *overlayContext) cloneTask(t *task, dst, src *scheduler) *task { } id := t.id - if id.cc != nil { - id.cc = ctx.allocCC(t.id.cc) // TODO: may be nil for disjunctions. - } - // TODO: alloc from buffer. + env := ctx.derefDisjunctsEnv(t.env) + + // TODO(perf): alloc from buffer. d := &task{ run: t.run, state: t.state, completes: t.completes, unblocked: t.unblocked, blockCondition: t.blockCondition, + blockedOn: t.blockedOn, // will be rewritten later err: t.err, - env: t.env, + env: env, x: t.x, id: id, node: dst.node, - // TODO: need to copy closeContexts? + // These are rewritten after everything is cloned when all vertices are + // known. comp: t.comp, leaf: t.leaf, } - if t.blockedOn != nil { - if t.blockedOn != src { - panic("invalid scheduler") + return d +} + +func (ctx *overlayContext) rewriteComprehension(t *task) { + if t.comp != nil { + t.comp = ctx.mapComprehensionContext(t.comp) + } + + t.leaf = ctx.mapComprehension(t.leaf) +} + +func (ctx *overlayContext) mapComprehension(c *Comprehension) *Comprehension { + if c == nil { + return nil + } + cc := *c + cc.comp = ctx.mapComprehensionContext(cc.comp) + cc.arc = ctx.ctx.deref(cc.arc) + cc.parent = ctx.mapComprehension(cc.parent) + return &cc +} + +func (ctx *overlayContext) mapComprehensionContext(ec *envComprehension) *envComprehension { + if ec == nil { + return nil + } + + if ctx.compMap == nil { + ctx.compMap = make(map[*envComprehension]*envComprehension) + } + + if ctx.compMap[ec] == nil { + vertex := ctx.vertexMap.deref(ec.vertex) + // Report the error at the root of the disjunction if otherwise the + // error would be reported outside of the disjunction. + if vertex == ec.vertex { + vertex = ctx.root } - d.blockedOn = dst + x := &envComprehension{ + comp: ec.comp, + structs: ec.structs, + vertex: vertex, + } + ctx.compMap[ec] = x + ec = x } - return d + return ec } diff --git a/vendor/cuelang.org/go/internal/core/adt/runmode_string.go b/vendor/cuelang.org/go/internal/core/adt/runmode_string.go index 1cb34d6ab1..a35a462245 100644 --- a/vendor/cuelang.org/go/internal/core/adt/runmode_string.go +++ b/vendor/cuelang.org/go/internal/core/adt/runmode_string.go @@ -19,9 +19,9 @@ const _runMode_name = "ignoreattemptOnlyyieldfinalize" var _runMode_index = [...]uint8{0, 6, 17, 22, 30} func (i runMode) String() string { - i -= 1 - if i >= runMode(len(_runMode_index)-1) { - return "runMode(" + strconv.FormatInt(int64(i+1), 10) + ")" + idx := int(i) - 1 + if i < 1 || idx >= len(_runMode_index)-1 { + return "runMode(" + strconv.FormatInt(int64(i), 10) + ")" } - return _runMode_name[_runMode_index[i]:_runMode_index[i+1]] + return _runMode_name[_runMode_index[idx]:_runMode_index[idx+1]] } diff --git a/vendor/cuelang.org/go/internal/core/adt/sched.go b/vendor/cuelang.org/go/internal/core/adt/sched.go index c6d0727cfa..50f8042a8b 100644 --- a/vendor/cuelang.org/go/internal/core/adt/sched.go +++ b/vendor/cuelang.org/go/internal/core/adt/sched.go @@ -176,7 +176,7 @@ func (s schedState) String() string { // runMode indicates how to proceed after a condition could not be met. type runMode uint8 -//go:generate go run golang.org/x/tools/cmd/stringer -type=runMode +//go:generate go tool stringer -type=runMode const ( // ignore indicates that the new evaluator should not do any processing. @@ -368,13 +368,9 @@ func (s *scheduler) process(needs condition, mode runMode) bool { } if s.ctx.LogEval > 0 && len(s.tasks) > 0 { + if v := s.tasks[0].node.node; v != nil { - c.Logf(v, "START Process %v -- mode: %v", v.Label, mode) - c.nest++ - defer func() { - c.nest-- - c.Logf(v, "END Process") - }() + c.Logf(v, "PROCESS(%v)", mode) } } @@ -417,9 +413,12 @@ processNextTask: if s.meets(needs) { return true } - c.current().waitFor(s, needs) - s.yield() - panic("unreachable") + // This can happen in some cases. We "promote" to finalization if this + // was not triggered by a task. + if t := c.current(); t != nil { + t.waitFor(s, needs) + s.yield() + } case finalize: // remainder of function @@ -604,8 +603,8 @@ type task struct { // The Conjunct processed by this task. env *Environment - id CloseInfo // TODO: rename to closeInfo? - x Node // The conjunct Expression or Value. + id CloseInfo + x Node // The conjunct Expression or Value. // For Comprehensions: comp *envComprehension @@ -630,14 +629,6 @@ func (s *scheduler) insertTask(t *task) { } s.incrementCounts(completes) - if cc := t.id.cc; cc != nil { - // may be nil for "group" tasks, such as processLists. - dep := cc.incDependent(t.node.ctx, TASK, nil) - if dep != nil { - dep.taskID = len(s.tasks) - dep.task = t - } - } s.tasks = append(s.tasks, t) // Sort by priority. This code is optimized for the case that there are @@ -659,14 +650,13 @@ func runTask(t *task, mode runMode) { if t.defunct { if t.state != taskCANCELLED { t.state = taskCANCELLED - if t.id.cc != nil { - t.id.cc.decDependent(t.node.ctx, TASK, nil) - } } return } - t.node.Logf("============ RUNTASK %v %v", t.run.name, t.x) ctx := t.node.ctx + if ctx.LogEval > 0 { + defer ctx.Un(ctx.Indentf(t.node.node, "RUNTASK(%v, %v)", t.run.name, t.x)) + } switch t.state { case taskSUCCESS, taskFAILED: @@ -675,7 +665,10 @@ func runTask(t *task, mode runMode) { // TODO: should we mark this as a cycle? } + ctx.freeScope = append(ctx.freeScope, t.node) defer func() { + ctx.freeScope = ctx.freeScope[:len(ctx.freeScope)-1] + if n := t.node; n.toComplete { n.toComplete = false n.completeNodeTasks(attemptOnly) @@ -706,7 +699,6 @@ func runTask(t *task, mode runMode) { // This is done to avoid struct args from passing fields up. // Use [task.updateCI] to get the current CloseInfo with this field // restored. - id.cc = nil s := ctx.PushConjunct(MakeConjunct(t.env, t.x, id)) defer ctx.PopState(s) } @@ -732,9 +724,6 @@ func runTask(t *task, mode runMode) { // TODO: do not add both context and task errors. Do something more // principled. t.node.addBottom(t.err) - if t.id.cc != nil { - t.id.cc.decDependent(ctx, TASK, nil) - } t.node.decrementCounts(t.completes) t.completes = 0 // safety } @@ -743,7 +732,6 @@ func runTask(t *task, mode runMode) { // updateCI stitches back the closeContext that more removed from the CloseInfo // before in the given CloseInfo. func (t *task) updateCI(ci CloseInfo) CloseInfo { - ci.cc = t.id.cc return ci } diff --git a/vendor/cuelang.org/go/internal/core/adt/share.go b/vendor/cuelang.org/go/internal/core/adt/share.go index be5bd45f14..bb0e24a9bb 100644 --- a/vendor/cuelang.org/go/internal/core/adt/share.go +++ b/vendor/cuelang.org/go/internal/core/adt/share.go @@ -38,6 +38,7 @@ func (n *nodeContext) unshare() { } n.isShared = false n.node.IsShared = false + n.node.OpenedShared = false v := n.node.BaseValue.(*Vertex) @@ -63,11 +64,12 @@ func (n *nodeContext) finalizeSharing() { case *Vertex: if n.shareCycleType == NoCycle { v.Finalize(n.ctx) - } else if !v.isFinal() { - // TODO: ideally we just handle cycles in optional chains directly, - // rather than relying on this mechanism. This requires us to add - // a mechanism to detect that. - n.ctx.toFinalize = append(n.ctx.toFinalize, v) + // See the TODO in unify.go for toFinalize. + // } else if !v.isFinal() { + // // TODO: ideally we just handle cycles in optional chains directly, + // // rather than relying on this mechanism. This requires us to add + // // a mechanism to detect that. + // n.ctx.toFinalize = append(n.ctx.toFinalize, v) } // If state.parent is non-nil, we determined earlier that this Vertex // is not rooted and that it can safely be shared. Because it is @@ -100,9 +102,6 @@ func (n *nodeContext) addShared(id CloseInfo) { // such a count should not hurt performance, as a shared node is completed // anyway. n.sharedIDs = append(n.sharedIDs, id) - if id.cc != nil { - id.cc.incDependent(n.ctx, SHARED, n.node.cc()) - } } func (n *nodeContext) decSharedIDs() { @@ -111,9 +110,7 @@ func (n *nodeContext) decSharedIDs() { } n.shareDecremented = true for _, id := range n.sharedIDs { - if cc := id.cc; cc != nil { - cc.decDependent(n.ctx, SHARED, n.node.cc()) - } + n.updateConjunctInfo(n.node.Kind(), id, 0) } } @@ -127,6 +124,7 @@ func (n *nodeContext) share(c Conjunct, arc *Vertex, id CloseInfo) { n.isShared = true n.shared = c n.addShared(id) + n.node.OpenedShared = id.Opened if arc.IsDetached() && arc.MayAttach() { // TODO: Second check necessary? // This node can safely be shared. Since it is not rooted, though, it @@ -147,6 +145,29 @@ func (n *nodeContext) shareIfPossible(c Conjunct, arc *Vertex, id CloseInfo) boo return false } + // We disallow sharing for any Arcs, even pending ones, to be defensive. + // CUE currently does not always unwind sharing properly in the precense of + // pending arcs. See, for instance: + // + // a: X + // if true { + // a: b: c: e: 1 // ensure 'e' is added + // } + // X: b: Y + // Y: c: d: int + // + // TODO: allow sharing in the precense of pending or not present arcs. + if len(n.node.Arcs) > 0 { + return false + } + + // See Issue #3801: structure sharing seems to be broken for non-rooted + // values. We disable sharing for now. + // TODO: make sharing work again for non-rooted structs. + if arc.nonRooted || arc.IsDynamic { + return false + } + // We do not allowing sharing if the conjunct has a cycle. Sharing is only // possible if there is a single conjunct. We want to further evaluate this // conjunct to force recognition of a structural cycle. diff --git a/vendor/cuelang.org/go/internal/core/adt/simplify.go b/vendor/cuelang.org/go/internal/core/adt/simplify.go index d36af819e5..6be4b49ac2 100644 --- a/vendor/cuelang.org/go/internal/core/adt/simplify.go +++ b/vendor/cuelang.org/go/internal/core/adt/simplify.go @@ -86,7 +86,10 @@ func SimplifyBounds(ctx *OpContext, k Kind, x, y *BoundValue) Value { case -1: case 0: if x.Op == GreaterEqualOp && y.Op == LessEqualOp { - return ctx.NewString(a.Str) + if ctx.SimplifyValidators { + return ctx.NewString(a.Str) + } + return nil } fallthrough @@ -111,7 +114,10 @@ func SimplifyBounds(ctx *OpContext, k Kind, x, y *BoundValue) Value { case -1: case 0: if x.Op == GreaterEqualOp && y.Op == LessEqualOp { - return ctx.newBytes(a.B) + if ctx.SimplifyValidators { + return ctx.newBytes(a.B) + } + return nil } fallthrough @@ -161,7 +167,7 @@ func SimplifyBounds(ctx *OpContext, k Kind, x, y *BoundValue) Value { // numbers // >=a & <=b // a if a == b - // _|_ if a < b + // _|_ if b < a // >=a & a & <=b @@ -172,7 +178,7 @@ func SimplifyBounds(ctx *OpContext, k Kind, x, y *BoundValue) Value { // integers // >=a & <=b // a if b-a == 0 - // _|_ if a < b + // _|_ if b < a // >=a & =-9_223_372_036_854_775_808 & <=9_223_372_036_854_775_807 + // + // Constructing that error is unfortunate as it allocates a few times + // and stringifies the number too, which also has a cost. + // Which is entirely unnecessary, as we don't use the error value at all. + // If we know the integer will have more than one digit, give up early. + if d.NumDigits() > 1 { + break + } switch diff, err := d.Int64(); { case diff == 1: if k&FloatKind == 0 { if x.Op == GreaterEqualOp && y.Op == LessThanOp { - return ctx.newNum(&lo, k&NumberKind, x, y) + return newNum(ctx, &lo, k&NumberKind, x, y) } if x.Op == GreaterThanOp && y.Op == LessEqualOp { - return ctx.newNum(&hi, k&NumberKind, x, y) + return newNum(ctx, &hi, k&NumberKind, x, y) } if x.Op == GreaterThanOp && y.Op == LessThanOp { return ctx.NewErrf("incompatible integer bounds %v and %v", x, y) @@ -200,21 +221,14 @@ func SimplifyBounds(ctx *OpContext, k Kind, x, y *BoundValue) Value { case diff == 2: if k&FloatKind == 0 && x.Op == GreaterThanOp && y.Op == LessThanOp { _, _ = internal.BaseContext.Add(&d, d.SetInt64(1), &lo) - return ctx.newNum(&d, k&NumberKind, x, y) + return newNum(ctx, &d, k&NumberKind, x, y) } case diff == 0 && err == nil: if x.Op == GreaterEqualOp && y.Op == LessEqualOp { - return ctx.newNum(&lo, k&NumberKind, x, y) - } - fallthrough - - case d.Negative: - if k == IntKind { - return ctx.NewErrf("incompatible integer bounds %v and %v", y, x) - } else { - return ctx.NewErrf("incompatible number bounds %v and %v", y, x) + return newNum(ctx, &lo, k&NumberKind, x, y) } + return errIncompatibleBounds(ctx, k, x, y) } case x.Op == NotEqualOp: @@ -230,6 +244,20 @@ func SimplifyBounds(ctx *OpContext, k Kind, x, y *BoundValue) Value { return nil } +func errIncompatibleBounds(ctx *OpContext, k Kind, x, y *BoundValue) *Bottom { + if k == IntKind { + return ctx.NewErrf("incompatible integer bounds %v and %v", y, x) + } else { + return ctx.NewErrf("incompatible number bounds %v and %v", y, x) + } +} +func newNum(ctx *OpContext, d *apd.Decimal, k Kind, sources ...Node) Value { + if ctx.SimplifyValidators { + return ctx.newNum(d, k, sources...) + } + return nil +} + func opInfo(op Op) (cmp Op, norm int) { switch op { case GreaterThanOp: @@ -251,7 +279,7 @@ func opInfo(op Op) (cmp Op, norm int) { } func test(ctx *OpContext, op Op, a, b Value) bool { - if b, ok := BinOp(ctx, op, a, b).(*Bool); ok { + if b, ok := BinOp(ctx, nil, op, a, b).(*Bool); ok { return b.B } return false diff --git a/vendor/cuelang.org/go/internal/core/adt/states.go b/vendor/cuelang.org/go/internal/core/adt/states.go index 56ab1af6ac..6dd58e9022 100644 --- a/vendor/cuelang.org/go/internal/core/adt/states.go +++ b/vendor/cuelang.org/go/internal/core/adt/states.go @@ -170,6 +170,10 @@ const ( // subFieldsProcessed + // pendingKnown means that this task is relevant for resolving whether an + // arc is present or not. This implies actTypeKnown. + pendingKnown + // disjunctionTask indicates that this task is a disjunction. This is // used to trigger finalization of disjunctions. disjunctionTask @@ -183,7 +187,12 @@ const ( conditionsUsingCounters = arcTypeKnown | valueKnown | fieldConjunctsKnown | - allTasksCompleted + allTasksCompleted | + // TODO: not adding this improves error message for issue3691 in + // eval/comprehensions.txtar. But without this, TestVisit of dep + // panics. Investigate. + pendingKnown | + disjunctionTask // The xConjunct condition sets indicate a conjunct MAY contribute the to // final result. For some conjuncts it may not be known what the @@ -212,7 +221,12 @@ const ( // list value. scalarConjunct = allTasksCompleted | scalarKnown | - valueKnown + valueKnown | + disjunctionTask + + // a scalarValue is one that is guaranteed to result in a scalar. + // TODO: use more widely instead of scalarKnown. + scalarValue = scalarKnown | disjunctionTask // needsX condition sets are used to indicate which conditions need to be // met. @@ -247,7 +261,9 @@ var schedConfig = taskContext{ func stateCompletions(s *scheduler) condition { x := s.completed v := s.node.node - s.node.Logf("=== stateCompletions: %v %v", v.Label, s.completed) + if s.node.ctx.LogEval > 0 { + s.node.Logf("=== stateCompletions: %v %v", v.Label, s.completed) + } if x.meets(allAncestorsProcessed) { x |= conditionsUsingCounters &^ s.provided // If we have a pending or constraint arc, a sub arc may still cause the @@ -297,12 +313,13 @@ func stateCompletions(s *scheduler) condition { // allChildConjunctsKnown indicates that all conjuncts have been added by // the parents and every conjunct that may add fields to subfields have been // processed. -func (v *Vertex) allChildConjunctsKnown() bool { +func (v *Vertex) allChildConjunctsKnown(ctx *OpContext) bool { if v == nil { return true } - if v.Status() == finalized { + // TODO(refcount): allow partial processed? + if v.Status() == finalized || (v.state == nil && v.status != unprocessed) { // This can happen, for instance, if this is called on a parent of a // rooted node that is marked as a parent for a dynamic node. // In practice this should be handled by the caller, but we add this @@ -311,7 +328,9 @@ func (v *Vertex) allChildConjunctsKnown() bool { return true } - return v.state.meets(fieldConjunctsKnown | allAncestorsProcessed) + n := v.getState(ctx) + + return n.meets(fieldConjunctsKnown | allAncestorsProcessed) } func (n *nodeContext) scheduleTask(r *runner, env *Environment, x Node, ci CloseInfo) *task { @@ -326,20 +345,3 @@ func (n *nodeContext) scheduleTask(r *runner, env *Environment, x Node, ci Close n.insertTask(t) return t } - -// require ensures that a given condition is met for the given Vertex by -// evaluating it. It yields execution back to the scheduler if it cannot -// be completed at this point. -func (c *OpContext) require(v *Vertex, needs condition) { - state := v.getState(c) - if state == nil { - return - } - state.process(needs, yield) -} - -// scalarValue evaluates the given expression and either returns a -// concrete value or schedules the task for later evaluation. -func (ctx *OpContext) scalarValue(t *task, x Expr) Value { - return ctx.value(x, require(0, scalarKnown)) -} diff --git a/vendor/cuelang.org/go/internal/core/adt/tasks.go b/vendor/cuelang.org/go/internal/core/adt/tasks.go index 671169b8fd..dd08340559 100644 --- a/vendor/cuelang.org/go/internal/core/adt/tasks.go +++ b/vendor/cuelang.org/go/internal/core/adt/tasks.go @@ -16,6 +16,7 @@ package adt import ( "fmt" + "slices" "cuelang.org/go/cue/ast" "cuelang.org/go/cue/token" @@ -57,7 +58,7 @@ func init() { handleComprehension = &runner{ name: "Comprehension", f: processComprehension, - completes: valueKnown | allTasksCompleted | fieldConjunctsKnown, + completes: valueKnown | allTasksCompleted | fieldConjunctsKnown | pendingKnown, } handleListLit = &runner{ name: "ListLit", @@ -84,7 +85,10 @@ func init() { func processExpr(ctx *OpContext, t *task, mode runMode) { x := t.x.(Expr) - state := combineMode(concreteKnown, mode) + state := Flags{ + condition: concreteKnown, + mode: mode, + } v, ci := ctx.evalStateCI(x, state) if ci.CycleType == IsCyclic && t.node.node.IsPatternConstraint { // This is an optional cycle that we will ignore. @@ -101,20 +105,28 @@ func processResolver(ctx *OpContext, t *task, mode runMode) { // be conclusive, we could avoid triggering evaluating disjunctions. This // would be a pretty significant rework, though. - arc := r.resolve(ctx, oldOnly(0)) + arc := r.resolve(ctx, Flags{ + condition: fieldSetKnown, + mode: mode, + }) // TODO: ensure that resolve always returns one of these two. if arc == nil || arc == emptyNode { // TODO: yield instead? return } + ci := ctx.ci + if arc.OpenedShared { + ci.Opened = true + } + arc = arc.DerefNonDisjunct() - ctx.Logf(t.node.node, "RESOLVED %v to %v %v", r, arc.Label, fmt.Sprintf("%p", arc)) + if ctx.LogEval > 0 { + ctx.Logf(t.node.node, "RESOLVED %v to %v %v", r, arc.Label, fmt.Sprintf("%p", arc)) + } // TODO: consider moving after markCycle or removing. d := arc.DerefDisjunct() - ci := t.updateCI(ctx.ci) - // A reference that points to itself indicates equality. In that case // we are done computing and we can return the arc as is. ci, skip := t.node.detectCycleV3(d, t.env, r, ci) @@ -145,7 +157,10 @@ func processDynamic(ctx *OpContext, t *task, mode runMode) { field := t.x.(*DynamicField) - v := ctx.scalarValue(t, field.Key) + v := ctx.value(field.Key, Flags{ + condition: scalarValue, + mode: mode, + }) if v == nil { return } @@ -171,9 +186,20 @@ func processDynamic(ctx *OpContext, t *task, mode runMode) { // unevaluated. ci := t.id - c := MakeConjunct(t.env, field, ci) - // TODO(evalv3): this does not seem to be necessary and even treacherous. - c.CloseInfo.cc = nil + // TODO: consider using a different mechanism where we do not have to + // copy the environment every time. If we do not have an alternative, + // we could use the same technique in pattern constraints to at least + // not have to copy it in most cases. + env := t.env + if x := field.Src; x != nil && x.Alias != nil && x.Alias.Label != nil { + e := *(t.env) + if f.Index() < MaxIndex { + e.DynamicLabel = f + } + env = &e + } + + c := MakeConjunct(env, field, ci) n.insertArc(f, field.ArcType, c, ci, true) } @@ -184,7 +210,10 @@ func processPatternConstraint(ctx *OpContext, t *task, mode runMode) { // Note that the result may be a disjunction. Be sure to not take the // default value as we want to retain the options of the disjunction. - v := ctx.evalState(field.Filter, require(0, scalarKnown)) + v := ctx.evalState(field.Filter, Flags{ + condition: scalarValue, + mode: yield, + }) if v == nil { return } @@ -209,7 +238,9 @@ func processComprehension(ctx *OpContext, t *task, mode runMode) { err := n.processComprehension(y, 0) t.err = CombineErrors(nil, t.err, err) - t.comp.vertex.state.addBottom(err) + if t.comp.vertex.state != nil { + t.comp.vertex.state.addBottom(err) + } } func processDisjunctions(c *OpContext, t *task, mode runMode) { @@ -218,11 +249,6 @@ func processDisjunctions(c *OpContext, t *task, mode runMode) { t.err = CombineErrors(nil, t.err, err) } -func processFinalizeDisjunctions(c *OpContext, t *task, mode runMode) { - n := t.node - n.finalizeDisjunctions() -} - func processListLit(c *OpContext, t *task, mode runMode) { n := t.node @@ -232,6 +258,8 @@ func processListLit(c *OpContext, t *task, mode runMode) { var ellipsis Node + id := c.subField(t.id) + index := int64(0) hasComprehension := false for j, elem := range l.Elems { @@ -239,11 +267,10 @@ func processListLit(c *OpContext, t *task, mode runMode) { switch x := elem.(type) { case *Comprehension: - err := c.yield(nil, t.env, x, 0, func(e *Environment) { + err := c.yield(nil, t.env, x, Flags{status: partial, mode: mode}, func(e *Environment) { label, err := MakeLabel(x.Source(), index, IntLabel) n.addErr(err) index++ - id := t.id // id.setOptional(t.node) c := MakeConjunct(e, x.Value, id) n.insertArc(label, ArcMember, c, id, true) @@ -268,7 +295,7 @@ func processListLit(c *OpContext, t *task, mode runMode) { elem = &Top{} } - id := t.id + id := id id.setOptionalV3(t.node) c := MakeConjunct(t.env, elem, id) @@ -283,8 +310,8 @@ func processListLit(c *OpContext, t *task, mode runMode) { label, err := MakeLabel(x.Source(), index, IntLabel) n.addErr(err) index++ - c := MakeConjunct(t.env, x, t.id) - n.insertArc(label, ArcMember, c, t.id, true) + c := MakeConjunct(t.env, x, id) + n.insertArc(label, ArcMember, c, id, true) } if max := n.maxListLen; n.listIsClosed && int(index) > max { @@ -310,7 +337,7 @@ func processListLit(c *OpContext, t *task, mode runMode) { n.listIsClosed = isClosed } - n.updateListType(l, t.id, isClosed, ellipsis) + n.updateListType(l, id, isClosed, ellipsis) } func processListVertex(c *OpContext, t *task, mode runMode) { @@ -318,7 +345,7 @@ func processListVertex(c *OpContext, t *task, mode runMode) { l := t.x.(*Vertex) - elems := l.Elems() + elems := slices.Collect(l.Elems()) isClosed := l.IsClosedList() // TODO: Share with code above. @@ -350,7 +377,6 @@ func processListVertex(c *OpContext, t *task, mode runMode) { continue } for _, c := range a.Conjuncts { - c.CloseInfo.cc = t.id.cc n.insertArc(a.Label, ArcMember, c, t.id, true) } } @@ -360,7 +386,6 @@ func processListVertex(c *OpContext, t *task, mode runMode) { func (n *nodeContext) updateListType(list Expr, id CloseInfo, isClosed bool, ellipsis Node) { if n.kind == 0 { - n.node.updateStatus(finalized) // TODO(neweval): remove once transitioned. return } m, ok := n.node.BaseValue.(*ListMarker) diff --git a/vendor/cuelang.org/go/internal/core/adt/typocheck.go b/vendor/cuelang.org/go/internal/core/adt/typocheck.go new file mode 100644 index 0000000000..9205211408 --- /dev/null +++ b/vendor/cuelang.org/go/internal/core/adt/typocheck.go @@ -0,0 +1,1065 @@ +// Copyright 2025 CUE Authors +// +// 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 +// +// https://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. + +package adt + +// This file holds CUE's algorithm to detect misspelled field names. +// +// ## Outline +// +// Typo checking MAY be enabled whenever a node is unified with a definition or +// a struct returned from the close builtin. Each distinct unification of such a +// struct triggers a separate "typo check", which is associated with a unique +// identifier. This identifier is passed along all values that result from +// unification with this struct. +// +// Once the processing of a node is complete, it is checked that for all its +// fields there is supportive evidence that the field is allowed for all structs +// for which typo checking is enabled. +// +// ## Selecting which Structs to Typo Check +// +// The algorithm is quite general and allows many types of heuristics to be +// applied. The initial goal is to mimic V2 semantics as closely as possible to +// facilitate migration to V3. +// +// ### Embeddings +// +// Embeddings provide evidence allowing fields for their enclosing scopes. Even +// when an embedding references a definition, it will not start its own typo +// check. +// +// ### Definitions +// +// By default, all references to non-embedded definitions are typo checked. The +// following situations qualify. +// +// #A: b: {a: int} +// a: #A +// +// // Trigger typo check +// r1: #A +// r2: a +// +// // Do NOT trigger typo check +// r3: a.b +// +// In the case of r3, no typo check is triggered as the inserted value does not +// reference a definition directly. This choice is somewhat arbitrary. The main +// reason to pick this semantics is to be compatible with V2. +// +// ### Inline structs +// +// Like in V2, inline structs are generally not typo checked. We can add this +// later if necessary. +// +// ## Tracking Evidence +// +// The basic principle of this algorithm is that each (dynamic) reference is +// associated with a unique identifier. When a node is unified with a definition +// all its descendant nodes are tagged with this number if any of the conjuncts +// of this definition end up being unified with such nodes. Once a node finished +// processing, it is checked, recursively, that all its fields adhere to this +// schema by checking that there is supportive evidence that this schema allows +// such fields. +// +// Consider, for instance, the following CUE. Here, the reference to #Schema +// will be assigned the unique identifier 7. +// +// foo: #Schema & { +// a: 1 // marked with 7 as #Schema has a field `a`. +// b: 1 // marked with 7 as the pattern of #Schema allows `b`. +// c: 1 // not marked with 7 as #Schema does not have a field `c`. +// } +// +// #Schema: { +// a?: int +// [<="b"]: int +// } +// +// Details of this algorithm are included below. +// +// ### Evidence sets and multiple insertions +// +// The same struct may be referred to within a node multiple times. If it is not +// itself a typo-checked definition, it may provide evidence for multiple other +// typo-checked definitions. To avoid having to process the conjuncts of such +// structs multiple times, we will still assign a unique identifier to such +// structs, and will annotate each typo-checked definition to which this applies +// that it is satisfied by this struct. +// +// In other words, each typo-checked struct may be associated with multiple +// unique identifiers that provide evidence for an allowed field. See the +// section below for a more detailed example. +// +// ### Embeddings +// +// Embeddings are a special case of structs that are not typo checked, but may +// provide evidence for other typo-checked definitions. As a struct associated +// with an embedding may be referred to multiple times, we will also assign a +// unique identifier to embeddings. This identifier is then also added to the +// evidence set of the typo-checked definition. +// +// Note that if a definition is embedded within a struct, that struct is +// considered closed after unifying all embeddings. We need to track this +// separately. This is discussed in the code below where appropriate. Ideally, +// we would get rid of this behavior by only allowing "open" or "closed" +// unifications, without considering any of the other context. +// +// Consider the following example: +// +// a: #A & { #A, b: int, c: int } +// #A: #B +// #B: { b: int } +// +// In this case, for `a`, we need find evidence that all fields of `#A` are +// allowed. If `a` were to be referenced by another field, we would also +// need to check that the struct with the embedded definition, which is +// closed after unification, is valid. +// +// So, for `a` we track two requirements, say `1`, which corresponds to the +// reference to `#A` and `2`, which corresponds to the literal struct. +// During evaluation, we additionally assign `3` to `#B`. +// +// The algorithm now proceeds as follows. We start with the requirement sets +// `{1}` and `{2}`. For the first, while evaluating definition `#A`, we find +// that this redirects to `#B`. In this case, as `#B` is at least as strict +// as `#A`, we can rewrite the set as `{3}`. This means we need to find +// evidence that each field of `a` is marked with a `3`. +// For the second case, `{2}`, we find that `#A` is embedded. As this is not +// a further restriction, we add the ID for `#A` to the set, resulting in +// `{2, 1}`. Subsequently, `#A` maps to `#B` again, but in this case, as `#A` +// is embedded, it is also additive, resulting in `{2, 1, 3}`, where each field +// in `a` needs to be marked with at least one of these values. +// +// After `a` is fully unified, field `b` will be marked with `3` and thus has +// evidence for both requirements. Field `c`, however, is marked with `2`, which +// is only supports the second requirement, and thus will result in a typo +// error. +// +// NOTE 1: that the second set is strictly more permissive then the first +// requirement and could be elided. +// NOTE 2: a reference to the same node within one field is only assigned a +// single ID and only needs to be processed once per node. +// +// ### Pruning of sub nodes +// +// For definitions, typo checking proceeds recursively. However, typo checking +// is disabled for certain fields, even when a node still has subfields. Typo +// checking is disabled if a field has: +// +// - a "naked" top `_` (so not, for instance `{_}`), - an ellipsis `...`, or - +// it has a "non-concrete" validator, like matchn. +// +// In the latter case, the builtin takes over the responsibility of checking the +// type. +// +import ( + "slices" + + "cuelang.org/go/cue/ast" +) + +type defID uint32 + +//go:generate go tool stringer -type=defIDType -linecomment + +type defIDType int8 + +const ( + // defIDTypeUnknown indicates that the ID is not a definition. + defIDTypeUnknown defIDType = iota // * + + defEmbedding // E + defReference // D + defStruct // S +) + +type containment struct { + id defID + n Node +} + +func (c *OpContext) getNextDefID(n Node) defID { + c.stats.NumCloseIDs++ + c.nextDefID++ + + if len(c.containments) == 0 { + // Our ID starts at 1. Create an extra element for the zero value. + c.containments = make([]containment, 1, 16) + } + c.containments = append(c.containments, containment{id: 0, n: n}) + + return c.nextDefID +} + +type refInfo struct { + v *Vertex + id defID + + // parent is used for enclosing structs and embedding relations. + parent defID + + // embed defines the scope of the embedding in which id is defined. + embed defID + + // ignore defines whether we should not do typo checking for this defID. + ignore bool + + // kind explains the type of defID. + kind defIDType + + // isRecursive indicates this is recursively closed. + isRecursive bool +} + +type conjunctFlags uint8 + +const ( + cHasEllipsis conjunctFlags = 1 << iota + cHasTop + cHasStruct + cHasOpenValidator +) + +type conjunctInfo struct { + id defID + embed defID + kind Kind + flags conjunctFlags +} + +func (c conjunctFlags) hasTop() bool { + return c&(cHasTop) != 0 +} + +func (c conjunctFlags) hasStruct() bool { + return c&(cHasStruct) != 0 +} + +func (c conjunctFlags) forceOpen() bool { + return c&(cHasOpenValidator) != 0 +} + +func (c conjunctFlags) hasEllipsis() bool { + return c&(cHasEllipsis) != 0 +} + +type replaceID struct { + from defID + to defID +} + +func (n *nodeContext) addReplacement(x replaceID) { + if x.from == x.to { + return + } + + if x.from < x.to && n.ctx.containments[x.to].id == 0 { + n.ctx.containments[x.to].id = x.from + return + } + + // TODO: we currently may compute n.reqSets too early in some rare + // circumstances. We clear the set if it needs to be recomputed. + n.computedCloseInfo = false + n.reqSets = n.reqSets[:0] + + n.replaceIDs = append(n.replaceIDs, x) +} + +func (n *nodeContext) updateConjunctInfo(k Kind, id CloseInfo, flags conjunctFlags) { + if n.ctx.OpenDef { + return + } + if id.defID != 0 && id.opID != n.ctx.opID { + n.ctx.stats.MisalignedConjunct++ + return + } + for i, c := range n.conjunctInfo { + if c.id == id.defID { + n.conjunctInfo[i].kind &= k + n.conjunctInfo[i].flags |= flags + return + } + } + n.ctx.stats.ConjunctInfos++ + n.conjunctInfo = append(n.conjunctInfo, conjunctInfo{ + id: id.defID, + embed: id.enclosingEmbed, + kind: k, + flags: flags, + }) + if len(n.conjunctInfo) > int(n.ctx.stats.MaxConjunctInfos) { + n.ctx.stats.MaxConjunctInfos = int64(len(n.conjunctInfo)) + } +} + +// addResolver adds a resolver to typo checking. Both definitions and +// non-definitions should typically be added: non-definitions may be added +// multiple times to a single node. As we only want to insert each conjunct +// once, we need to ensure that within all contexts a single ID assigned to such +// a resolver is tracked. +func (n *nodeContext) addResolver(p Node, v *Vertex, id CloseInfo, forceIgnore bool) CloseInfo { + if n.ctx.OpenDef { + return id + } + + if id.opID != 0 && id.opID != n.ctx.opID { + return id + } + + // This can only be true when not using the @experiment(explicitopen). + closeOuter := id.FromDef && id.FromEmbed && !id.Opened + + if closeOuter && !forceIgnore { + // Walk up the parent chain of the outer structs to "activate" them. + outerID := id.outerID + for i := len(n.reqDefIDs) - 1; i >= 0; i-- { + x := n.reqDefIDs[i] + if x.id == outerID && outerID != 0 { + n.reqDefIDs[i].ignore = false + if v.ClosedRecursive { + n.reqDefIDs[i].isRecursive = true + } + outerID = x.parent + } + } + } + + var ignore bool + switch { + case forceIgnore, id.Opened: + // Special mode to always ignore the outer enclosing group. + // This is the case, for instance, if a resolver resolves to a + // non-definition. + ignore = true + // TODO: Consider resetting FromDef. + // id.FromDef = false + case id.enclosingEmbed != 0 || id.outerID == 0: + // We have a reference within an inner embedding group. If this is + // a definition, or otherwise typo checked struct, we need to track + // the embedding for mutual compatibility. + // is a definition: + // a: { + // // Even though #A and #B do not constraint `a` individually, + // // they need to be checked for mutual consistency within + // // the embedding. + // #A & #B + // } + isClosed := id.FromDef || v.ClosedNonRecursive || v.ClosedRecursive + ignore = !isClosed + default: + // In the default case we can disable typo checking this type if it is + // an embedding. + ignore = id.FromEmbed + } + + dstID := defID(0) + for i, x := range n.reqDefIDs { + if x.v == v { + dstID = x.id + if x.ignore && !ignore { + // Override settings of a vertex added by #A... + n.reqDefIDs[i].ignore = false + n.reqDefIDs[i].parent = id.outerID + n.reqDefIDs[i].embed = id.enclosingEmbed + } + break + } + } + + if dstID == 0 || id.enclosingEmbed != 0 { + next := n.ctx.getNextDefID(p) + if dstID != 0 { + // If we need to activate an enclosing embed group, and the added + // resolver was already before, we need to allocate a new ID and + // add the original ID to the set of the new one. + n.addReplacement(replaceID{from: next, to: dstID}) + } + dstID = next + + n.reqDefIDs = append(n.reqDefIDs, refInfo{ + v: v, + id: dstID, + parent: id.outerID, + ignore: ignore, + kind: defReference, + embed: id.enclosingEmbed, + isRecursive: v.ClosedRecursive, + }) + } + srcID := id.defID + id.opID = n.ctx.opID + id.defID = dstID + + n.addReplacement(replaceID{from: srcID, to: dstID}) + + return id +} + +// subField updates a CloseInfo for subfields of a struct. +func (c *OpContext) subField(ci CloseInfo) CloseInfo { + // TODO: we mostly signal here that we need a new scope if a subfield has + // another embedding. IOW, we are overloading this field. This seems fine + // as, at this point, it seems to be only used for debugging. We may + // want to consider having a separate field for this, though. + ci.FromEmbed = false + + // The priority should be cleared for sub fields: we take default struct + // in its entirety, but not piecemeal. + ci.Priority = 0 + return ci +} + +// clearCloseCheck clears the CloseInfo for a node, so that it is not +// considered for typo checking. +func (id CloseInfo) clearCloseCheck() CloseInfo { + id.opID = 0 + id.defID = 0 + id.enclosingEmbed = 0 + id.outerID = 0 + return id +} + +func (n *nodeContext) newReq(p Node, id CloseInfo, kind defIDType) CloseInfo { + if id.defID != 0 && id.opID != n.ctx.opID { + return id.clearCloseCheck() + } + + dstID := n.ctx.getNextDefID(p) + n.addReplacement(replaceID{from: id.defID, to: dstID}) + + parent := id.defID + id.opID = n.ctx.opID + id.defID = dstID + + switch kind { + case defEmbedding: + id.enclosingEmbed = dstID + + case defStruct: + id.outerID = dstID + + default: + panic("unknown kind") + } + + // TODO: consider only adding when record || OpenGraph + n.reqDefIDs = append(n.reqDefIDs, refInfo{ + v: emptyNode, + id: dstID, + parent: parent, + embed: id.enclosingEmbed, + ignore: true, + kind: kind, + isRecursive: id.FromDef, + }) + + return id +} + +// AddOpenConjunct adds w as a conjunct of v and disables typo checking for w, +// even if it is a definition. +// This is called from UnifyAccept only. +func (v *Vertex) AddOpenConjunct(ctx *OpContext, w *Vertex) { + n := v.getBareState(ctx) + ci := n.injectEmbedNode(w, CloseInfo{}) + c := MakeConjunct(nil, w, ci) + v.AddConjunct(c) +} + +// injectEmbedNode is used to track typo checking within an embedding. +// Consider, for instance: +// +// #A: {a: int} +// #B: {b: int} +// #C: { +// #A & #B // fails +// c: int +// } +// +// In this case, even though #A and #B are both embedded, they are intended +// to be mutually exclusive. We track this by introducing a separate defID +// for the embedding. Suppose that the embedding #A&#B is assigned defID 2, +// where its parent is defID 1. Then #A is assigned 3 and #B is assigned 4. +// +// We can then say that requirement 3 (node A) holds if all fields contain +// either label 3, or any field within 1 that is not 2. +func (n *nodeContext) injectEmbedNode(x Decl, id CloseInfo) CloseInfo { + if pos(x).Experiment().ExplicitOpen { + return id + } + + id.FromEmbed = true + + // Filter cases where we do not need to track the definition. + switch x := x.(type) { + case *BinaryExpr: + if x.Op != AndOp { + return id + } + } + + return n.newReq(x, id, defEmbedding) +} + +// splitStruct is used to mark the outer struct of a field in which embeddings +// occur. The significance is that a reference to this node expects a node +// to be closed, even if it only has embeddings. Consider for instance: +// +// // A is closed and allows the fields of #B plus c. +// A: { { #B }, c: int } +// +// TODO(flatclose): this is a temporary solution to handle the case where a +// definition is embedded within a struct. It can be removed if we implement +// the #A vs #A... semantics. +func (n *nodeContext) splitStruct(s *StructLit, id CloseInfo) CloseInfo { + if pos(s).Experiment().ExplicitOpen || n.ctx.OpenDef { + return id + } + + if id.outerID != 0 { + // This is not strictly necessary, but it reduces the counters a bit. + return id + } + if id.FromEmbed { + // If we already had a struct within this field we can simply use it. + return id + } + + if _, ok := s.Src.(*ast.File); ok { + // If this is not a file, the struct indicates the scope/ + // boundary at which closedness should apply. This is not true + // for files. + // We should also not spawn if this is a nested Comprehension, + // where the spawn is already done as it may lead to spurious + // field not allowed errors. We can detect this with a nil s.Src. + // TODO(evalv3): use a more principled detection mechanism. + // TODO: set this as a flag in StructLit so as to not have to + // do the somewhat dangerous cast here. + return id + } + + return n.splitScope(s, id) +} + +func (n *nodeContext) splitScope(p Node, id CloseInfo) CloseInfo { + return n.newReq(p, id, defStruct) +} + +func (n *nodeContext) checkTypos() { + ctx := n.ctx + if ctx.OpenDef { + return + } + noDeref := n.node // noDeref retained for debugging purposes. + v := noDeref.DerefValue() + + // Stop early, avoiding the work in appendRequired below, if we have no arcs to check. + if len(v.Arcs) == 0 { + return + } + + // Avoid unnecessary errors. + if b, ok := v.BaseValue.(*Bottom); ok && !b.CloseCheck { + return + } + + baseRequired := getReqSets(n) + if len(baseRequired) == 0 { + return + } + + var err *Bottom + for _, a := range v.Arcs { + f := a.Label + + // TODO(mem): child states of uncompleted nodes must have a state. + a = a.DerefDisjunct() + na := a.state + // TODO(refcount): remove: cache in Vertex? + if na == nil { + // A node may be evaluated twice, for instance when processing + // validators. In this case, the closedness will already have been + // checked and the nodeContext may already be nil. + continue + } + + required := baseRequired + // If the field has its own rules, apply them as a delta. + // This requires a copy to not pollute the base for the next iteration. + if len(na.replaceIDs) > 0 { + required = slices.Clone(required) + } + + n.filterSets(&required, func(n *nodeContext, a *reqSet) bool { + if id := hasParentEllipsis(n, a, n.conjunctInfo); id != 0 { + a.removed = true + } + return true + }) + // TODO(perf): somehow prevent error generation of recursive structures, + // or at least make it cheap. Right now if this field is a typo, likely + // all descendents will be regarded as typos. + if b, ok := a.BaseValue.(*Bottom); ok { + if !b.CloseCheck { + continue + } + } + + if allowedInClosed(f) { + continue + } + + if na.hasEvidenceForAll(required, na.conjunctInfo) { + continue + } + + // TODO: do not descend on optional? + + if OpenGraphs { + openDebugGraph(ctx, a, "NOT ALLOWED") // Uncomment for debugging. + } + + if b := ctx.notAllowedError(a); b != nil && a.ArcType <= ArcRequired { + err = CombineErrors(nil, err, b) + } + } + + if err != nil { + n.AddChildError(err) // TODO: should not be necessary. + } +} + +// hasEvidenceForAll reports whether there is evidence in a set of +// conjuncts for each of the typo-checked structs represented by +// the reqSets. +func (n *nodeContext) hasEvidenceForAll(a reqSets, conjuncts []conjunctInfo) bool { + for i, rs := range a { + if rs.ignored { + continue + } + if rs.removed { + continue + } + + if !n.hasEvidenceForOne(a, uint32(i), conjuncts) { + if n.ctx.LogEval > 0 { + n.Logf("DENIED BY %d", a[i].id) + } + return false + } + } + return true +} + +// hasEvidenceForOne reports whether a single typo-checked set has evidence for +// any of its defIDs. +func (n *nodeContext) hasEvidenceForOne(all reqSets, i uint32, conjuncts []conjunctInfo) bool { + a := all[i] + for _, x := range conjuncts { + if n.containsDefID(a.id, x.id) { + return true + } + } + + embedScope, ok := all.lookupSet(a.embed) + if !ok { + return false + } + + outerScope, ok := all.lookupSet(a.parent) + +outer: + for _, c := range conjuncts { + if n.containsDefID(embedScope.id, c.embed) { + // Within the scope of the embedding. + continue outer + } + + if !ok || a.parent == 0 { + return true + } + if outerScope.removed { + return true + } + + // If this conjunct is within the outer struct, but outside the + // embedding scope, this means it was "added" and we do not have + // to verify it within the embedding scope. + if n.containsDefID(outerScope.id, c.id) { + return true + } + } + return false +} + +func (n *nodeContext) containsDefID(node, child defID) bool { + // TODO(perf): we could keep track of the minimum defID that could map so + // that we can use this to bail out early. + c := n.ctx + + key := [2]defID{node, child} + if result, ok := n.containsDefIDCache[key]; ok { + return result + } + + c.redirectsBuf = c.redirectsBuf[:0] + for p := n; p != nil; p = p.node.Parent.state { + if p.opID != n.opID { + break + } + c.redirectsBuf = append(c.redirectsBuf, p.replaceIDs...) + if p.node.Parent == nil { + break + } + } + + if int64(len(c.redirectsBuf)) > c.stats.MaxRedirect { + c.stats.MaxRedirect = int64(len(c.redirectsBuf)) + } + + result := n.containsDefIDRec(node, child, child) + + // Caching in [nodeContext.containsDefIDCache] adds overhead; + // only do it if we estimate that [nodeContext.containsDefIDRec] + // is doing significant work by looking at the number of replaceIDs. + if len(c.redirectsBuf) > 15 { + if n.containsDefIDCache == nil { + n.containsDefIDCache = make(map[[2]defID]bool) + } + n.containsDefIDCache[key] = result + } + + return result +} + +func (n *nodeContext) containsDefIDRec(node, child, start defID) bool { + c := n.ctx + + // NOTE: this loop is O(H) + for p := child; p != 0; { + if p == node { + return true + } + + // TODO(perf): can be binary search if we keep redirects sorted. Also, p + // should be monotonically decreasing, so we could use this to direct + // the binary search or-- at the very least--to only have to pass the + // array once. + for _, r := range c.redirectsBuf { + if r.to == p && r.from != child { + if n.containsDefIDRec(node, r.from, start) { + return true + } + } + } + + p = c.containments[p].id + if p == start { + // We won't match node we haven't already after one cycle. + return false + } + } + + return child == node +} + +// reqSets defines a set of sets of defIDs that can each satisfy a required id. +// +// A reqSet holds a sequence of a defID "representative", or "head" for a +// requirement, followed by all defIDs that satisfy this requirement. For head +// elements, size indicates the number of entries in the set, including the +// head. For non-head elements, size is 0. +type reqSets []reqSet + +// A single reqID might be satisfied by multiple defIDs, if the definition +// associated with the reqID embeds other definitions, for instance. In this +// case we keep a list of defIDs that may also be satisfied. +// +// This type is used in [nodeContext.equivalences] as follows: +// - if an embedding is used by a definition, it is inserted in the list +// pointed to by its refInfo. Similarly, +// refInfo is added to the list +type reqSet struct { + id defID + parent defID + embed defID // TODO(flatclose): can be removed later. + kind defIDType + + // once indicates that a reqSet closes only one level, i.e. closedness + // is the result of a close() + once bool + // ignored indicates whether this reqSet should be used to check closedness. + // A group can be ignored while still needed to determine the scope of + // an outer struct or embedding group. + // The value of ignored may flip from true to false (e.g. with an embedded + // definition) or false to true (e.g. getting out of scope of a close() + // builtin). + ignored bool + // removed is like ignore, but is permanent. Once removed, a reqSet cannot + // be "unremoved". In many cases we cannot actually remove a reqSet as + // we still need to track the group memberships for embeddings or enclosing + // structs. + removed bool +} + +// mergeCloseInfo merges the conjunctInfo of nw that is missing from nv into nv. +// +// This is used to merge conjunctions from a disjunct to the Vertex that +// originated the disjunct. +// TODO: consider whether we can do without. We usually aim to not check +// such nodes, but sometimes we do. +func mergeCloseInfo(nv, nw *nodeContext) { + v := nv.node + w := nw.node + if w == nil { + return + } + // Merge missing conjunct infos +outer: + for _, wci := range nw.conjunctInfo { + for _, vci := range nv.conjunctInfo { + if wci.id == vci.id { + continue outer + } + } + nv.conjunctInfo = append(nv.conjunctInfo, wci) + if nw.ctx != nil { + nw.ctx.stats.ConjunctInfos++ + if len(nw.conjunctInfo) > int(nw.ctx.stats.MaxConjunctInfos) { + nw.ctx.stats.MaxConjunctInfos = int64(len(nw.conjunctInfo)) + } + } + } + +outer2: + for _, d := range nw.replaceIDs { + for _, vd := range nv.replaceIDs { + if d == vd { + continue outer2 + } + } + nv.replaceIDs = append(nv.replaceIDs, d) + } + + for _, wa := range w.Arcs { + for _, va := range v.Arcs { + if va.Label == wa.Label { + mergeCloseInfo(va.state, wa.state) + break + } + } + } +} + +// getReqSets initializes, if necessary, and returns the reqSets for n. +func getReqSets(n *nodeContext) reqSets { + if n == nil { + return nil + } + + if n.computedCloseInfo { + return n.reqSets + } + + a := n.reqSets[:0] + v := n.node + + if p := v.Parent; p != nil && !n.dropParentRequirements { + a = append(a, getReqSets(p.state)...) + n.filterNonRecursive(&a) + } + + last := len(a) - 1 + +outer: + for _, y := range n.reqDefIDs { + // A defReference is never "reactivated" once it is ignored. + // Embeddings we need to keep around to compute the embedding scope, + // even when the embedding itself is ignored. + if y.ignore && y.kind == defReference { + continue + } + + for _, x := range a { + if x.id == y.id { + continue outer + } + } + once := false + if y.v != nil && y.kind != defEmbedding { + once = y.v.ClosedNonRecursive + if !y.ignore && !y.isRecursive { + once = true + } + } + + a = append(a, reqSet{ + id: y.id, + parent: y.parent, + once: once, + ignored: y.ignore, + embed: y.embed, + kind: y.kind, + }) + + if y.parent != 0 && !y.ignore { + // Enable outer structs for checking. + outerID := y.parent + for i := last; i >= 0 && outerID != 0; i-- { + x := a[i] + if x.id == outerID { + if a[i].ignored { + a[i].once = !y.isRecursive + } else { + a[i].once = a[i].once && !y.isRecursive + } + a[i].ignored = false + outerID = x.parent + } + } + } + } + + // If 'v' is a hidden field, then all reqSets in 'a' for which there is no + // corresponding entry in conjunctInfo should be removed from 'a'. + if allowedInClosed(v.Label) { + n.filterSets(&a, func(n *nodeContext, a *reqSet) bool { + for _, c := range n.conjunctInfo { + if n.containsDefID(a.id, c.id) { + return true // keep the set + } + } + return false // discard the set + }) + } + + var parentConjuncts []conjunctInfo + if p := v.Parent; p != nil && p.state != nil { + parentConjuncts = p.state.conjunctInfo + } + + n.filterTop(&a, n.conjunctInfo, parentConjuncts) + + n.computedCloseInfo = true + if int64(len(a)) > n.ctx.stats.MaxReqSets { + n.ctx.stats.MaxReqSets = int64(len(a)) + } + n.reqSets = a + return a +} + +// If there is a top or ellipsis for all supported conjuncts, we have +// evidence that this node can be dropped. +func (n *nodeContext) filterTop(a *reqSets, conjuncts, parentConjuncts []conjunctInfo) (openLevel bool) { + n.filterSets(a, func(n *nodeContext, a *reqSet) bool { + var f conjunctFlags + hasAny := false + + for _, c := range conjuncts { + if n.containsDefID(a.id, c.id) { + hasAny = true + flags := c.flags + if c.id < a.id { + flags &^= cHasStruct + } + f |= flags + } + } + if (f.hasTop() && !f.hasStruct()) || f.forceOpen() { + return false + } + + if hasAny && a.kind != defStruct { + // fast path. + return true + } + + switch id := hasParentEllipsis(n, a, parentConjuncts); { + case id == 0: + case !hasAny: + a.removed = true + case a.kind != defStruct: + // The following logic should only apply to non-structs. + default: + hasAny = false + for _, c := range conjuncts { + if n.containsDefID(id, c.id) { + hasAny = true + } + } + if !hasAny { + a.removed = true + } + } + + return true + }) + return openLevel +} + +// hasParentEllipsis reports if the parent has any conjuncts from an ellipsis +// matching any of the ids in a. +// +// TODO: this is currently called twice. Consider an approach where we only need +// to filter this once for each node. Luckily we can avoid quadratic checks +// for any conjunct that is not an ellipsis, which is most. +func hasParentEllipsis(n *nodeContext, a *reqSet, conjuncts []conjunctInfo) defID { + for _, c := range conjuncts { + if !c.flags.hasEllipsis() { + continue + } + if n.containsDefID(a.id, c.id) { + return c.id + } + } + return 0 +} + +func (n *nodeContext) filterNonRecursive(a *reqSets) { + n.filterSets(a, func(n *nodeContext, e *reqSet) bool { + x := e + if x.once { // || x.id == 0 + e.ignored = true + } + return true // keep the entry + }) +} + +// filter keeps all reqSets e in a for which f(e) and removes the rest. +func (n *nodeContext) filterSets(a *reqSets, f func(n *nodeContext, e *reqSet) bool) { + temp := (*a)[:0] + for i := range *a { + set := (*a)[i] + + if f(n, &set) { + temp = append(temp, set) + } + } + *a = temp +} + +// lookupSet returns the set in a with the given id or nil if no such set. +func (a reqSets) lookupSet(id defID) (reqSet, bool) { + if id != 0 { + for i := range a { + if a[i].id == id { + return a[i], true + } + } + } + return reqSet{}, false +} diff --git a/vendor/cuelang.org/go/internal/core/adt/unify.go b/vendor/cuelang.org/go/internal/core/adt/unify.go index c145948bd7..8beeabcf8b 100644 --- a/vendor/cuelang.org/go/internal/core/adt/unify.go +++ b/vendor/cuelang.org/go/internal/core/adt/unify.go @@ -26,7 +26,11 @@ func (v *Vertex) isInitialized() bool { } func (n *nodeContext) assertInitialized() { - if n != nil && n.ctx.isDevVersion() { + if n != nil { + if n.node == nil { + // Can happen for unit tests. + return + } if v := n.node; !v.isInitialized() { panic(fmt.Sprintf("vertex %p not initialized", v)) } @@ -46,12 +50,8 @@ func (v *Vertex) getBareState(c *OpContext) *nodeContext { if v.state == nil { v.state = c.newNodeContext(v) v.state.initBare() - v.state.refCount = 1 } - // An additional refCount for the current user. - v.state.refCount += 1 - // TODO: see if we can get rid of ref counting after new evaluator is done: // the recursive nature of the new evaluator should make this unnecessary. @@ -107,60 +107,84 @@ func (n *nodeContext) scheduleConjuncts() { defer ctx.PopArc(ctx.PushArc(v)) - root := n.node.rootCloseContext(n.ctx) - root.incDependent(n.ctx, INIT, nil) // decremented below - - for _, c := range v.Conjuncts { + for i, c := range v.Conjuncts { + _ = i // for debugging purposes ci := c.CloseInfo - ci.cc = root + ci = ctx.combineCycleInfo(ci) n.scheduleConjunct(c, ci) } - - root.decDependent(ctx, INIT, nil) } // TODO(evalv3): consider not returning a result at all. -func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { +// +// func (v *Vertex) unify@(c *OpContext, needs condition, mode runMode) bool { +// return v.unifyC(c, needs, mode, true) +// } +func (v *Vertex) unify(c *OpContext, flags Flags) bool { + needs := flags.condition + mode := flags.mode + checkTypos := flags.checkTypos + if c.LogEval > 0 { - c.Logf(v, "Unify %v", fmt.Sprintf("%p", v)) - c.nest++ - defer func() { - c.nest-- - c.Logf(v, "END Unify") - }() - } - - if c.evalDepth == 0 { - defer func() { - // This loop processes nodes that need to be evaluated, but should be - // evaluated outside of the stack to avoid structural cycle detection. - // See comment at toFinalize. - a := c.toFinalize - c.toFinalize = c.toFinalize[:0] - for _, x := range a { - x.Finalize(c) - } - }() + defer c.Un(c.Indentf(v, "UNIFY(%x, %v)", needs, mode)) } + // TODO: investigate whether we still need this mechanism. + // + // This has been disabled to fix Issue #3709. This was added in lieu of a + // proper depth detecting mechanism. This has been implemented now, but + // we keep this around to investigate certain edge cases, such as + // depth checking across inline vertices. + // + // if c.evalDepth == 0 { + // defer func() { + // // This loop processes nodes that need to be evaluated, but should be + // // evaluated outside of the stack to avoid structural cycle detection. + // // See comment at toFinalize. + // a := c.toFinalize + // c.toFinalize = c.toFinalize[:0] + // for _, x := range a { + // x.Finalize(c) + // } + // }() + // } + if mode == ignore { return false } + if n := v.state; n != nil && n.ctx.opID != c.opID { + // TODO: we could clear the closedness information. + // v.state = nil + // v.status = finalized + // for _, c := range v.Conjuncts { + // c.CloseInfo.defID = 0 + // c.CloseInfo.enclosingEmbed = 0 + // c.CloseInfo.outerID = 0 + // } + c.stats.GenerationMismatch++ + } + // Note that the state of a node can be removed before the node is. // This happens with the close builtin, for instance. // See TestFromAPI in pkg export. // TODO(evalv3): find something more principled. - if v.state == nil && v.cc() != nil && v.cc().conjunctCount == 0 { - v.status = finalized - return true - } - n := v.getState(c) if n == nil { return true // already completed } - defer n.free() + + n.retainProcess() + defer func() { + n.releaseProcess() + if v.state != nil && v.status == finalized { + n.ctx.reclaimTempBuffers(v) + } + }() + + // TODO(perf): reintroduce freeing once we have the lifetime under control. + // Right now this is not managed anyway, so we prevent bugs by disabling it. + // defer n.free() // Typically a node processes all conjuncts before processing its fields. // So this condition is very likely to trigger. If for some reason the @@ -173,7 +197,7 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { // Note that if mode is final, we will guarantee that the conditions for // this if clause are met down the line. So we assume this is already the // case and set the signal accordingly if so. - if !v.Rooted() || v.Parent.allChildConjunctsKnown() || mode == finalize { + if !v.Rooted() || v.Parent.allChildConjunctsKnown(c) || mode == finalize { n.signal(allAncestorsProcessed) } @@ -192,11 +216,18 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { // through an expression. As long as there is no request to process arcs or // finalize the value, we can and should stop processing here to avoid // spurious cycles. - if v.status == evaluating && - v.state.evalDepth == c.evalDepth && - needs&fieldSetKnown == 0 && - mode != finalize { - return false + + if v.status == evaluating && v.state.evalDepth == c.evalDepth { + switch mode { + case finalize: + // We will force completion below. + case yield: + // TODO: perhaps add to queue in some condition. + default: + if needs&fieldSetKnown == 0 { + return false + } + } } v.status = evaluating @@ -206,15 +237,25 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { if n.node.ArcType == ArcPending { // forcefully do an early recursive evaluation to decide the state // of the arc. See https://cuelang.org/issue/3621. - n.process(nodeOnlyNeeds, attemptOnly) + n.process(pendingKnown, attemptOnly) if n.node.ArcType == ArcPending { for _, a := range n.node.Arcs { - a.unify(c, needs, attemptOnly) + a.unify(c, Flags{condition: needs, mode: attemptOnly, checkTypos: checkTypos}) } } + // TODO(evalv3): do we need this? Error messages are slightly better, + // but adding leads to Issue #3941. + // n.completePending(yield) } + n.process(nodeOnlyNeeds, mode) + if n.node.ArcType != ArcPending && + n.meets(allAncestorsProcessed) && + len(n.tasks) == n.taskPos { + n.signal(arcTypeKnown) + } + defer c.PopArc(c.PushArc(v)) w := v.DerefDisjunct() @@ -223,7 +264,10 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { v.ClosedRecursive = w.ClosedRecursive v.status = w.status v.ChildErrors = CombineErrors(nil, v.ChildErrors, w.ChildErrors) - v.Arcs = nil + v.clearArcs(c) + if w.status == finalized { + return true + } return w.state.meets(needs) } n.updateScalar() @@ -258,13 +302,6 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { n.validateValue(state) } - if n.node.Label.IsLet() || n.meets(allAncestorsProcessed) { - if cc := v.rootCloseContext(n.ctx); !cc.isDecremented { // TODO: use v.cc - cc.decDependent(c, ROOT, nil) // REF(decrement:nodeDone) - cc.isDecremented = true - } - } - if v, ok := n.node.BaseValue.(*Vertex); ok && n.shareCycleType == NoCycle { if n.ctx.hasDepthCycle(v) { n.reportCycleError() @@ -272,7 +309,7 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { } // We unify here to proactively detect cycles. We do not need to, // nor should we, if have have already found one. - v.unify(n.ctx, needs, mode) + v.unify(n.ctx, Flags{condition: needs, mode: mode, checkTypos: checkTypos}) } // At this point, no more conjuncts will be added, so we could decrement @@ -285,9 +322,19 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { case needs&subFieldsProcessed != 0: switch { case assertStructuralCycleV3(n): - n.breakIncomingDeps(mode) + + case n.node.status == finalized: + // There is no need to recursively process if the node is already + // finalized. This can happen if there was an error, for instance. + // This may drop a structural cycle error, but as long as the node + // already is erroneous, that is fine. It is probably possible to + // skip more processing if the node is already finalized. + // TODO: consider bailing on error if n.errs != nil. - case n.completeAllArcs(needs, mode): + // At the very least, no longer propagate typo errors if this node + // is erroneous. + case n.kind == BottomKind: + case n.completeAllArcs(needs, mode, checkTypos): } if mode == finalize { @@ -326,6 +373,8 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { n.setBaseValue(err) } + n.finalizeDisjunctions() + if mode == attemptOnly { return n.meets(needs) } @@ -335,14 +384,22 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { n.signal(mask) } - n.finalizeDisjunctions() - w = v.DerefValue() // Dereference anything, including shared nodes. if w != v { // Clear value fields that are now referred to in the dereferenced // value (w). + v.clearArcs(c) v.ChildErrors = nil - v.Arcs = nil + + if n.completed&(subFieldsProcessed) == 0 { + // Ensure the shared node is processed to the requested level. This is + // typically needed for scalar values. + if w.status == unprocessed { + w.unify(c, Flags{condition: needs, mode: mode, checkTypos: false}) + } + + return n.meets(needs) + } // Set control fields that are referenced without dereferencing. if w.ClosedRecursive { @@ -353,15 +410,29 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { if w.HasEllipsis { v.HasEllipsis = true } + v.status = w.status + n.finalizeSharing() + + // TODO: find a more principled way to catch this cycle and avoid this + // check. + if n.hasAncestorV3(w) { + n.reportCycleError() + return true + } + // Ensure that shared nodes comply to the same requirements as we // need for the current node. - w.unify(c, needs, mode) + w.unify(c, Flags{condition: needs, mode: mode, checkTypos: checkTypos}) return true } + if n.completed&(subFieldsProcessed) == 0 { + return n.meets(needs) + } + // TODO: adding this is wrong, but it should not cause the snippet below // to hang. Investigate. // v.Closed = v.cc.isClosed @@ -376,54 +447,55 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { // } // validationCompleted - if n.completed&(subFieldsProcessed) != 0 { - n.node.HasEllipsis = n.node.cc().isTotal - - // The next piece of code used to address the following case - // (order matters) - // - // c1: c: [string]: f2 - // f2: c1 - // Also: cycle/issue990 - // - // However, with recent changes, it no longer matters. Simultaneously, - // this causes a hang in the following case: - // - // _self: x: [...and(x)] - // _self - // x: [1] - // - // For this reason we disable it now. It may be the case that we need - // to enable it for computing disjunctions. - // - n.incDepth() - defer n.decDepth() - - if pc := n.node.PatternConstraints; pc != nil { - for _, c := range pc.Pairs { - c.Constraint.unify(n.ctx, allKnown, attemptOnly) - } - } - - n.node.updateStatus(finalized) + // The next piece of code used to address the following case + // (order matters) + // + // c1: c: [string]: f2 + // f2: c1 + // Also: cycle/issue990 + // + // However, with recent changes, it no longer matters. Simultaneously, + // this causes a hang in the following case: + // + // _self: x: [...and(x)] + // _self + // x: [1] + // + // For this reason we disable it now. It may be the case that we need + // to enable it for computing disjunctions. + // + n.incDepth() + defer n.decDepth() - defer n.unmarkOptional(n.markOptional()) + // TODO: find more strategic place to set ClosedRecursive and get rid + // of helper fields. + blockClose := n.hasTop + if n.hasStruct { + blockClose = false + } + if n.hasOpenValidator { + blockClose = true + } + if n.isDef && !blockClose { + n.node.ClosedRecursive = true + } - if DebugDeps { - switch n.node.BaseValue.(type) { - case *Disjunction: - // If we have a disjunction, its individual disjuncts will - // already have been checked. The node itself will likely have - // spurious results, as it will contain unclosed holes. + if checkTypos { + n.checkTypos() + } - case *Vertex: - // No need to check dereferenced results. + // After this we no longer need the defIDs of the conjuncts. By clearing + // them we ensure that we do not have rogue index values into the + // [OpContext.containments]. + // for i := range n.node.Conjuncts { + // // Consider if this is necessary now we have generations. + // c := &n.node.Conjuncts[i] + // c.CloseInfo.defID = 0 + // c.CloseInfo.enclosingEmbed = 0 + // c.CloseInfo.outerID = 0 + // } - default: - RecordDebugGraph(n.ctx, n.node, "Finalize") - } - } - } + v.updateStatus(finalized) return n.meets(needs) } @@ -447,7 +519,18 @@ func (v *Vertex) unify(c *OpContext, needs condition, mode runMode) bool { // NOT: // - complete value. That is reserved for Unify. func (n *nodeContext) completeNodeTasks(mode runMode) { - n.assertInitialized() + if n.ctx.LogEval > 0 { + defer n.ctx.Un(n.ctx.Indentf(n.node, "(%v)", mode)) + } + + // In attemptOnly mode, don't assert initialization to allow processing + // of partially initialized vertices + if mode != attemptOnly { + n.assertInitialized() + } else if n.node != nil && !n.node.isInitialized() { + // In attemptOnly mode, skip processing if vertex is not initialized + return + } if n.isCompleting > 0 { return @@ -458,14 +541,6 @@ func (n *nodeContext) completeNodeTasks(mode runMode) { }() v := n.node - c := n.ctx - - if n.ctx.LogEval > 0 { - c.nest++ - defer func() { - c.nest-- - }() - } if !v.Label.IsLet() { if p := v.Parent; p != nil && p.state != nil { @@ -475,7 +550,7 @@ func (n *nodeContext) completeNodeTasks(mode runMode) { } } - if v.IsDynamic || v.Label.IsLet() || v.Parent.allChildConjunctsKnown() { + if v.IsDynamic || v.Label.IsLet() || v.Parent.allChildConjunctsKnown(n.ctx) { n.signal(allAncestorsProcessed) } @@ -487,8 +562,6 @@ func (n *nodeContext) completeNodeTasks(mode runMode) { n.updateScalar() } - n.breakIncomingNotifications(mode) - // As long as ancestors are not processed, it is still possible for // conjuncts to be inserted. Until that time, it is not okay to decrement // theroot. It is not necessary to wait on tasks to complete, though, @@ -497,27 +570,20 @@ func (n *nodeContext) completeNodeTasks(mode runMode) { if !n.meets(allAncestorsProcessed) && !n.node.Label.IsLet() && mode != finalize { return } - - // At this point, no more conjuncts will be added, so we could decrement - // the notification counters. - - if cc := v.rootCloseContext(n.ctx); !cc.isDecremented { // TODO: use v.cc - cc.isDecremented = true - - cc.decDependent(n.ctx, ROOT, nil) // REF(decrement:nodeDone) - } } func (n *nodeContext) updateScalar() { // Set BaseValue to scalar, but only if it was not set before. Most notably, // errors should not be discarded. if n.scalar != nil && (!n.node.IsErr() || isCyclePlaceholder(n.node.BaseValue)) { - n.setBaseValue(n.scalar) + if v, ok := n.node.BaseValue.(*Vertex); !ok || !v.IsDisjunct { + n.setBaseValue(n.scalar) + } n.signal(scalarKnown) } } -func (n *nodeContext) completeAllArcs(needs condition, mode runMode) bool { +func (n *nodeContext) completeAllArcs(needs condition, mode runMode, checkTypos bool) bool { if n.underlying != nil { // References within the disjunct may end up referencing the layer that // this node overlays. Also for these nodes we want to be able to detect @@ -537,19 +603,23 @@ func (n *nodeContext) completeAllArcs(needs condition, mode runMode) bool { // Investigate how to work around this. n.completeNodeTasks(finalize) - n.breakIncomingDeps(mode) - n.incDepth() defer n.decDepth() + // TODO: do something more principled here.s + if n.hasDisjunction { + checkTypos = false + } + // XXX(0.7): only set success if needs complete arcs. success := true // Visit arcs recursively to validate and compute error. Use index instead // of range in case the Arcs grows during processing. for arcPos := 0; arcPos < len(n.node.Arcs); arcPos++ { a := n.node.Arcs[arcPos] + // TODO: Consider skipping lets. - if !a.unify(n.ctx, needs, mode) { + if !a.unify(n.ctx, Flags{condition: needs, mode: mode, checkTypos: checkTypos}) { success = false } @@ -617,7 +687,11 @@ func (n *nodeContext) completeAllArcs(needs condition, mode runMode) bool { ctx := n.ctx f := ctx.PushState(c.env, c.expr.Source()) - v := ctx.evalState(c.expr, oldOnly(finalized)) + v := ctx.evalState(c.expr, Flags{ + status: finalized, + condition: allKnown, + mode: ignore, + }) v, _ = ctx.getDefault(v) v = Unwrap(v) @@ -670,12 +744,45 @@ func (n *nodeContext) completeAllArcs(needs condition, mode runMode) bool { return success } +// completePending determines if n is pending. In order to do so, it must +// recursively find any descendents with unresolved comprehensions. Note that +// it is currently possible for arcs with unresolved comprehensions to not be +// marked as pending. Consider this example (from issue 3708): +// +// out: people.bob.kind +// people: [string]: { +// kind: "person" +// name?: string +// } +// if true { +// people: bob: name: "Bob" +// } +// +// In this case, the pattern constraint inserts fields into 'bob', which then +// marks 'name' as not pending. However, for 'people' to become non-pending, +// the comprehension associated with field 'name' still needs to be evaluated. +// +// For this reason, this method does not check whether 'n' is pending. +// +// TODO(evalv4): consider making pending not an arc state, but rather a +// separate mode. This will allow us to descend with more precision to only +// visit arcs that still need to be resolved. +func (n *nodeContext) completePending(mode runMode) { + for _, a := range n.node.Arcs { + state := a.getState(n.ctx) + if state != nil { + state.completePending(mode) + } + } + n.process(pendingKnown, mode) +} + func (n *nodeContext) evalArcTypes(mode runMode) { for _, a := range n.node.Arcs { if a.ArcType != ArcPending { continue } - a.unify(n.ctx, arcTypeKnown, mode) + a.unify(n.ctx, Flags{condition: arcTypeKnown, mode: mode, checkTypos: false}) // Ensure the arc is processed up to the desired level if a.ArcType == ArcPending { // TODO: cancel tasks? @@ -691,14 +798,16 @@ func root(v *Vertex) *Vertex { return v } -func (v *Vertex) lookup(c *OpContext, pos token.Pos, f Feature, flags combinedFlags) *Vertex { +func (v *Vertex) lookup(c *OpContext, pos token.Pos, f Feature, flags Flags) *Vertex { task := c.current() - needs := flags.conditions() - runMode := flags.runMode() + needs := flags.condition + runMode := flags.mode v = v.DerefValue() - c.Logf(c.vertex, "LOOKUP %v", f) + if c.LogEval > 0 { + c.Logf(c.vertex, "LOOKUP %v", f) + } state := v.getState(c) if state != nil { @@ -718,7 +827,9 @@ func (v *Vertex) lookup(c *OpContext, pos token.Pos, f Feature, flags combinedFl // A lookup counts as new structure. See the commend in Section // "Lookups in inline cycles" in cycle.go. - state.hasNonCycle = true + // TODO: this seems no longer necessary and setting this will cause some + // hangs. Investigate. + // state.hasNonCycle = true // TODO: ideally this should not be run at this point. Consider under // which circumstances this is still necessary, and at least ensure @@ -768,26 +879,11 @@ func (v *Vertex) lookup(c *OpContext, pos token.Pos, f Feature, flags combinedFl } if arcState != nil && (!arcState.meets(needTasksDone) || !arcState.meets(arcTypeKnown)) { - needs |= arcTypeKnown - // If this arc is not ArcMember, which it is not at this point, - // any pending arcs could influence the field set. - for _, a := range arc.Arcs { - if a.ArcType == ArcPending { - needs |= fieldSetKnown - break - } - } + arcState.completePending(attemptOnly) + arcState.completeNodeTasks(yield) - // Child nodes, if pending and derived from a comprehension, may - // still cause this arc to become not pending. - if arc.ArcType != ArcMember { - for _, a := range arcState.node.Arcs { - if a.ArcType == ArcPending { - a.unify(c, arcTypeKnown, runMode) - } - } - } + needs |= arcTypeKnown switch runMode { case ignore, attemptOnly: @@ -795,14 +891,9 @@ func (v *Vertex) lookup(c *OpContext, pos token.Pos, f Feature, flags combinedFl // arcType be known at this point, but that does not seem to work. // Revisit once we have the structural cycle detection in place. - // TODO: should we avoid notifying ArcPending vertices here? - if task != nil { - arcState.addNotify2(task.node.node, task.id) - } if arc.ArcType == ArcPending { return arcReturn } - goto handleArcType case yield: arcState.process(needs, yield) @@ -810,14 +901,39 @@ func (v *Vertex) lookup(c *OpContext, pos token.Pos, f Feature, flags combinedFl // in an invalid field. case finalize: - // TODO: should we try to use finalize? Using it results in errors and this works. It would be more principled, though. - arcState.process(needs, yield) + // TODO: we should try to always use finalize? Using it results in + // errors. For now we only use it for let values. Let values are + // not normally finalized (they may be cached) and as such might + // not trigger the usual unblocking. Force unblocking may cause + // some values to be remain unevaluated. + switch { + case needs == arcTypeKnown|fieldSetKnown: + arc.unify(c, Flags{condition: needs, mode: finalize, checkTypos: false}) + default: + // Now we can't finalize, at least try to get as far as we + // can and only yield if we really have to. + if !arc.unify(c, Flags{condition: needs, mode: attemptOnly, checkTypos: false}) { + arcState.process(needs, yield) + } + } + if arc.ArcType == ArcPending { + arc.ArcType = ArcNotPresent + } } } -handleArcType: switch arc.ArcType { - case ArcMember, ArcRequired: + case ArcRequired: + label := f.SelectorString(c.Runtime) + b := &Bottom{ + Code: IncompleteError, + Err: c.NewPosf(pos, "required field missing: %s", label), + Node: v, + } + // TODO: yield failure + c.AddBottom(b) // TODO: unify error mechanism. + return arcReturn + case ArcMember: return arcReturn case ArcOptional: @@ -870,5 +986,17 @@ func (v *Vertex) accept(ctx *OpContext, f Feature) bool { return false } - return matchPattern(ctx, pc.Allowed, f) + // TODO: parhaps use matchPattern again if we have an allowed. + if matchPattern(ctx, pc.Allowed, f) { + return true + } + + // TODO: fall back for now to just matching any pattern. + for _, c := range pc.Pairs { + if matchPattern(ctx, c.Pattern, f) { + return true + } + } + + return false } diff --git a/vendor/cuelang.org/go/internal/core/adt/validate.go b/vendor/cuelang.org/go/internal/core/adt/validate.go new file mode 100644 index 0000000000..6de64d9163 --- /dev/null +++ b/vendor/cuelang.org/go/internal/core/adt/validate.go @@ -0,0 +1,202 @@ +// Copyright 2020 CUE Authors +// +// 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. + +package adt + +type ValidateConfig struct { + // Concrete, if true, requires that all values be concrete. + Concrete bool + + // Final, if true, checks that there are no required fields left. + Final bool + + // DisallowCycles indicates that there may not be cycles. + DisallowCycles bool + + // ReportIncomplete reports an incomplete error even when concrete is not + // requested. + ReportIncomplete bool + + // AllErrors continues descending into a Vertex, even if errors are found. + AllErrors bool + + // TODO: omitOptional, if this is becomes relevant. +} + +// Validate checks that a value has certain properties. The value must have +// been evaluated. +func Validate(ctx *OpContext, v *Vertex, cfg *ValidateConfig) *Bottom { + if cfg == nil { + cfg = &ValidateConfig{} + } + x := validator{ValidateConfig: *cfg, ctx: ctx} + x.validate(v) + return x.err +} + +// validateValue checks that a value has certain properties. The value must have +// been evaluated. +func validateValue(ctx *OpContext, v Value, cfg *ValidateConfig) *Bottom { + if cfg == nil { + cfg = &ValidateConfig{} + } + + if v.Concreteness() > Concrete { + return &Bottom{ + Code: IncompleteError, + Err: ctx.Newf("non-concrete value '%v'", v), + Node: ctx.vertex, + } + } + + if x, ok := v.(*Vertex); ok { + if v.Kind()&(StructKind|ListKind) != 0 { + x.Finalize(ctx) + } + return Validate(ctx, x, cfg) + } + + return nil +} + +type validator struct { + ValidateConfig + ctx *OpContext + err *Bottom + inDefinition int + + sharedPositions []Node + + // shared vertices should be visited at least once if referenced by + // a non-definition. + // TODO: we could also keep track of the number of references to a + // shared vertex. This would allow us to report more than a single error + // per shared vertex. + visited map[*Vertex]bool +} + +func (v *validator) addPositions(err *ValueError) { + for _, p := range v.sharedPositions { + err.AddPosition(p) + } +} + +func (v *validator) checkConcrete() bool { + return v.Concrete && v.inDefinition == 0 +} + +func (v *validator) checkFinal() bool { + return (v.Concrete || v.Final) && v.inDefinition == 0 +} + +func (v *validator) add(b *Bottom) { + if !v.AllErrors { + v.err = CombineErrors(nil, v.err, b) + return + } + if !b.ChildError { + v.err = CombineErrors(nil, v.err, b) + } +} + +func (v *validator) validate(x *Vertex) { + defer v.ctx.PopArcAndLabel(v.ctx.PushArcAndLabel(x)) + + y := x + + if x.IsShared { + saved := v.sharedPositions + // assume there is always a single conjunct: multiple references either + // result in the same shared value, or no sharing. And there has to be + // at least one to be able to share in the first place. + c, n := x.SingleConjunct() + if n >= 1 { + v.sharedPositions = append(v.sharedPositions, c.Elem()) + } + defer func() { v.sharedPositions = saved }() + } + // Dereference values, but only those that are not shared. This includes let + // values. This prevents us from processing structure-shared nodes more than + // once and prevents potential cycles. + x = x.DerefValue() + if y != x { + // Ensure that each structure shared node is processed at least once + // in a position that is not a definition. + if v.inDefinition > 0 { + return + } + if v.visited == nil { + v.visited = make(map[*Vertex]bool) + } + if v.visited[x] { + return + } + v.visited[x] = true + } + + if b := x.Bottom(); b != nil { + switch b.Code { + case CycleError: + if v.checkFinal() || v.DisallowCycles { + v.add(b) + } + + case IncompleteError: + if v.ReportIncomplete || v.checkConcrete() { + v.add(b) + } + + default: + v.add(b) + } + if !b.HasRecursive { + return + } + + } else if v.checkConcrete() { + x = x.Default() + if !IsConcrete(x) { + x := x.Value() + err := v.ctx.Newf("incomplete value %v", x) + v.addPositions(err) + v.add(&Bottom{ + Code: IncompleteError, + Err: err, + }) + } + } + + for _, a := range x.Arcs { + if a.ArcType == ArcRequired && v.Final && v.inDefinition == 0 { + v.ctx.PushArcAndLabel(a) + v.add(NewRequiredNotPresentError(v.ctx, a, v.sharedPositions...)) + v.ctx.PopArcAndLabel(a) + continue + } + + if a.Label.IsLet() || !a.IsDefined(v.ctx) { + continue + } + if !v.AllErrors && v.err != nil { + break + } + if a.Label.IsRegular() { + v.validate(a) + } else { + v.inDefinition++ + v.validate(a) + v.inDefinition-- + } + } +} diff --git a/vendor/cuelang.org/go/internal/core/adt/vertexstatus_string.go b/vendor/cuelang.org/go/internal/core/adt/vertexstatus_string.go index 789f0883bb..4c7893ad09 100644 --- a/vendor/cuelang.org/go/internal/core/adt/vertexstatus_string.go +++ b/vendor/cuelang.org/go/internal/core/adt/vertexstatus_string.go @@ -12,17 +12,17 @@ func _() { _ = x[evaluating-1] _ = x[partial-2] _ = x[conjuncts-3] - _ = x[evaluatingArcs-4] - _ = x[finalized-5] + _ = x[finalized-4] } -const _vertexStatus_name = "unprocessedevaluatingpartialconjunctsevaluatingArcsfinalized" +const _vertexStatus_name = "unprocessedevaluatingpartialconjunctsfinalized" -var _vertexStatus_index = [...]uint8{0, 11, 21, 28, 37, 51, 60} +var _vertexStatus_index = [...]uint8{0, 11, 21, 28, 37, 46} func (i vertexStatus) String() string { - if i < 0 || i >= vertexStatus(len(_vertexStatus_index)-1) { + idx := int(i) - 0 + if i < 0 || idx >= len(_vertexStatus_index)-1 { return "vertexStatus(" + strconv.FormatInt(int64(i), 10) + ")" } - return _vertexStatus_name[_vertexStatus_index[i]:_vertexStatus_index[i+1]] + return _vertexStatus_name[_vertexStatus_index[idx]:_vertexStatus_index[idx+1]] } diff --git a/vendor/cuelang.org/go/internal/core/compile/builtin.go b/vendor/cuelang.org/go/internal/core/compile/builtin.go index 79e5bbca47..c7d60de800 100644 --- a/vendor/cuelang.org/go/internal/core/compile/builtin.go +++ b/vendor/cuelang.org/go/internal/core/compile/builtin.go @@ -15,9 +15,11 @@ package compile import ( + "strings" + "cuelang.org/go/cue/errors" - "cuelang.org/go/internal" "cuelang.org/go/internal/core/adt" + "cuelang.org/go/internal/iterutil" ) // This file contains predeclared builtins. @@ -25,26 +27,77 @@ import ( const supportedByLen = adt.StructKind | adt.BytesKind | adt.StringKind | adt.ListKind var ( + stringParam = adt.Param{Value: &adt.BasicType{K: adt.StringKind}} structParam = adt.Param{Value: &adt.BasicType{K: adt.StructKind}} listParam = adt.Param{Value: &adt.BasicType{K: adt.ListKind}} intParam = adt.Param{Value: &adt.BasicType{K: adt.IntKind}} topParam = adt.Param{Value: &adt.BasicType{K: adt.TopKind}} ) +// error is a special builtin that allows users to create a custom error +// message. If the argument is an interpolation, it will be evaluated and if it +// results in an error, the argument will be inserted as an expression. +var errorBuiltin = &adt.Builtin{ + Name: "error", + Added: "v0.14.0", + + Params: []adt.Param{stringParam}, + Result: adt.BottomKind, + RawFunc: func(call *adt.CallContext) adt.Value { + ctx := call.OpContext() + arg := call.Expr(0) + + var b *adt.Bottom + + switch x := arg.(type) { + case *adt.Interpolation: + var args []any + var w strings.Builder + for i := 0; i < len(x.Parts); i++ { + v := x.Parts[i] + w.WriteString(v.(*adt.String).Str) + if i++; i >= len(x.Parts) { + break + } + w.WriteString("%v") + y := call.OpContext().EvaluateKeepState(x.Parts[i]) + if err := ctx.Err(); err != nil { + args = append(args, x.Parts[i]) + } else if y.Concreteness() == adt.Concrete && + y.Kind()&adt.NumberKind|adt.StringKind|adt.BytesKind|adt.BoolKind != 0 { + args = append(args, ctx.ToString(y)) + } else { + args = append(args, y) + } + } + b = call.Errf(w.String(), args...) + default: + msg := ctx.ToString(call.Arg(0)) + b = call.Errf("%s", msg) + } + + _ = arg + b.Code = adt.UserError + return b + }, +} + var lenBuiltin = &adt.Builtin{ Name: "len", Params: []adt.Param{{Value: &adt.BasicType{K: supportedByLen}}}, Result: adt.IntKind, - Func: func(c *adt.OpContext, args []adt.Value) adt.Expr { + Func: func(call *adt.CallContext) adt.Expr { + c := call.OpContext() + args := call.Args() + v := args[0] if x, ok := v.(*adt.Vertex); ok { - x.LockArcs = true switch x.BaseValue.(type) { case nil: // This should not happen, but be defensive. return c.NewErrf("unevaluated vertex") case *adt.ListMarker: - return c.NewInt64(int64(len(x.Elems())), v) + return c.NewInt64(int64(iterutil.Count(x.Elems())), v) case *adt.StructMarker: n := 0 @@ -82,27 +135,88 @@ var closeBuiltin = &adt.Builtin{ Name: "close", Params: []adt.Param{structParam}, Result: adt.StructKind, - Func: func(c *adt.OpContext, args []adt.Value) adt.Expr { + Func: func(call *adt.CallContext) adt.Expr { + c := call.OpContext() + args := call.Args() + s, ok := args[0].(*adt.Vertex) if !ok { return c.NewErrf("struct argument must be concrete") } - var v *adt.Vertex - if c.Version == internal.DevVersion { - // TODO(evalv3) this is a rather convoluted and inefficient way to - // accomplish signaling vertex should be closed. In most cases, it - // would suffice to set IsClosed in the CloseInfo. However, that - // does not cover all code paths. Consider simplifying this. - v = c.Wrap(s, c.CloseInfo()) - v.ClosedNonRecursive = true - } else { - if m, ok := s.BaseValue.(*adt.StructMarker); ok && m.NeedClose { - return s + // TODO(evalv3) this is a rather convoluted and inefficient way to + // accomplish signaling vertex should be closed. In most cases, it + // would suffice to set IsClosed in the CloseInfo. However, that + // does not cover all code paths. Consider simplifying this. + v := c.Wrap(s, c.CloseInfo()) + v.ClosedNonRecursive = true + return v + }, +} + +var closeAllBuiltin = &adt.Builtin{ + Name: "__closeAll", + Params: []adt.Param{topParam}, + Result: adt.TopKind, + Func: func(call *adt.CallContext) adt.Expr { + c := call.OpContext() + + x := call.Expr(0) + switch x.(type) { + case *adt.StructLit, *adt.ListLit: + if src := x.Source(); src == nil || !src.Pos().Experiment().ExplicitOpen { + // Allow usage if explicit open is set + return c.NewErrf("__closeAll may only be used when explicitopen is enabled") } - v = s.Clone() - v.BaseValue = &adt.StructMarker{NeedClose: true} + default: + return c.NewErrf("argument must be a struct or list literal") } - return v + + // must be literal struct + args := call.Args() + + s, ok := args[0].(*adt.Vertex) + if !ok { + return c.NewErrf("struct argument must be concrete") + } + + s.ClosedRecursive = true + + return s + }, +} + +var recloseBuiltin = &adt.Builtin{ + Name: "__reclose", + Params: []adt.Param{topParam}, + Result: adt.TopKind, + Func: func(call *adt.CallContext) adt.Expr { + c := call.OpContext() + + x := call.Expr(0) + switch x.(type) { + case *adt.StructLit, *adt.ListLit: + if src := x.Source(); src == nil || !src.Pos().Experiment().ExplicitOpen { + // Allow usage if explicit open is set + return c.NewErrf("__reclose may only be used when explicitopen is enabled") + } + default: + return c.NewErrf("argument must be a struct or list literal") + } + + // must be literal struct + args := call.Args() + + // Note that we could have an embedded scalar here, so having a struct + // or list does not guarantee that the result is that as well. + // + // #Def: 1 + // a: __reclose({ #Def }) + // + if s, ok := args[0].(*adt.Vertex); ok && s.ShouldRecursivelyClose() { + s.ClosedRecursive = true + } + + return args[0] }, } @@ -110,17 +224,18 @@ var andBuiltin = &adt.Builtin{ Name: "and", Params: []adt.Param{listParam}, Result: adt.IntKind, - RawFunc: func(c *adt.OpContext, args []adt.Expr) adt.Value { - // Pass through the cycle information from evaluating the first argument. - v := c.EvaluateKeepState(args[0]) - list := c.RawElems(v) - if len(list) == 0 { - return &adt.Top{} - } + Func: func(call *adt.CallContext) adt.Expr { + c := call.OpContext() + args := call.Args() + + seq := c.RawElems(args[0]) a := []adt.Value{} - for _, c := range list { + for c := range seq { a = append(a, c) } + if len(a) == 0 { + return &adt.Top{} + } return &adt.Conjunction{Values: a} }, } @@ -130,9 +245,12 @@ var orBuiltin = &adt.Builtin{ Params: []adt.Param{listParam}, Result: adt.IntKind, NonConcrete: true, - Func: func(c *adt.OpContext, args []adt.Value) adt.Expr { + Func: func(call *adt.CallContext) adt.Expr { + c := call.OpContext() + args := call.Args() + d := []adt.Disjunct{} - for _, c := range c.RawElems(args[0]) { + for c := range c.RawElems(args[0]) { d = append(d, adt.Disjunct{Val: c, Default: false}) } if len(d) == 0 { @@ -165,7 +283,10 @@ var divBuiltin = &adt.Builtin{ Name: "div", Params: []adt.Param{intParam, intParam}, Result: adt.IntKind, - Func: func(c *adt.OpContext, args []adt.Value) adt.Expr { + Func: func(call *adt.CallContext) adt.Expr { + c := call.OpContext() + args := call.Args() + const name = "argument to div builtin" return intDivOp(c, (*adt.OpContext).IntDiv, name, args) @@ -176,7 +297,10 @@ var modBuiltin = &adt.Builtin{ Name: "mod", Params: []adt.Param{intParam, intParam}, Result: adt.IntKind, - Func: func(c *adt.OpContext, args []adt.Value) adt.Expr { + Func: func(call *adt.CallContext) adt.Expr { + c := call.OpContext() + args := call.Args() + const name = "argument to mod builtin" return intDivOp(c, (*adt.OpContext).IntMod, name, args) @@ -187,7 +311,10 @@ var quoBuiltin = &adt.Builtin{ Name: "quo", Params: []adt.Param{intParam, intParam}, Result: adt.IntKind, - Func: func(c *adt.OpContext, args []adt.Value) adt.Expr { + Func: func(call *adt.CallContext) adt.Expr { + c := call.OpContext() + args := call.Args() + const name = "argument to quo builtin" return intDivOp(c, (*adt.OpContext).IntQuo, name, args) @@ -198,7 +325,10 @@ var remBuiltin = &adt.Builtin{ Name: "rem", Params: []adt.Param{intParam, intParam}, Result: adt.IntKind, - Func: func(c *adt.OpContext, args []adt.Value) adt.Expr { + Func: func(call *adt.CallContext) adt.Expr { + c := call.OpContext() + args := call.Args() + const name = "argument to rem builtin" return intDivOp(c, (*adt.OpContext).IntRem, name, args) @@ -217,3 +347,18 @@ func intDivOp(c *adt.OpContext, fn intFunc, name string, args []adt.Value) adt.V return fn(c, a, b) } + +var testExperiment = &adt.Builtin{ + Name: "testExperiment", + Params: []adt.Param{topParam}, + Result: adt.TopKind, + Func: func(call *adt.CallContext) adt.Expr { + args := call.Args() + + if call.Pos().Experiment().Testing { + return args[0] + } else { + return call.OpContext().NewErrf("testing experiment disabled") + } + }, +} diff --git a/vendor/cuelang.org/go/internal/core/compile/compile.go b/vendor/cuelang.org/go/internal/core/compile/compile.go index ca5825616b..9d1c120f2d 100644 --- a/vendor/cuelang.org/go/internal/core/compile/compile.go +++ b/vendor/cuelang.org/go/internal/core/compile/compile.go @@ -24,6 +24,8 @@ import ( "cuelang.org/go/internal" "cuelang.org/go/internal/astinternal" "cuelang.org/go/internal/core/adt" + "cuelang.org/go/internal/cueexperiment" + "cuelang.org/go/internal/mod/semver" ) // A Scope represents a nested scope of Vertices. @@ -102,6 +104,8 @@ type compiler struct { index adt.StringIndexer + experiments cueexperiment.File + stack []frame inSelector int @@ -215,7 +219,8 @@ func (c *compiler) lookupAlias(k int, id *ast.Ident) aliasEntry { entry, ok := m[name] if !ok { - err := c.errf(id, "could not find LetClause associated with identifier %q", name) + err := c.errf(id, + "could not find let or alias associated with identifier %q", name) return aliasEntry{expr: err} } @@ -278,6 +283,7 @@ func (c *compiler) compileFiles(a []*ast.File) *adt.Vertex { // Or value? if f.PackageName() == "" { continue } + for _, d := range f.Decls { if f, ok := d.(*ast.Field); ok { if id, ok := f.Label.(*ast.Ident); ok { @@ -302,6 +308,8 @@ func (c *compiler) compileFiles(a []*ast.File) *adt.Vertex { // Or value? } for _, file := range a { + c.experiments = file.Pos().Experiment() + c.pushScope(nil, 0, file) // File scope v := &adt.StructLit{Src: file} c.addDecls(v, file.Decls) @@ -327,6 +335,53 @@ func (c *compiler) compileExpr(x ast.Expr) adt.Conjunct { return adt.MakeRootConjunct(env, expr) } +// verifyVersion checks whether n is a Builtin and then checks whether the +// Added version is compatible with the file version registered in c. +func (c *compiler) verifyVersion(src ast.Node, n adt.Expr) adt.Expr { + var kind, name, added string + switch x := n.(type) { + default: + return n + + case *adt.Builtin: + if x.Added == "" { + // No version check needed. + return n + } + + kind = "builtin" + name = x.Name + added = x.Added + + case *adt.ValueReference: + // NOTE: this is always self or __self. + kind = "predeclared identifier" + name = x.Src.Name + // Check if Self experiment is enabled + if !c.experiments.AliasV2 { + return c.errf(src, "%s %q requires @experiment(aliasv2)", kind, name) + } + x.Label = adt.MakeStringLabel(c.index, name) + return n + } + + v := c.experiments.LanguageVersion() + if v == "" { + // We assume "latest" if the file is not associated with a version. + return n + } + + if semver.Compare(added, v) <= 0 { + // The feature is available in the file version. + return n + } + + // The feature is not available in the file version. + // NonConcrete builtins are not allowed in older versions. + return c.errf(src, "%s %q is not available in version %v; "+ + "it was added in version %q", kind, name, v, added) +} + // resolve assumes that all existing resolutions are legal. Validation should // be done in a separate step if required. // @@ -390,7 +445,7 @@ func (c *compiler) resolve(n *ast.Ident) adt.Expr { } if p := predeclared(n); p != nil { - return p + return c.verifyVersion(n, p) } return c.errf(n, "reference %q not found", n.Name) @@ -415,9 +470,35 @@ func (c *compiler) resolve(n *ast.Ident) adt.Expr { UpCount: upCount, } - switch f := n.Node.(type) { + switch x := n.Node.(type) { + case *ast.Ident: + // If the identifier refers to a label alias, we link to that. + if f.Alias != nil && f.Alias.Label == x { + switch lab := f.Label.(type) { + case *ast.Ident: + if internal.IsDefOrHidden(lab.Name) { + return c.errf(x, "label alias cannot reference definition or hidden field") + } + return c.expr(ast.NewString(lab.Name)) + case *ast.BasicLit: + return c.expr(lab) + } + } case *ast.Field: - _ = c.lookupAlias(k, f.Label.(*ast.Alias).Ident) // mark as used + var ident *ast.Ident + if alias, _ := x.Label.(*ast.Alias); alias != nil { + if x.Alias != nil { + return c.errf(x, + "field has both label alias and postfix alias") + } + ident = alias.Ident + } else if x.Alias != nil { + ident = x.Alias.Field + } else { + return c.errf(x, "label reference has no alias") + } + + _ = c.lookupAlias(k, ident) // mark as used // The expression of field Label is always done in the same // Environment as pointed to by the UpCount of the DynamicReference // and the evaluation of a DynamicReference assumes this. @@ -430,11 +511,11 @@ func (c *compiler) resolve(n *ast.Ident) adt.Expr { } case *ast.Alias: - _ = c.lookupAlias(k, f.Ident) // mark as used + _ = c.lookupAlias(k, x.Ident) // mark as used return &adt.ValueReference{ Src: n, UpCount: upCount, - Label: c.label(f.Ident), + Label: c.label(x.Ident), } } return label @@ -484,26 +565,43 @@ func (c *compiler) resolve(n *ast.Ident) adt.Expr { X: entry.expr, // TODO: remove usage } - // TODO: handle new-style aliases - + // Handle new-style postfix aliases: a~X or a~(K,V) case *ast.Field: - // X=x: y - // X=(x): y - // X="\(x)": y - a, ok := f.Label.(*ast.Alias) - if !ok { + var ident *ast.Ident + lab := f.Label + // Old-style label aliases: X=x: y, X=(x): y, X="\(x)": + + if a, ok := f.Label.(*ast.Alias); ok { + ident = a.Ident + if f.Alias != nil { + return c.errf(f, "field has both label alias and postfix alias") + } + label, ok := a.Expr.(ast.Label) + if !ok { + return c.errf(a.Expr, "invalid label expression") + } + lab = label + } else if f.Alias != nil { + // Check if this identifier refers to the Field alias or Label alias + // The Field alias (X or V) is the value reference + // The Label alias (K) in dual form is a string reference + if f.Alias.Field == nil { + return c.errf(f, "postfix alias must have field component") + } + ident = f.Alias.Field + } else { return c.errf(n, "illegal reference %s", n.Name) } - aliasInfo := c.lookupAlias(k, a.Ident) // marks alias as used. - lab, ok := a.Expr.(ast.Label) - if !ok { - return c.errf(a.Expr, "invalid label expression") - } + + aliasInfo := c.lookupAlias(k, ident) // marks alias as used. + name, _, err := ast.LabelName(lab) switch { case errors.Is(err, ast.ErrIsExpression): if aliasInfo.expr == nil { - panic("unreachable") + // This can happen when we have a cyclic reference like (x)~x: 3 + // where the label expression references the alias being defined. + return c.errf(n, "cyclic reference in field alias") } return &adt.DynamicReference{ Src: n, @@ -543,6 +641,10 @@ func (c *compiler) addDecls(st *adt.StructLit, a []ast.Decl) { } } +func isNonBlank(a *ast.Ident) bool { + return a != nil && a.Name != "_" +} + func (c *compiler) markAlias(d ast.Decl) { switch x := d.(type) { case *ast.Field: @@ -557,6 +659,15 @@ func (c *compiler) markAlias(d ast.Decl) { c.insertAlias(a.Ident, e) } + // Register postfix aliases for regular fields (not pattern constraints) + // Pattern constraints register aliases in value scope only + // Regular field: register in parent scope + // Store the Field in the label so we can find it later + // Skip _ (blank identifier) + if a := x.Alias; a != nil && isNonBlank(a.Field) { + c.insertAlias(a.Field, aliasEntry{source: a}) + } + case *ast.LetClause: a := aliasEntry{ label: (*letScope)(x), @@ -586,6 +697,8 @@ func (c *compiler) decl(d ast.Decl) adt.Decl { v := x.Value var value adt.Expr + + // Handle value aliases. Deprecated in new aliases. if a, ok := v.(*ast.Alias); ok { c.pushScope(nil, 0, a) c.insertAlias(a.Ident, aliasEntry{source: a}) @@ -603,12 +716,10 @@ func (c *compiler) decl(d ast.Decl) adt.Decl { return c.errf(x, "cannot use _ as label") } - t, _ := internal.ConstraintToken(x) - return &adt.Field{ Src: x, Label: label, - ArcType: adt.ConstraintFromToken(t), + ArcType: adt.ConstraintFromToken(x.Constraint), Value: value, } @@ -626,6 +737,12 @@ func (c *compiler) decl(d ast.Decl) adt.Decl { elem = a.Expr } + // For postfix aliases, use the Field identifier (X or V) + // For dual form ~(K,V), we use V as the primary label + if a := x.Alias; a != nil && isNonBlank(a.Label) { + label = c.label(a.Label) + } + return &adt.BulkOptionalField{ Src: x, Filter: c.expr(elem), @@ -634,22 +751,18 @@ func (c *compiler) decl(d ast.Decl) adt.Decl { } case *ast.ParenExpr: - t, _ := internal.ConstraintToken(x) - return &adt.DynamicField{ Src: x, Key: c.expr(l), - ArcType: adt.ConstraintFromToken(t), + ArcType: adt.ConstraintFromToken(x.Constraint), Value: value, } case *ast.Interpolation: - t, _ := internal.ConstraintToken(x) - return &adt.DynamicField{ Src: x, Key: c.expr(l), - ArcType: adt.ConstraintFromToken(t), + ArcType: adt.ConstraintFromToken(x.Constraint), Value: value, } } @@ -679,8 +792,6 @@ func (c *compiler) decl(d ast.Decl) adt.Decl { Value: value, } - // case: *ast.Alias: // TODO(value alias) - case *ast.CommentGroup: // Nothing to do for a free-floating comment group. @@ -713,19 +824,31 @@ func (c *compiler) addLetDecl(d ast.Decl) { switch x := d.(type) { case *ast.Field: lab := x.Label + var ident *ast.Ident if a, ok := lab.(*ast.Alias); ok { + if x.Alias != nil { + c.errf(x, "field has both label alias and postfix alias") + return + } + if lab, ok = a.Expr.(ast.Label); !ok { // error reported elsewhere return } + ident = a.Ident - switch lab.(type) { - case *ast.Ident, *ast.BasicLit, *ast.ListLit: - // Even though we won't need the alias, we still register it - // for duplicate and failed reference detection. - default: - c.updateAlias(a.Ident, c.expr(a.Expr)) - } + } else if a := x.Alias; a != nil && isNonBlank(a.Field) { + ident = x.Alias.Field + } else { + break + } + + switch lab.(type) { + case *ast.Ident, *ast.BasicLit, *ast.ListLit: + // Even though we won't need the alias, we still register it + // for duplicate and failed reference detection. + default: + c.updateAlias(ident, c.expr(lab.(ast.Expr))) } case *ast.Alias: @@ -835,12 +958,21 @@ func (c *compiler) labeledExpr(f ast.Decl, lab labeler, expr ast.Expr) adt.Expr func (c *compiler) labeledExprAt(k int, f ast.Decl, lab labeler, expr ast.Expr) adt.Expr { saved := c.stack[k] + savedStack := c.stack c.stack[k].label = lab c.stack[k].field = f + if k < len(c.stack)-1 { + // Limit the capacity, so that if there is growth, we don't overwrite + // any values we need to restore later. This shouldn't happen too often, + // as this will result in a non-reclaimable allocation. + c.stack = c.stack[: k+1 : k+1] + } + value := c.expr(expr) + c.stack = savedStack c.stack[k] = saved return value } @@ -872,7 +1004,7 @@ func (c *compiler) expr(expr ast.Expr) adt.Expr { case *ast.ListLit: c.pushScope(nil, 1, n) v := &adt.ListLit{Src: n} - elts, ellipsis := internal.ListEllipsis(n) + elts, ellipsis := listEllipsis(n) for _, d := range elts { elem := c.elem(d) @@ -896,9 +1028,14 @@ func (c *compiler) expr(expr ast.Expr) adt.Expr { case *ast.SelectorExpr: c.inSelector++ + x := c.expr(n.X) + // TODO: check if x is an ImportReference, and if so, check if it a + // standard library, look up the builtin, and check its version. The + // index of standard libraries is available in c.index, which is really + // an adt.Runtime under the hood. ret := &adt.SelectorExpr{ Src: n, - X: c.expr(n.X), + X: x, Sel: c.label(n.Sel)} c.inSelector-- return ret @@ -923,7 +1060,7 @@ func (c *compiler) expr(expr ast.Expr) adt.Expr { case *ast.BottomLit: return &adt.Bottom{ Src: n, - Code: adt.UserError, + Code: adt.LegacyUserError, Err: errors.Newf(n.Pos(), "explicit error (_|_ literal) in source"), } @@ -994,6 +1131,11 @@ func (c *compiler) expr(expr ast.Expr) adt.Expr { Op: adt.OpFromToken(n.Op), X: c.expr(n.X), } + case token.EQL: + if !c.experiments.StructCmp { + return c.errf(n, "unsupported unary operator %q", n.Op) + } + fallthrough case token.GEQ, token.GTR, token.LSS, token.LEQ, token.NEQ, token.MAT, token.NMAT: return &adt.BoundExpr{ @@ -1028,17 +1170,44 @@ func (c *compiler) expr(expr ast.Expr) adt.Expr { return &adt.BinaryExpr{Src: n, Op: op, X: x, Y: y} // ) } + case *ast.PostfixExpr: + switch n.Op { + case token.ELLIPSIS: + if c.experiments.ExplicitOpen { + return &adt.OpenExpr{ + Src: n, + X: c.expr(n.X), + } + } + return c.errf(n, "postfix ... operator requires @experiment(explicitopen)") + default: + return c.errf(n, "unsupported postfix operator %s", n.Op) + } + default: return c.errf(n, "%s values not allowed in this position", ast.Name(n)) } } -func (c *compiler) assertConcreteIsPossible(src ast.Node, op adt.Op, x adt.Expr) bool { +// listEllipsis reports the list type and remaining elements of a list. If we +// ever relax the usage of ellipsis, this function will likely change. Using +// this function will ensure keeping correct behavior or causing a compiler failure. +func listEllipsis(n *ast.ListLit) (elts []ast.Expr, e *ast.Ellipsis) { + elts = n.Elts + if n := len(elts); n > 0 { + var ok bool + if e, ok = elts[n-1].(*ast.Ellipsis); ok { + elts = elts[:n-1] + } + } + return elts, e +} + +func (c *compiler) assertConcreteIsPossible(src ast.Node, op adt.Op, x adt.Expr) { if !adt.AssertConcreteIsPossible(op, x) { str := astinternal.DebugStr(src) c.errf(src, "invalid operand %s ('%s' requires concrete value)", str, op) } - return false } func (c *compiler) addDisjunctionElem(d *adt.DisjunctionExpr, n ast.Expr, mark bool) { diff --git a/vendor/cuelang.org/go/internal/core/compile/label.go b/vendor/cuelang.org/go/internal/core/compile/label.go index 24bed7d4be..a97230db2b 100644 --- a/vendor/cuelang.org/go/internal/core/compile/label.go +++ b/vendor/cuelang.org/go/internal/core/compile/label.go @@ -44,7 +44,7 @@ func (c *compiler) label(n ast.Node) adt.Feature { return adt.InvalidLabel } - i := int64(index.StringToIndex(norm.NFC.String(s))) + i := index.StringToIndex(norm.NFC.String(s)) f, err := adt.MakeLabel(n, i, adt.StringLabel) if err != nil { c.errf(n, msg, err) @@ -119,7 +119,7 @@ func (l *fieldLabel) labelString() string { case *ast.BasicLit: if x.Kind == token.STRING { s, err := literal.Unquote(x.Value) - if err == nil && ast.IsValidIdent(s) { + if err == nil && !ast.StringLabelNeedsQuoting(s) { return s } } diff --git a/vendor/cuelang.org/go/internal/core/compile/predeclared.go b/vendor/cuelang.org/go/internal/core/compile/predeclared.go index ec2fceb347..eaff9daf7c 100644 --- a/vendor/cuelang.org/go/internal/core/compile/predeclared.go +++ b/vendor/cuelang.org/go/internal/core/compile/predeclared.go @@ -40,10 +40,16 @@ func predeclared(n *ast.Ident) adt.Expr { case "number", "__number": return &adt.BasicType{Src: n, K: adt.NumberKind} + case "error", "__error": + return errorBuiltin case "len", "__len": return lenBuiltin case "close", "__close": return closeBuiltin + case "__closeAll": + return closeAllBuiltin + case "__reclose": + return recloseBuiltin case "matchIf", "__matchIf": return matchIfBuiltin case "matchN", "__matchN": @@ -61,8 +67,15 @@ func predeclared(n *ast.Ident) adt.Expr { case "rem", "__rem": return remBuiltin + case "self", "__self": + // UpCount of 1 gets resolved to relNode(1) + return &adt.ValueReference{Src: n, UpCount: 1} + case "__no_sharing": return adt.NoShareSentinel + + case "__test_experiment": + return testExperiment } if r, ok := predefinedRanges[n.Name]; ok { diff --git a/vendor/cuelang.org/go/internal/core/compile/validator.go b/vendor/cuelang.org/go/internal/core/compile/validator.go index de3633e7d0..f417623fce 100644 --- a/vendor/cuelang.org/go/internal/core/compile/validator.go +++ b/vendor/cuelang.org/go/internal/core/compile/validator.go @@ -18,7 +18,6 @@ package compile import ( "cuelang.org/go/internal/core/adt" - "cuelang.org/go/internal/core/validate" ) // matchN is a validator that checks that the number of schemas in the given @@ -30,7 +29,10 @@ var matchNBuiltin = &adt.Builtin{ Params: []adt.Param{topParam, intParam, listParam}, // varargs Result: adt.BoolKind, NonConcrete: true, - Func: func(c *adt.OpContext, args []adt.Value) adt.Expr { + Func: func(call *adt.CallContext) adt.Expr { + c := call.OpContext() + args := call.Args() + if !c.IsValidator { return c.NewErrf("matchN is a validator and should not be used as a function") } @@ -40,16 +42,16 @@ var matchNBuiltin = &adt.Builtin{ return &adt.Bool{B: false} } - constraints := c.Elems(args[2]) - + var errs []*adt.Bottom var count, possibleCount int64 - for _, check := range constraints { - v := unifyValidator(c, self, check) - if err := validate.Validate(c, v, finalCfg); err == nil { + for check := range c.Elems(args[2]) { + v := adt.Unify(c, self, check) + if err := adt.Validate(c, v, finalCfg); err == nil { // TODO: is it always true that the lack of an error signifies // success? count++ } else { + errs = append(errs, err) if err.IsIncomplete() { possibleCount++ } @@ -62,6 +64,14 @@ var matchNBuiltin = &adt.Builtin{ b := checkNum(c, bound, count, count+possibleCount) if b != nil { + // Only show errors related to incomplete schema if there is still + // a possibility that we can resolve it. + isIncomplete := b.IsIncomplete() + for _, err := range errs { + if !isIncomplete || err.IsIncomplete() { + c.AddBottom(err) + } + } return b } return &adt.Bool{B: true} @@ -78,7 +88,10 @@ var matchIfBuiltin = &adt.Builtin{ Params: []adt.Param{topParam, topParam, topParam, topParam}, Result: adt.BoolKind, NonConcrete: true, - Func: func(c *adt.OpContext, args []adt.Value) adt.Expr { + Func: func(call *adt.CallContext) adt.Expr { + c := call.OpContext() + args := call.Args() + if !c.IsValidator { return c.NewErrf("matchIf is a validator and should not be used as a function") } @@ -88,15 +101,15 @@ var matchIfBuiltin = &adt.Builtin{ return &adt.Bool{B: false} } ifSchema, thenSchema, elseSchema := args[1], args[2], args[3] - v := unifyValidator(c, self, ifSchema) + v := adt.Unify(c, self, ifSchema) var chosenSchema adt.Value - if err := validate.Validate(c, v, finalCfg); err == nil { + if err := adt.Validate(c, v, finalCfg); err == nil { chosenSchema = thenSchema } else { chosenSchema = elseSchema } - v = unifyValidator(c, self, chosenSchema) - err := validate.Validate(c, v, finalCfg) + v = adt.Unify(c, self, chosenSchema) + err := adt.Validate(c, v, finalCfg) if err == nil { return &adt.Bool{B: true} } @@ -106,7 +119,8 @@ var matchIfBuiltin = &adt.Builtin{ }, } -var finalCfg = &validate.Config{Final: true} +// Explicitly disallow incomplete errors. +var finalCfg = &adt.ValidateConfig{ReportIncomplete: true, Final: true} // finalizeSelf ensures a value is fully evaluated and then strips it of any // of its validators or default values. @@ -117,7 +131,8 @@ func finalizeSelf(c *adt.OpContext, self adt.Value) adt.Value { return self } -func unifyValidator(c *adt.OpContext, self, check adt.Value) *adt.Vertex { +// TODO: use adt.Unify instead. +func unifyScalar(c *adt.OpContext, self, check adt.Value) *adt.Vertex { v := &adt.Vertex{} closeInfo := c.CloseInfo() v.AddConjunct(adt.MakeConjunct(nil, self, closeInfo)) @@ -128,7 +143,7 @@ func unifyValidator(c *adt.OpContext, self, check adt.Value) *adt.Vertex { func checkNum(ctx *adt.OpContext, bound adt.Value, count, maxCount int64) *adt.Bottom { cnt := ctx.NewInt64(count) - n := unifyValidator(ctx, bound, cnt) + n := unifyScalar(ctx, bound, cnt) b, _ := n.BaseValue.(*adt.Bottom) if b != nil { b := ctx.NewErrf("%d matched, expected %v", count, bound) diff --git a/vendor/cuelang.org/go/internal/core/convert/go.go b/vendor/cuelang.org/go/internal/core/convert/go.go index da4a754ee4..366dee1a76 100644 --- a/vendor/cuelang.org/go/internal/core/convert/go.go +++ b/vendor/cuelang.org/go/internal/core/convert/go.go @@ -151,7 +151,7 @@ func getName(f *reflect.StructField) string { func isOptional(f *reflect.StructField) bool { isOptional := false switch f.Type.Kind() { - case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Interface, reflect.Slice: + case reflect.Pointer, reflect.Map, reflect.Chan, reflect.Interface, reflect.Slice: // Note: it may be confusing to distinguish between an empty slice and // a nil slice. However, it is also surprising to not be able to specify // a default value for a slice. So for now we will allow it. @@ -161,7 +161,7 @@ func isOptional(f *reflect.StructField) bool { // TODO: only if first field is not empty. _, opt := splitTag(tag) isOptional = false - for _, f := range strings.Split(opt, ",") { + for f := range strings.SplitSeq(opt, ",") { switch f { case "opt": isOptional = true @@ -171,10 +171,8 @@ func isOptional(f *reflect.StructField) bool { } } else if tag, ok = f.Tag.Lookup("json"); ok { isOptional = false - for _, f := range strings.Split(tag, ",")[1:] { - if f == "omitempty" { - return true - } + if slices.Contains(strings.Split(tag, ",")[1:], "omitempty") { + return true } } return isOptional @@ -184,7 +182,7 @@ func isOptional(f *reflect.StructField) bool { func isOmitEmpty(f *reflect.StructField) bool { isOmitEmpty := false switch f.Type.Kind() { - case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Interface, reflect.Slice: + case reflect.Pointer, reflect.Map, reflect.Chan, reflect.Interface, reflect.Slice: // Note: it may be confusing to distinguish between an empty slice and // a nil slice. However, it is also surprising to not be able to specify // a default value for a slice. So for now we will allow it. @@ -197,10 +195,8 @@ func isOmitEmpty(f *reflect.StructField) bool { tag, ok := f.Tag.Lookup("json") if ok { isOmitEmpty = false - for _, f := range strings.Split(tag, ",")[1:] { - if f == "omitempty" { - return true - } + if slices.Contains(strings.Split(tag, ",")[1:], "omitempty") { + return true } } return isOmitEmpty @@ -217,7 +213,7 @@ func GoValueToExpr(ctx *adt.OpContext, nilIsTop bool, x interface{}) adt.Expr { func isNil(x reflect.Value) bool { switch x.Kind() { // Only check for supported types; ignore func and chan. - case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Interface: + case reflect.Pointer, reflect.Map, reflect.Slice, reflect.Interface: return x.IsNil() } return false @@ -344,7 +340,7 @@ func (c *goConverter) convertRec(nilIsTop bool, x interface{}) (result adt.Value case int32: return c.toInt(int64(v)) case int64: - return c.toInt(int64(v)) + return c.toInt(v) case uint: return c.toUint(uint64(v)) case uint8: @@ -354,7 +350,7 @@ func (c *goConverter) convertRec(nilIsTop bool, x interface{}) (result adt.Value case uint32: return c.toUint(uint64(v)) case uint64: - return c.toUint(uint64(v)) + return c.toUint(v) case uintptr: return c.toUint(uint64(v)) case float64: @@ -404,7 +400,7 @@ func (c *goConverter) convertRec(nilIsTop bool, x interface{}) (result adt.Value case reflect.Float32, reflect.Float64: return c.convertRec(nilIsTop, value.Float()) - case reflect.Ptr: + case reflect.Pointer: if value.IsNil() { if nilIsTop { ident, _ := src.(*ast.Ident) @@ -416,10 +412,11 @@ func (c *goConverter) convertRec(nilIsTop bool, x interface{}) (result adt.Value case reflect.Struct: sl := &adt.StructLit{Src: c.setNextPos(ast.NewStruct())} + sl.Init(c.ctx) v := &adt.Vertex{} t := value.Type() - for i := 0; i < value.NumField(); i++ { + for i := range value.NumField() { sf := t.Field(i) if sf.PkgPath != "" { continue @@ -476,6 +473,7 @@ func (c *goConverter) convertRec(nilIsTop bool, x interface{}) (result adt.Value case reflect.Map: obj := &adt.StructLit{Src: c.setNextPos(ast.NewStruct())} + obj.Init(c.ctx) v := &adt.Vertex{} t := value.Type() @@ -491,10 +489,7 @@ func (c *goConverter) convertRec(nilIsTop bool, x interface{}) (result adt.Value reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - iter := value.MapRange() - for iter.Next() { - k := iter.Key() - val := iter.Value() + for k, val := range value.Seq2() { // if isNil(val) { // continue // } @@ -538,8 +533,8 @@ func (c *goConverter) convertRec(nilIsTop bool, x interface{}) (result adt.Value v := &adt.Vertex{} - for i := 0; i < value.Len(); i++ { - val := value.Index(i) + i := 0 + for _, val := range value.Seq2() { x := c.convertRec(nilIsTop, val.Interface()) if x == nil { return c.ctx.AddErrf("unsupported Go type (%T)", @@ -551,6 +546,7 @@ func (c *goConverter) convertRec(nilIsTop bool, x interface{}) (result adt.Value list.Elems = append(list.Elems, x) f := adt.MakeIntLabel(adt.IntLabel, int64(i)) v.Arcs = append(v.Arcs, c.ensureArcVertex(x, f)) + i++ } env := c.ctx.Env(0) @@ -670,9 +666,9 @@ func (c *goConverter) goTypeToValueRec(allowNullDefault bool, t reflect.Type) (e } switch k := t.Kind(); k { - case reflect.Ptr: + case reflect.Pointer: elem := t.Elem() - for elem.Kind() == reflect.Ptr { + for elem.Kind() == reflect.Pointer { elem = elem.Elem() } e, _ = c.goTypeToValueRec(false, elem) @@ -716,7 +712,7 @@ func (c *goConverter) goTypeToValueRec(allowNullDefault bool, t reflect.Type) (e // references. Maybe have a special kind of "hardlink" reference. c.ctx.StoreType(t, obj, nil) - for i := 0; i < t.NumField(); i++ { + for i := range t.NumField() { f := t.Field(i) if f.PkgPath != "" { continue diff --git a/vendor/cuelang.org/go/internal/core/debug/compact.go b/vendor/cuelang.org/go/internal/core/debug/compact.go index 5450cf93cf..b40cb3f90f 100644 --- a/vendor/cuelang.org/go/internal/core/debug/compact.go +++ b/vendor/cuelang.org/go/internal/core/debug/compact.go @@ -27,32 +27,28 @@ import ( "cuelang.org/go/internal/core/adt" ) -type compactPrinter struct { - printer -} - -func (w *compactPrinter) string(s string) { - w.dst = append(w.dst, s...) -} - -func (w *compactPrinter) node(n adt.Node) { +func (w *printer) compactNode(n adt.Node) { switch x := n.(type) { case *adt.Vertex: if x.BaseValue == nil || (w.cfg.Raw && !x.IsData()) { i := 0 - x.VisitLeafConjuncts(func(c adt.Conjunct) bool { + for c := range x.LeafConjuncts() { if i > 0 { w.string(" & ") } i++ w.node(c.Elem()) - return true - }) + } return } switch v := x.BaseValue.(type) { case *adt.StructMarker: + if !w.pushVertex(x) { + return + } + defer w.popVertex() + w.string("{") for i, a := range x.Arcs { if i > 0 { @@ -80,6 +76,11 @@ func (w *compactPrinter) node(n adt.Node) { w.string("}") case *adt.ListMarker: + if !w.pushVertex(x) { + return + } + defer w.popVertex() + w.string("[") for i, a := range x.Arcs { if i > 0 { @@ -90,6 +91,8 @@ func (w *compactPrinter) node(n adt.Node) { w.string("]") case *adt.Vertex: + // Disjunction, structure shared, etc. + if v, ok := w.printShared(x); !ok { w.node(v) w.popVertex() @@ -162,7 +165,7 @@ func (w *compactPrinter) node(n adt.Node) { w.string(`_|_`) if x.Err != nil { w.string("(") - w.string(x.Err.Error()) + w.shortError(x.Err, false) w.string(")") } @@ -270,6 +273,10 @@ func (w *compactPrinter) node(n adt.Node) { w.node(x.Y) w.string(")") + case *adt.OpenExpr: + w.node(x.X) + w.string("...") + case *adt.CallExpr: w.node(x.Fun) w.string("(") @@ -277,7 +284,7 @@ func (w *compactPrinter) node(n adt.Node) { if i > 0 { w.string(", ") } - w.node(a) + w.arg(a) } w.string(")") @@ -295,7 +302,7 @@ func (w *compactPrinter) node(n adt.Node) { if i > 0 { w.string(", ") } - w.node(a) + w.arg(a) } w.string(")") diff --git a/vendor/cuelang.org/go/internal/core/debug/debug.go b/vendor/cuelang.org/go/internal/core/debug/debug.go index e6431bd57e..1c7a44e5b2 100644 --- a/vendor/cuelang.org/go/internal/core/debug/debug.go +++ b/vendor/cuelang.org/go/internal/core/debug/debug.go @@ -21,6 +21,7 @@ package debug import ( "fmt" + "slices" "strconv" "strings" @@ -38,6 +39,11 @@ type Config struct { Cwd string Compact bool Raw bool + + // ExpandLetExpr causes the expression of let reference to be printed. + // Note that this may result in large outputs. Use with care. + // Only applies if Compact is false. + ExpandLetExpr bool } // AppendNode writes a string representation of the node to w. @@ -45,12 +51,7 @@ func AppendNode(dst []byte, i adt.StringIndexer, n adt.Node, config *Config) []b if config == nil { config = &Config{} } - p := printer{dst: dst, index: i, cfg: config} - if config.Compact { - p := compactPrinter{p} - p.node(n) - return p.dst - } + p := printer{dst: dst, index: i, cfg: config, compact: config.Compact} p.node(n) return p.dst } @@ -65,10 +66,11 @@ func NodeString(i adt.StringIndexer, n adt.Node, config *Config) string { } type printer struct { - dst []byte - index adt.StringIndexer - indent string - cfg *Config + dst []byte + index adt.StringIndexer + indent string + cfg *Config + compact bool // copied from config.Compact // keep track of vertices to avoid cycles. stack []*adt.Vertex @@ -80,8 +82,51 @@ type printer struct { // - auto } +// ReplaceArg implements the format.Printer interface. It wraps Vertex arguments +// with a formatter value, that holds a pointer to w. This allows the stack +// of processed vertices to be passed down, which in turn is used for cycle +// detection. +func (w *printer) ReplaceArg(arg any) (replacement any, replaced bool) { + var x adt.Node + var r adt.Runtime + switch v := arg.(type) { + case adt.Node: + x = v + case adt.Formatter: + x = v.X + r = v.R + } + + switch x := x.(type) { + default: + return arg, false + case *adt.Vertex: + // We replace the formatter (or node) with our own formatter that is + // capable of detecting cycles. + return formatter{p: w, x: x, r: r}, true + } +} + +type formatter struct { + p *printer + x adt.Node + r adt.Runtime `` +} + +func (f formatter) String() string { + p := printer{ + dst: make([]byte, 0, 128), + index: f.r, + cfg: f.p.cfg, + compact: true, // Always compact for error arguments. + stack: f.p.stack, + } + p.node(f.x) + return string(p.dst) +} + func (w *printer) string(s string) { - if len(w.indent) > 0 { + if !w.compact && len(w.indent) > 0 { s = strings.Replace(s, "\n", "\n"+w.indent, -1) } w.dst = append(w.dst, s...) @@ -132,19 +177,15 @@ func (w *printer) shared(v *adt.Vertex) { // of v, if it is a shared node. It reports the dereferenced node and whether // the node was printed. func (w *printer) printShared(v0 *adt.Vertex) (x *adt.Vertex, ok bool) { - // Handle cyclic shared nodes differently. If a shared node was part of // a disjunction, it will still be wrapped in a disjunct Vertex. // Similarly, a shared node should never point to a disjunct directly, // but rather to the original arc that subsequently points to a // disjunct. v0 = v0.DerefDisjunct() - isCyclic := v0.IsCyclic s, ok := v0.BaseValue.(*adt.Vertex) v1 := v0.DerefValue() - useReference := v0.IsShared && v1.Rooted() - isCyclic = isCyclic || v1.IsCyclic - _ = isCyclic + useReference := v0.IsShared && !v1.Internal() // NOTE(debug): use this line instead of the following to expand shared // cases where it is safe to do so. // if useReference && isCyclic && ok && len(v.Arcs) > 0 { @@ -164,11 +205,11 @@ func (w *printer) printShared(v0 *adt.Vertex) (x *adt.Vertex, ok bool) { } func (w *printer) pushVertex(v *adt.Vertex) bool { - for _, x := range w.stack { - if x == v { - w.string("") - return false - } + if slices.Contains(w.stack, v) { + w.string("value at path '") + w.path(v) + w.string("'") + return false } w.stack = append(w.stack, v) return true @@ -178,21 +219,15 @@ func (w *printer) popVertex() { w.stack = w.stack[:len(w.stack)-1] } -func (w *printer) shortError(errs errors.Error) { - for { - msg, args := errs.Msg() - w.dst = fmt.Appendf(w.dst, msg, args...) - - err := errors.Unwrap(errs) - if err == nil { - break - } - - if errs, _ = err.(errors.Error); errs != nil { - w.string(err.Error()) - break - } - } +// TODO: always print path? We allow a choice for keeping the error diff at a +// minimum. +func (w *printer) shortError(errs errors.Error, omitPath bool) { + w.string(errors.StringWithConfig(errs, &errors.Config{ + Cwd: w.cfg.Cwd, + ToSlash: true, + OmitPath: omitPath, + Printer: w, + })) } func (w *printer) interpolation(x *adt.Interpolation) { @@ -225,7 +260,21 @@ func (w *printer) interpolation(x *adt.Interpolation) { w.string(quote) } +func (w *printer) arg(n adt.Node) { + if x, ok := n.(*adt.Vertex); ok { + if x.Label != adt.InvalidLabel { + w.path(x) + return + } + } + w.node(n) +} + func (w *printer) node(n adt.Node) { + if w.compact { + w.compactNode(n) + return + } switch x := n.(type) { case *adt.Vertex: x, ok := w.printShared(x) @@ -262,10 +311,11 @@ func (w *printer) node(n adt.Node) { w.indent += "// " w.string("\n") w.dst = fmt.Appendf(w.dst, "[%v]", v.Code) - if !v.ChildError { + if !v.ChildError || len(x.Arcs) == 0 { msg := errors.Details(v.Err, &errors.Config{ Cwd: w.cfg.Cwd, ToSlash: true, + Printer: w, }) msg = strings.TrimSpace(msg) if msg != "" { @@ -427,7 +477,7 @@ func (w *printer) node(n adt.Node) { w.string(`_|_`) if x.Err != nil { w.string("(") - w.shortError(x.Err) + w.shortError(x.Err, true) w.string(")") } @@ -507,6 +557,10 @@ func (w *printer) node(n adt.Node) { w.string(";let ") w.label(x.Label) w.string(closeTuple) + if w.cfg.ExpandLetExpr { + w.string("=>") + w.node(x.X) + } case *adt.SelectorExpr: w.node(x.X) @@ -551,6 +605,10 @@ func (w *printer) node(n adt.Node) { w.node(x.Y) w.string(")") + case *adt.OpenExpr: + w.node(x.X) + w.string("...") + case *adt.CallExpr: w.node(x.Fun) w.string("(") @@ -558,7 +616,7 @@ func (w *printer) node(n adt.Node) { if i > 0 { w.string(", ") } - w.node(a) + w.arg(a) } w.string(")") @@ -576,7 +634,7 @@ func (w *printer) node(n adt.Node) { if i > 0 { w.string(", ") } - w.node(a) + w.arg(a) } w.string(")") diff --git a/vendor/cuelang.org/go/internal/core/dep/dep.go b/vendor/cuelang.org/go/internal/core/dep/dep.go index 97bd94a127..c896fc7924 100644 --- a/vendor/cuelang.org/go/internal/core/dep/dep.go +++ b/vendor/cuelang.org/go/internal/core/dep/dep.go @@ -17,7 +17,6 @@ package dep import ( "cuelang.org/go/cue/errors" - "cuelang.org/go/internal" "cuelang.org/go/internal/core/adt" ) @@ -197,6 +196,7 @@ func Visit(cfg *Config, c *adt.OpContext, n *adt.Vertex, f VisitFunc) error { all: cfg.Descend, top: true, cfgDynamic: cfg.Dynamic, + resolved: map[refEntry]bool{}, } return v.visitReusingVisitor(n, true) } @@ -236,10 +236,9 @@ func (v *visitor) visit(n *adt.Vertex, top bool) (err error) { } }() - n.VisitLeafConjuncts(func(x adt.Conjunct) bool { + for x := range n.LeafConjuncts() { v.markExpr(x.Env, x.Elem()) - return true - }) + } return nil } @@ -269,6 +268,9 @@ type visitor struct { cfgDynamic bool marked marked + + // resolved dedups resolving references to prevent exponential blowup. + resolved map[refEntry]bool } type refEntry struct { @@ -299,6 +301,9 @@ func (c *visitor) markExpr(env *adt.Environment, expr adt.Elem) { case *adt.UnaryExpr: c.markExpr(env, x.X) + case *adt.OpenExpr: + c.markExpr(env, x.X) + case *adt.Interpolation: for i := 1; i < len(x.Parts); i += 2 { c.markExpr(env, x.Parts[i]) @@ -357,10 +362,18 @@ func (c *visitor) markExpr(env *adt.Environment, expr adt.Elem) { // markResolve resolves dependencies. func (c *visitor) markResolver(env *adt.Environment, r adt.Resolver) { + if c.resolved[refEntry{env, r}] { + // TODO: this seems to still not remove everything. Consider a + // different approach. + return + } + // Note: it is okay to pass an empty CloseInfo{} here as we assume that // all nodes are finalized already and we need neither closedness nor cycle // checks. ref, _ := c.ctxt.Resolve(adt.MakeConjunct(env, r, adt.CloseInfo{}), r) + c.resolved[refEntry{env, r}] = true + c.ctxt.Stats().ResolveDep++ // TODO: consider the case where an inlined composite literal does not // resolve, but has references. For instance, {a: k, ref}.b would result @@ -414,13 +427,7 @@ func (c *visitor) reportDependency(env *adt.Environment, ref adt.Resolver, v *ad reference = c.topRef } - inspect := false - - if c.ctxt.Version == internal.DevVersion { - inspect = v.IsDetached() || !v.MayAttach() - } else { - inspect = !v.Rooted() - } + inspect := v.IsDetached() || !v.MayAttach() if inspect { // TODO: there is currently no way to inspect where a non-rooted node @@ -489,9 +496,8 @@ func (c *visitor) reportDependency(env *adt.Environment, ref adt.Resolver, v *ad c.numRefs++ - if c.ctxt.Version == internal.DevVersion { - v.Finalize(c.ctxt) - } + // Note: we did not finalize in V2. + v.Unify(c.ctxt, adt.FinalizeWithoutTypoCheck) d := Dependency{ Node: v, @@ -539,12 +545,11 @@ func hasLetParent(v *adt.Vertex) bool { // markConjuncts transitively marks all reference of the current node. func (c *visitor) markConjuncts(v *adt.Vertex) { - v.VisitLeafConjuncts(func(x adt.Conjunct) bool { + for x := range v.LeafConjuncts() { // Use Elem instead of Expr to preserve the Comprehension to, in turn, // ensure an Environment is inserted for the Value clause. c.markExpr(x.Env, x.Elem()) - return true - }) + } } // markInternalResolvers marks dependencies for rootless nodes. As these @@ -552,19 +557,14 @@ func (c *visitor) markConjuncts(v *adt.Vertex) { // proactive. For selectors and indices this means we need to evaluate their // objects to see exactly what the selector or index refers to. func (c *visitor) markInternalResolvers(env *adt.Environment, r adt.Resolver, v *adt.Vertex) { - if v.Rooted() { - panic("node must not be rooted") - } - saved := c.all // recursive traversal already done by this function. // As lets have no path and we otherwise will not process them, we set // processing all to true. if c.marked != nil && hasLetParent(v) { - v.VisitLeafConjuncts(func(x adt.Conjunct) bool { + for x := range v.LeafConjuncts() { c.marked.markExpr(x.Expr()) - return true - }) + } } c.markConjuncts(v) @@ -594,7 +594,7 @@ func (c *visitor) evaluateInner(env *adt.Environment, x adt.Expr, r adt.Resolver return } // TODO(perf): one level of evaluation would suffice. - v.Finalize(c.ctxt) + v.Unify(c.ctxt, adt.FinalizeWithoutTypoCheck) saved := len(c.pathStack) c.pathStack = append(c.pathStack, refEntry{env, r}) diff --git a/vendor/cuelang.org/go/internal/core/dep/mixed.go b/vendor/cuelang.org/go/internal/core/dep/mixed.go index 5ae089a928..277c2ece61 100644 --- a/vendor/cuelang.org/go/internal/core/dep/mixed.go +++ b/vendor/cuelang.org/go/internal/core/dep/mixed.go @@ -31,13 +31,12 @@ func (v *visitor) dynamic(n *adt.Vertex, top bool) { found := false // TODO: Consider if we should only visit the conjuncts of the disjunction // for dynamic mode. - n.VisitLeafConjuncts(func(c adt.Conjunct) bool { + for c := range n.LeafConjuncts() { if v.marked[c.Expr()] { found = true - return false + break } - return true - }) + } if !found { return @@ -70,10 +69,9 @@ func (m marked) markExpr(x adt.Expr) { case nil: case *adt.Vertex: - x.VisitLeafConjuncts(func(c adt.Conjunct) bool { + for c := range x.LeafConjuncts() { m.markExpr(c.Expr()) - return true - }) + } case *adt.BinaryExpr: if x.Op == adt.AndOp { diff --git a/vendor/cuelang.org/go/internal/core/export/adt.go b/vendor/cuelang.org/go/internal/core/export/adt.go index c7b8b7085c..7fb30f278d 100644 --- a/vendor/cuelang.org/go/internal/core/export/adt.go +++ b/vendor/cuelang.org/go/internal/core/export/adt.go @@ -55,7 +55,6 @@ func (e *exporter) adt(env *adt.Environment, expr adt.Elem) ast.Expr { // _, saved := e.pushFrame([]adt.Conjunct{adt.MakeConjunct(nil, x)}) // defer e.popFrame(saved) // s := e.frame(0).scope - s := &ast.StructLit{} // TODO: ensure e.node() is set in more cases. Right now it is not // always set in mergeValues, even in cases where it could be. Better @@ -231,6 +230,12 @@ func (e *exporter) adt(env *adt.Environment, expr adt.Elem) ast.Expr { X: e.innerExpr(env, x.X), } + case *adt.OpenExpr: + return &ast.PostfixExpr{ + X: e.innerExpr(env, x.X), + Op: token.ELLIPSIS, + } + case *adt.BinaryExpr: if x.Op == adt.AndOp || x.Op == adt.OrOp { return e.sortBinaryTree(env, x) @@ -484,13 +489,13 @@ func (e *exporter) resolve(env *adt.Environment, r adt.Resolver) ast.Expr { case *adt.ImportReference: importPath := x.ImportPath.StringValue(e.index) + info := ast.ParseImportPath(importPath) spec := ast.NewImport(nil, importPath) - info, _ := astutil.ParseImportSpec(spec) - name := info.PkgName + name := info.Qualifier if x.Label != 0 { - name = x.Label.StringValue(e.index) - if name != info.PkgName { + name = x.Label.IdentString(e.index) + if name != info.Qualifier { spec.Name = ast.NewIdent(name) } } diff --git a/vendor/cuelang.org/go/internal/core/export/export.go b/vendor/cuelang.org/go/internal/core/export/export.go index 331b39f38d..b87e10f2ee 100644 --- a/vendor/cuelang.org/go/internal/core/export/export.go +++ b/vendor/cuelang.org/go/internal/core/export/export.go @@ -16,7 +16,8 @@ package export import ( "fmt" - "math/rand" + "math/rand/v2" + "slices" "cuelang.org/go/cue/ast" "cuelang.org/go/cue/ast/astutil" @@ -71,6 +72,10 @@ type Profile struct { // InlineImports expands references to non-builtin packages. InlineImports bool + + // ExpandReferences causes all references to be expanded inline. This + // disables the ability to prevent billion laughs attacks, so use with care. + ExpandReferences bool } var Simplified = &Profile{ @@ -192,10 +197,10 @@ func (e *exporter) toFile(v *adt.Vertex, x ast.Expr) *ast.File { // prevent the file comment from attaching to pkg when there is no pkg comment PackagePos: token.NoPos.WithRel(token.NewSection), } - v.VisitLeafConjuncts(func(c adt.Conjunct) bool { + for c := range v.LeafConjuncts() { f, _ := c.Source().(*ast.File) if f == nil { - return true + continue } if name := f.PackageName(); name != "" { @@ -214,18 +219,17 @@ func (e *exporter) toFile(v *adt.Vertex, x ast.Expr) *ast.File { ast.AddComment(fout, c) } } - return true - }) + } if pkgName != "" { pkg.Name = ast.NewIdent(pkgName) fout.Decls = append(fout.Decls, pkg) - ast.SetComments(pkg, internal.MergeDocs(pkg.Comments())) + ast.SetComments(pkg, mergeDocs(pkg.Comments())) } else { for _, c := range fout.Comments() { ast.AddComment(pkg, c) } - ast.SetComments(fout, internal.MergeDocs(pkg.Comments())) + ast.SetComments(fout, mergeDocs(pkg.Comments())) } } @@ -243,6 +247,39 @@ func (e *exporter) toFile(v *adt.Vertex, x ast.Expr) *ast.File { return fout } +// mergeDocs merges multiple doc comments into one single doc comment. +func mergeDocs(comments []*ast.CommentGroup) []*ast.CommentGroup { + if len(comments) <= 1 || !hasDocComment(comments) { + return comments + } + + comments1 := make([]*ast.CommentGroup, 0, len(comments)) + comments1 = append(comments1, nil) + var docComment *ast.CommentGroup + for _, c := range comments { + switch { + case !c.Doc: + comments1 = append(comments1, c) + case docComment == nil: + docComment = c + default: + docComment.List = append(slices.Clip(docComment.List), &ast.Comment{Text: "//"}) + docComment.List = append(docComment.List, c.List...) + } + } + comments1[0] = docComment + return comments1 +} + +func hasDocComment(comments []*ast.CommentGroup) bool { + for _, c := range comments { + if c.Doc { + return true + } + } + return false +} + // Vertex exports evaluated values (data mode). // It resolves incomplete references that point outside the current context. func Vertex(r adt.Runtime, pkgID string, n *adt.Vertex) (*ast.File, errors.Error) { @@ -383,7 +420,7 @@ func (e *exporter) initPivot(n *adt.Vertex) { switch { case e.cfg.SelfContained, e.cfg.InlineImports: // Explicitly enabled. - case n.Parent == nil, e.cfg.Fragment: + case n.Parent == nil, e.cfg.Fragment, e.cfg.ExpandReferences: return } e.initPivotter(n) @@ -412,10 +449,9 @@ func (e *exporter) markUsedFeatures(x adt.Expr) { switch x := n.(type) { case *adt.Vertex: if !x.IsData() { - x.VisitLeafConjuncts(func(c adt.Conjunct) bool { + for c := range x.LeafConjuncts() { w.Elem(c.Elem()) - return true - }) + } } case *adt.DynamicReference: @@ -644,7 +680,7 @@ type featureSet interface { } func (e *exporter) intn(n int) int { - return e.rand.Intn(n) + return e.rand.IntN(n) } func (e *exporter) makeFeature(s string) (f adt.Feature, ok bool) { @@ -665,7 +701,7 @@ func (e *exporter) makeFeature(s string) (f adt.Feature, ok bool) { // clearer this concerns a generated number. func (e *exporter) uniqueFeature(base string) (f adt.Feature, name string) { if e.rand == nil { - e.rand = rand.New(rand.NewSource(808)) + e.rand = rand.New(rand.NewPCG(123, 456)) // ensure determinism between runs } return findUnique(e, base) } @@ -686,7 +722,7 @@ func findUnique(set featureSet, base string) (f adt.Feature, name string) { const mask = 0xff_ffff_ffff_ffff // max bits; stay clear of int64 overflow const shift = 4 // rate of growth digits := 1 - for n := int64(0x10); ; n = int64(mask&((n< 0 { - sets = append(sets, a) - } - - return sortedArcs(sets) + return toposort.VertexFeatures(c, v) } func extractFeatures(in []*adt.StructInfo) (a [][]adt.Feature) { @@ -110,28 +82,6 @@ func VertexFeaturesUnsorted(v *adt.Vertex) (features []adt.Feature) { return features } -// sortedArcs is like sortArcs, but returns the features of optional and -// required fields in an sorted slice. Ultimately, the implementation should -// use merge sort everywhere, and this will be the preferred method. Also, -// when querying optional fields as well, this helps identifying the optional -// fields. -func sortedArcs(fronts [][]adt.Feature) []adt.Feature { - m := sortArcs(fronts) - return sortedArcsFromMap(m) -} - -func sortedArcsFromMap(m map[adt.Feature]int) []adt.Feature { - a := make([]adt.Feature, 0, len(m)) - - for k := range m { - a = append(a, k) - } - - slices.SortFunc(a, func(a1, a2 adt.Feature) int { return -cmp.Compare(m[a1], m[a2]) }) - - return a -} - // sortArcs does a topological sort of arcs based on a variant of Kahn's // algorithm. See // https://www.geeksforgeeks.org/topological-sorting-indegree-based-solution/ diff --git a/vendor/cuelang.org/go/internal/core/export/value.go b/vendor/cuelang.org/go/internal/core/export/value.go index f476a51bcd..e40af23fc8 100644 --- a/vendor/cuelang.org/go/internal/core/export/value.go +++ b/vendor/cuelang.org/go/internal/core/export/value.go @@ -56,10 +56,9 @@ func (e *exporter) vertex(n *adt.Vertex) (result ast.Expr) { e.popFrame(saved) }() - n.VisitLeafConjuncts(func(c adt.Conjunct) bool { + for c := range n.LeafConjuncts() { e.markLets(c.Expr().Source(), s) - return true - }) + } switch x := n.BaseValue.(type) { case nil: @@ -103,14 +102,9 @@ func (e *exporter) vertex(n *adt.Vertex) (result ast.Expr) { } if result == nil { // fall back to expression mode - a := []adt.Conjunct{} - n.VisitLeafConjuncts(func(c adt.Conjunct) bool { - a = append(a, c) - return true - }) // Use stable sort to ensure that tie breaks (for instance if elements // are not associated with a position) are deterministic. - slices.SortStableFunc(a, cmpConjuncts) + a := slices.SortedStableFunc(n.LeafConjuncts(), cmpConjuncts) exprs := make([]ast.Expr, 0, len(a)) for _, c := range a { @@ -228,6 +222,9 @@ func (e *exporter) value(n adt.Value, a ...adt.Conjunct) (result ast.Expr) { } result = ast.NewBinExpr(token.OR, a...) + case *adt.NodeLink: + return e.value(x.Node, a...) + default: panic(fmt.Sprintf("unsupported type %T", x)) } @@ -259,15 +256,13 @@ func (e *exporter) bool(n *adt.Bool) (b *ast.BasicLit) { return ast.NewBool(n.B) } -func extractBasic(a []adt.Conjunct) (lit *ast.BasicLit) { - adt.VisitConjuncts(a, func(c adt.Conjunct) bool { +func extractBasic(a []adt.Conjunct) *ast.BasicLit { + for c := range adt.ConjunctsSeq(a) { if b, ok := c.Source().(*ast.BasicLit); ok { - lit = &ast.BasicLit{Kind: b.Kind, Value: b.Value} - return false + return &ast.BasicLit{Kind: b.Kind, Value: b.Value} } - return true - }) - return lit + } + return nil } func (e *exporter) num(n *adt.Num, orig []adt.Conjunct) *ast.BasicLit { diff --git a/vendor/cuelang.org/go/internal/core/format/printer.go b/vendor/cuelang.org/go/internal/core/format/printer.go new file mode 100644 index 0000000000..a907a73b01 --- /dev/null +++ b/vendor/cuelang.org/go/internal/core/format/printer.go @@ -0,0 +1,26 @@ +// Copyright 2025 CUE Authors +// +// 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 +// +// https://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. + +// Package format provides functionality for pretty-printing CUE values. +// These types need to be in a separate package to avoid import cycles. +package format + +// Printer is the interface used to print CUE values. The only implementation so +// far is the one in internal/core/debug. Note that most packages cannot +// directly import the debug package. +type Printer interface { + // ReplaceArg is a function that may be called to replace arguments to + // errors. This is mostly used for cycle detection. + ReplaceArg(x any) (r any, wasReplaced bool) +} diff --git a/vendor/cuelang.org/go/internal/core/layer/layer.go b/vendor/cuelang.org/go/internal/core/layer/layer.go new file mode 100644 index 0000000000..2d04be7ee5 --- /dev/null +++ b/vendor/cuelang.org/go/internal/core/layer/layer.go @@ -0,0 +1,30 @@ +// Copyright 2025 CUE Authors +// +// 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 +// +// https://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. + +package layer + +type Priority int8 + +// TODO: algorithm for handling disjunctions more intuitively with layering. +// For instance, how do we handle this case?: +// +// x: {} | *{ +// b: x: 1 +// c: x: 2 +// } +// // If y > x, does the 2 of b force the default of x to fail? Could be an option. +// y: { +// b: *{x: 2} | {} +// c: *{x: 3} | {} +// } diff --git a/vendor/cuelang.org/go/internal/core/runtime/build.go b/vendor/cuelang.org/go/internal/core/runtime/build.go index 9e90ed8ef1..3bfab58ce9 100644 --- a/vendor/cuelang.org/go/internal/core/runtime/build.go +++ b/vendor/cuelang.org/go/internal/core/runtime/build.go @@ -15,14 +15,13 @@ package runtime import ( + "strconv" "strings" "cuelang.org/go/cue/ast" - "cuelang.org/go/cue/ast/astutil" "cuelang.org/go/cue/build" "cuelang.org/go/cue/errors" "cuelang.org/go/cue/stats" - "cuelang.org/go/cue/token" "cuelang.org/go/internal/core/adt" "cuelang.org/go/internal/core/compile" ) @@ -58,11 +57,9 @@ func (x *Runtime) Build(cfg *Config, b *build.Instance) (v *adt.Vertex, errs err // Build transitive dependencies. for _, file := range b.Files { - file.VisitImports(func(d *ast.ImportDecl) { - for _, s := range d.Specs { - errs = errors.Append(errs, x.buildSpec(cfg, b, s)) - } - }) + for s := range file.ImportSpecs() { + errs = errors.Append(errs, x.buildSpec(cfg, b, s)) + } } err := x.ResolveFiles(b) @@ -74,7 +71,7 @@ func (x *Runtime) Build(cfg *Config, b *build.Instance) (v *adt.Vertex, errs err } if cfg != nil && cfg.ImportPath != "" { b.ImportPath = cfg.ImportPath - b.PkgName = astutil.ImportPathName(b.ImportPath) + b.PkgName = ast.ParseImportPath(b.ImportPath).Qualifier } v, err = compile.Files(cc, x, b.ID(), b.Files...) errs = errors.Append(errs, err) @@ -91,15 +88,13 @@ func (x *Runtime) Build(cfg *Config, b *build.Instance) (v *adt.Vertex, errs err return v, errs } -func dummyLoad(token.Pos, string) *build.Instance { return nil } - func (r *Runtime) Compile(cfg *Config, source interface{}) (*adt.Vertex, *build.Instance) { ctx := build.NewContext() var filename string if cfg != nil && cfg.Filename != "" { filename = cfg.Filename } - p := ctx.NewInstance(filename, dummyLoad) + p := ctx.NewInstance(filename, nil) if err := p.AddFile(filename, source); err != nil { return nil, p } @@ -113,7 +108,7 @@ func (r *Runtime) CompileFile(cfg *Config, file *ast.File) (*adt.Vertex, *build. if cfg != nil && cfg.Filename != "" { filename = cfg.Filename } - p := ctx.NewInstance(filename, dummyLoad) + p := ctx.NewInstance(filename, nil) err := p.AddSyntax(file) if err != nil { return nil, p @@ -124,20 +119,20 @@ func (r *Runtime) CompileFile(cfg *Config, file *ast.File) (*adt.Vertex, *build. } func (x *Runtime) buildSpec(cfg *Config, b *build.Instance, spec *ast.ImportSpec) (errs errors.Error) { - info, err := astutil.ParseImportSpec(spec) + path, err := strconv.Unquote(spec.Path.Value) if err != nil { return errors.Promote(err, "invalid import path") } - pkg := b.LookupImport(info.ID) + pkg := b.LookupImport(path) if pkg == nil { - if strings.Contains(info.ID, ".") { + if strings.Contains(path, ".") { return errors.Newf(spec.Pos(), "package %q imported but not defined in %s", - info.ID, b.ImportPath) - } else if x.index.builtinPaths[info.ID] == nil { + path, b.ImportPath) + } else if x.index.builtinPaths[path] == nil { return errors.Newf(spec.Pos(), - "builtin package %q undefined", info.ID) + "builtin package %q undefined", path) } return nil } diff --git a/vendor/cuelang.org/go/internal/core/runtime/extern.go b/vendor/cuelang.org/go/internal/core/runtime/extern.go index edb231cef3..702528a032 100644 --- a/vendor/cuelang.org/go/internal/core/runtime/extern.go +++ b/vendor/cuelang.org/go/internal/core/runtime/extern.go @@ -74,10 +74,9 @@ func (r *Runtime) InjectImplementations(b *build.Instance, v *adt.Vertex) (errs d.errs = errors.Append(d.errs, d.addFile(f)) } - v.VisitLeafConjuncts(func(c adt.Conjunct) bool { + for c := range v.LeafConjuncts() { d.decorateConjunct(c.Elem(), v) - return true - }) + } return d.errs } diff --git a/vendor/cuelang.org/go/internal/core/runtime/imports.go b/vendor/cuelang.org/go/internal/core/runtime/imports.go index 3059b86447..17d8705f13 100644 --- a/vendor/cuelang.org/go/internal/core/runtime/imports.go +++ b/vendor/cuelang.org/go/internal/core/runtime/imports.go @@ -22,7 +22,6 @@ import ( "cuelang.org/go/cue/errors" "cuelang.org/go/internal" "cuelang.org/go/internal/core/adt" - "cuelang.org/go/internal/cueexperiment" ) type PackageFunc func(ctx adt.Runtime) (*adt.Vertex, errors.Error) @@ -59,12 +58,7 @@ var SharedRuntime = sync.OnceValue(func() *Runtime { // but future evaluator versions may not be compatible at that level. // We should consider using one SharedRuntime per evaluator version, // or getting rid of SharedRuntime altogether. - cueexperiment.Init() - if cueexperiment.Flags.EvalV3 { - r.version = internal.DevVersion - } else { - r.version = internal.DefaultVersion - } + r.SetVersion(internal.DefaultVersion) return r }) diff --git a/vendor/cuelang.org/go/internal/core/runtime/resolve.go b/vendor/cuelang.org/go/internal/core/runtime/resolve.go index 843245864b..0230dca859 100644 --- a/vendor/cuelang.org/go/internal/core/runtime/resolve.go +++ b/vendor/cuelang.org/go/internal/core/runtime/resolve.go @@ -43,9 +43,6 @@ func (r *Runtime) ResolveFiles(p *build.Instance) (errs errors.Error) { } } for _, f := range p.Files { - if f.PackageName() == "" { - continue - } err := resolveFile(idx, f, p, allFields) errs = errors.Append(errs, err) } @@ -74,7 +71,7 @@ func resolveFile( specs := []*ast.ImportSpec{} - for _, spec := range f.Imports { + for spec := range f.ImportSpecs() { id, err := strconv.Unquote(spec.Path.Value) if err != nil { continue // quietly ignore the error @@ -93,7 +90,7 @@ func resolveFile( if n, ok := fields[name]; ok { errs = errors.Append(errs, nodeErrorf(spec, "%s redeclared as imported package name\n"+ - "\tprevious declaration at %v", name, lineStr(idx, n))) + "\tprevious declaration at %s", name, n.Pos())) continue } fields[name] = spec @@ -162,7 +159,3 @@ func resolveFile( // } return errs } - -func lineStr(idx *index, n ast.Node) string { - return n.Pos().String() -} diff --git a/vendor/cuelang.org/go/internal/core/runtime/runtime.go b/vendor/cuelang.org/go/internal/core/runtime/runtime.go index cc1f71c931..f48dc2caa3 100644 --- a/vendor/cuelang.org/go/internal/core/runtime/runtime.go +++ b/vendor/cuelang.org/go/internal/core/runtime/runtime.go @@ -32,8 +32,8 @@ type Runtime struct { // the kind in a file-level @extern(kind) attribute. interpreters map[string]Interpreter - version internal.EvaluatorVersion - topoSort bool + version internal.EvaluatorVersion + simplifyValidators bool flags cuedebug.Config } @@ -44,7 +44,7 @@ func (r *Runtime) Settings() (internal.EvaluatorVersion, cuedebug.Config) { func (r *Runtime) ConfigureOpCtx(ctx *adt.OpContext) { ctx.Version = r.version - ctx.TopoSort = r.topoSort + ctx.SimplifyValidators = r.simplifyValidators ctx.Config = r.flags } @@ -80,20 +80,29 @@ func NewWithSettings(v internal.EvaluatorVersion, flags cuedebug.Config) *Runtim // SetVersion sets the version to use for the Runtime. This should only be set // before first use. func (r *Runtime) SetVersion(v internal.EvaluatorVersion) { - r.version = v -} - -// SetTopologicalSort sets whether or not to use topological sorting -// for the Runtime. -func (r *Runtime) SetTopologicalSort(b bool) { - r.topoSort = b + switch v { + case internal.EvalV3: + r.version = v + case internal.EvalVersionUnset, internal.DefaultVersion: + // TODO(evalv4): read from cueexperiment. + // cueexperiment.Init() + // if cueexperiment.Flags.EvalV3 { + r.version = internal.EvalV3 + } } // SetDebugOptions sets the debug flags to use for the Runtime. This should only // be set before first use. func (r *Runtime) SetDebugOptions(flags *cuedebug.Config) { r.flags = *flags - r.topoSort = r.topoSort || r.flags.SortFields +} + +// SetGlobalExperiments that apply to language evaluation. +// It does not set the version. +func (r *Runtime) SetGlobalExperiments(flags *cueexperiment.Config) { + r.simplifyValidators = !flags.KeepValidators + // Do not set version as this is already set by NewWithSettings or + // SetVersion. } // IsInitialized reports whether the runtime has been initialized. @@ -114,17 +123,14 @@ func (r *Runtime) Init() { r.loaded = map[*build.Instance]interface{}{} - cueexperiment.Init() - if cueexperiment.Flags.EvalV3 { - r.version = internal.DevVersion - } else { - r.version = internal.DefaultVersion - } - r.topoSort = cueexperiment.Flags.TopoSort + r.SetVersion(internal.DefaultVersion) // By default we follow the environment's CUE_DEBUG settings, // which can be overriden via [Runtime.SetDebugOptions], // such as with the API option [cuelang.org/go/cue/cuecontext.CUE_DEBUG]. cuedebug.Init() r.SetDebugOptions(&cuedebug.Flags) + + cueexperiment.Init() + r.SetGlobalExperiments(&cueexperiment.Flags) } diff --git a/vendor/cuelang.org/go/internal/core/subsume/subsume.go b/vendor/cuelang.org/go/internal/core/subsume/subsume.go index e2a6a7901c..0316bf2364 100644 --- a/vendor/cuelang.org/go/internal/core/subsume/subsume.go +++ b/vendor/cuelang.org/go/internal/core/subsume/subsume.go @@ -17,7 +17,6 @@ package subsume import ( "cuelang.org/go/cue/errors" - "cuelang.org/go/internal" "cuelang.org/go/internal/core/adt" ) @@ -114,6 +113,8 @@ func unifyValue(c *adt.OpContext, a, b adt.Value) adt.Value { return x } +var ErrInexact = errors.New("inexact subsumption") + func (s *subsumer) getError() (err errors.Error) { c := s.ctx // src := binSrc(token.NoPos, opUnify, gt, lt) @@ -132,7 +133,7 @@ func (s *subsumer) getError() (err errors.Error) { } err = s.errs if s.inexact { - err = errors.Wrap(err, internal.ErrInexact) + err = errors.Wrap(err, ErrInexact) } return err } diff --git a/vendor/cuelang.org/go/internal/core/subsume/value.go b/vendor/cuelang.org/go/internal/core/subsume/value.go index 8edbd6ad8b..3f13ea1d9a 100644 --- a/vendor/cuelang.org/go/internal/core/subsume/value.go +++ b/vendor/cuelang.org/go/internal/core/subsume/value.go @@ -312,7 +312,7 @@ func (s *subsumer) bound(x *adt.BoundValue, v adt.Value) bool { } func test(ctx *adt.OpContext, src adt.Node, op adt.Op, gt, lt adt.Value) bool { - x := adt.BinOp(ctx, op, gt, lt) + x := adt.BinOp(ctx, src, op, gt, lt) b, ok := x.(*adt.Bool) return ok && b.B } diff --git a/vendor/cuelang.org/go/internal/core/subsume/vertex.go b/vendor/cuelang.org/go/internal/core/subsume/vertex.go index adb164296a..98e312b3f4 100644 --- a/vendor/cuelang.org/go/internal/core/subsume/vertex.go +++ b/vendor/cuelang.org/go/internal/core/subsume/vertex.go @@ -16,10 +16,9 @@ package subsume import ( "fmt" + "slices" - "cuelang.org/go/internal" "cuelang.org/go/internal/core/adt" - "cuelang.org/go/internal/core/export" ) // Notes: @@ -29,212 +28,7 @@ import ( // // TODO(perf): use merge sort where possible. func (s *subsumer) vertices(x, y *adt.Vertex) bool { - if s.ctx.Version == internal.DevVersion { - return s.verticesDev(x, y) - } - if x == y { - return true - } - if x.ArcType < y.ArcType { - return false - } - - if s.Defaults { - y = y.Default() - } - - if b := y.Bottom(); b != nil { - // If the value is incomplete, the error is not final. So either check - // structural equivalence or return an error. - return !b.IsIncomplete() - } - - ctx := s.ctx - - final := y.IsData() || s.Final - - switch v := x.BaseValue.(type) { - case *adt.Bottom: - return false - - case *adt.ListMarker: - if !y.IsList() { - s.errf("list does not subsume %v (type %s)", y, y.Kind()) - return false - } - if !s.listVertices(x, y) { - return false - } - // TODO: allow other arcs alongside list arc. - return true - - case *adt.StructMarker: - _, ok := y.BaseValue.(*adt.StructMarker) - if !ok { - return false - } - - case adt.Value: - if !s.values(v, y.Value()) { - return false - } - - // Embedded scalars could still have arcs. - if final { - return true - } - - default: - panic(fmt.Sprintf("unexpected type %T", v)) - } - - xClosed := x.IsClosedStruct() && !s.IgnoreClosedness - // TODO: this should not close for taking defaults. Do a more principled - // makeover of this package before making it public, though. - yClosed := s.Final || s.Defaults || - (y.IsClosedStruct() && !s.IgnoreClosedness) - - if xClosed && !yClosed && !final { - return false - } - - types := x.OptionalTypes() - if !final && !s.IgnoreOptional && types&(adt.HasPattern|adt.HasAdditional) != 0 { - // TODO: there are many cases where pattern constraints can be checked. - s.inexact = true - return false - } - - // All arcs in x must exist in y and its values must subsume. - xFeatures := export.VertexFeaturesUnsorted(x) - for _, f := range xFeatures { - if s.Final && !f.IsRegular() { - continue - } - - a := x.Lookup(f) - aOpt := false - if a == nil { - // x.f is optional - if s.IgnoreOptional { - continue - } - - a = &adt.Vertex{Label: f} - x.MatchAndInsert(ctx, a) - a.Finalize(ctx) - - // If field a is optional and has value top, neither the - // omission of the field nor the field defined with any value - // may cause unification to fail. - if a.Kind() == adt.TopKind { - continue - } - - aOpt = true - } else if a.IsConstraint() { - if s.IgnoreOptional { - continue - } - // If field a is optional and has value top, neither the - // omission of the field nor the field defined with any value - // may cause unification to fail. - if a.Kind() == adt.TopKind { - continue - } - aOpt = true - } - - b := y.Lookup(f) - if b == nil { - // y.f is optional - if !aOpt { - s.errf("required field is optional in subsumed value: %v", f) - return false - } - - // If f is undefined for y and if y is closed, the field is - // implicitly defined as _|_ and thus subsumed. Technically, this is - // even true if a is not optional, but in that case it means that y - // is invalid, so return false regardless - if !y.Accept(ctx, f) || y.IsData() || s.Final { - continue - } - - b = &adt.Vertex{Label: f} - y.MatchAndInsert(ctx, b) - b.Finalize(ctx) - } - - if s.values(a, b) { - continue - } - - s.missing = f - s.gt = a - s.lt = y - - s.errf("field %v not present in %v", f, y) - return false - } - - if xClosed && !yClosed && !s.Final { - s.errf("closed struct does not subsume open struct") - return false - } - - yFeatures := export.VertexFeaturesUnsorted(y) -outer: - for _, f := range yFeatures { - if s.Final && !f.IsRegular() { - continue - } - - for _, g := range xFeatures { - if g == f { - // already validated - continue outer - } - } - - b := y.Lookup(f) - if b == nil { - if s.IgnoreOptional || s.Final { - continue - } - - b = &adt.Vertex{Label: f} - y.MatchAndInsert(ctx, b) - } else if b.IsConstraint() { - if s.IgnoreOptional || s.Final { - continue - } - } - - if !x.Accept(ctx, f) { - if s.Profile.IgnoreClosedness { - continue - } - s.errf("field not allowed in closed struct: %v", f) - return false - } - - a := &adt.Vertex{Label: f} - x.MatchAndInsert(ctx, a) - if !a.HasConjuncts() { - // It is accepted and has no further constraints, so all good. - continue - } - - a.Finalize(ctx) - b.Finalize(ctx) - - if !s.vertices(a, b) { - return false - } - } - - return true + return s.verticesDev(x, y) } // verticesDev replaces vertices with the implementation of the new evaluator. @@ -291,6 +85,9 @@ func (s *subsumer) verticesDev(x, y *adt.Vertex) bool { return true } + case nil: + return false + default: panic(fmt.Sprintf("unexpected type %T", v)) } @@ -432,7 +229,7 @@ outer: if apc == nil { return true } - if y.IsClosedList() || y.IsClosedList() || final { + if y.IsClosedStruct() || y.IsClosedList() || final { // This is a special case where know that any allowed optional field // in a must be bottom in y, which is strictly more specific. return true @@ -454,6 +251,8 @@ outerConstraint: for _, p := range apc.Pairs { for _, q := range bpc.Pairs { if adt.Equal(s.ctx, p.Pattern, q.Pattern, 0) { + p.Constraint.Finalize(s.ctx) + q.Constraint.Finalize(s.ctx) if !s.values(p.Constraint, q.Constraint) { return false } @@ -478,8 +277,8 @@ func (s *subsumer) listVertices(x, y *adt.Vertex) bool { return false } - xElems := x.Elems() - yElems := y.Elems() + xElems := slices.Collect(x.Elems()) + yElems := slices.Collect(y.Elems()) switch { case len(xElems) == len(yElems): diff --git a/vendor/cuelang.org/go/internal/core/toposort/cycles.go b/vendor/cuelang.org/go/internal/core/toposort/cycles.go deleted file mode 100644 index cd9b939bdd..0000000000 --- a/vendor/cuelang.org/go/internal/core/toposort/cycles.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2024 CUE Authors -// -// 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. - -package toposort - -import "slices" - -type ecNodeState struct { - visitedIncoming []*ecNodeState - blocked bool -} - -func (ecNode *ecNodeState) excluded() bool { - return ecNode == nil -} - -type ecFinderState struct { - cycles []*Cycle - stack []*Node -} - -type Cycle struct { - Nodes Nodes -} - -func (cycle *Cycle) RotateToStartAt(start *Node) { - nodes := cycle.Nodes - if start == nodes[0] { - return - } - for i, node := range nodes { - if start == node { - prefix := slices.Clone(nodes[:i]) - copy(nodes, nodes[i:]) - copy(nodes[len(nodes)-i:], prefix) - break - } - } -} - -// Calculate the Elementary Cycles (EC) within the current Strongly -// Connected Component (SCC). -// -// If the component contains no cycles (by definition, this means the -// component contains only a single node), then the slice returned -// will be empty. -// -// In general: -// -// 1. If a component contains two or more nodes then it contains at -// least one cycle. -// 2. A single node can be involved in many cycles. -// 3. This method finds all cycles within a component, but does not -// include cycles that are merely rotations of each -// other. I.e. every cycle is unique, ignoring rotations. -// 4. The cycles returned are unsorted: each cycle is itself in no -// particular rotation, and the complete slice of cycles is -// similarly unsorted. -// -// The complexity of this algorithm is O((n+e)*c) where -// - n: number of nodes in the SCC -// - e: number of edges between the nodes in the SCC -// - c: number of cycles discovered -// -// Donald B Johnson: Finding All the Elementary Circuits of a Directed -// Graph. SIAM Journal on Computing. Volumne 4, Nr. 1 (1975), -// pp. 77-84. -func (scc *StronglyConnectedComponent) ElementaryCycles() []*Cycle { - nodes := scc.Nodes - nodeStates := make([]ecNodeState, len(nodes)) - for i, node := range nodes { - node.ecNodeState = &nodeStates[i] - } - - ec := &ecFinderState{} - for i, node := range nodes { - ec.findCycles(node, node) - ec.unblockAll(nodes[i+1:]) - node.ecNodeState = nil - } - - return ec.cycles -} - -func (ec *ecFinderState) findCycles(origin, cur *Node) bool { - stackLen := len(ec.stack) - ec.stack = append(ec.stack, cur) - - curEc := cur.ecNodeState - curEc.blocked = true - - cycleFound := false - for _, next := range cur.Outgoing { - if next.ecNodeState.excluded() { - continue - } - if next == origin { // found cycle - ec.cycles = append(ec.cycles, &Cycle{Nodes: slices.Clone(ec.stack)}) - cycleFound = true - } else if !next.ecNodeState.blocked { - if ec.findCycles(origin, next) { - cycleFound = true - } - } - } - - if cycleFound { - ec.unblock(curEc) - } else { - for _, next := range cur.Outgoing { - if next.ecNodeState.excluded() { - continue - } - nextEc := next.ecNodeState - nextEc.visitedIncoming = append(nextEc.visitedIncoming, curEc) - } - } - - if len(ec.stack) != stackLen+1 { - panic("stack is unexpected height!") - } - ec.stack = ec.stack[:stackLen] - return cycleFound -} - -func (ec *ecFinderState) unblockAll(nodes Nodes) { - for _, node := range nodes { - nodeEc := node.ecNodeState - nodeEc.blocked = false - nodeEc.visitedIncoming = nodeEc.visitedIncoming[:0] - } -} - -func (ec *ecFinderState) unblock(nodeEc *ecNodeState) { - nodeEc.blocked = false - for _, previousEc := range nodeEc.visitedIncoming { - if previousEc.blocked { - ec.unblock(previousEc) - } - } - nodeEc.visitedIncoming = nodeEc.visitedIncoming[:0] -} diff --git a/vendor/cuelang.org/go/internal/core/toposort/graph.go b/vendor/cuelang.org/go/internal/core/toposort/graph.go index 9d43b76962..b2183f527d 100644 --- a/vendor/cuelang.org/go/internal/core/toposort/graph.go +++ b/vendor/cuelang.org/go/internal/core/toposort/graph.go @@ -16,15 +16,13 @@ package toposort import ( "cmp" - "math" "slices" "cuelang.org/go/internal/core/adt" ) const ( - NodeUnsorted = -1 - NodeInCurrentScc = -2 + NodeUnsorted = -1 ) type Graph struct { @@ -39,10 +37,7 @@ type Node struct { // temporary state for calculating the Strongly Connected // Components of a graph. sccNodeState *sccNodeState - // temporary state for calculating the Elementary Cycles of a - // graph. - ecNodeState *ecNodeState - position int + position int } func (n *Node) IsSorted() bool { @@ -154,127 +149,25 @@ func (index *indexComparison) compareNodeByName(a, b *Node) int { } } -func (index *indexComparison) compareCyclesByNames(a, b *Cycle) int { - return slices.CompareFunc(a.Nodes, b.Nodes, index.compareNodeByName) -} - func (index *indexComparison) compareComponentsByNodes(a, b *StronglyConnectedComponent) int { return slices.CompareFunc(a.Nodes, b.Nodes, index.compareNodeByName) } -func chooseCycleEntryNode(cycle *Cycle) (entryNode *Node, enabledSince, brokenEdgeCount int) { - enabledSince = math.MaxInt - - for _, cycleNode := range cycle.Nodes { - if cycleNode.IsSorted() { - // this node is already in the sorted result - continue - } - NextNodeIncoming: - for _, incoming := range cycleNode.Incoming { - position := incoming.position - - if position < 0 { - // this predecessor node has not yet been added to the sorted - // result. - for _, cycleNode1 := range cycle.Nodes { - // ignore this predecessor node if it is part of this cycle. - if cycleNode1 == incoming { - continue NextNodeIncoming - } - } - brokenEdgeCount++ - continue NextNodeIncoming - } - - // this predecessor node must already be in the sorted output. - if position < enabledSince { - enabledSince = position - entryNode = cycleNode - } - } - } - return entryNode, enabledSince, brokenEdgeCount -} - -func chooseCycle(indexCmp *indexComparison, unusedCycles []*Cycle) *Cycle { - chosenCycleIdx := -1 - chosenCycleBrokenEdgeCount := math.MaxInt - chosenCycleEnabledSince := math.MaxInt - var chosenCycleEntryNode *Node - - for i, cycle := range unusedCycles { - if cycle == nil { - continue - } - debug("cycle %d: %v\n", i, cycle) - entryNode, enabledSince, brokenEdgeCount := chooseCycleEntryNode(cycle) - - if entryNode == nil { - entryNode = slices.MinFunc( - cycle.Nodes, indexCmp.compareNodeByName) - } - - debug("cycle %v; edgeCount %v; enabledSince %v; entryNode %v\n", - cycle, brokenEdgeCount, enabledSince, - entryNode.SafeName(indexCmp)) - - cycleIsBetter := chosenCycleIdx == -1 - // this is written out long-form for ease of readability - switch { - case cycleIsBetter: - // noop - case brokenEdgeCount < chosenCycleBrokenEdgeCount: - cycleIsBetter = true - case brokenEdgeCount > chosenCycleBrokenEdgeCount: - // noop - only continue if == - - case enabledSince < chosenCycleEnabledSince: - cycleIsBetter = true - case enabledSince > chosenCycleEnabledSince: - // noop - only continue if == - - case indexCmp.compareNodeByName(entryNode, chosenCycleEntryNode) < 0: - cycleIsBetter = true - case entryNode == chosenCycleEntryNode: - cycleIsBetter = - indexCmp.compareCyclesByNames(cycle, unusedCycles[chosenCycleIdx]) < 0 - } - - if cycleIsBetter { - chosenCycleIdx = i - chosenCycleBrokenEdgeCount = brokenEdgeCount - chosenCycleEnabledSince = enabledSince - chosenCycleEntryNode = entryNode - } - } - - if chosenCycleEntryNode == nil { - return nil - } - - debug("Chose cycle: %v; entering at node: %s\n", - unusedCycles[chosenCycleIdx], chosenCycleEntryNode.SafeName(indexCmp)) - cycle := unusedCycles[chosenCycleIdx] - unusedCycles[chosenCycleIdx] = nil - cycle.RotateToStartAt(chosenCycleEntryNode) - return cycle -} - // Sort the features of the graph into a single slice. // -// As far as possible, a topological sort is used. -// -// Whenever there is choice as to which feature should occur next, a -// lexicographical comparison is done, and minimum feature chosen. +// As far as possible, a topological sort is used. We first calculate +// the strongly-connected-components (SCCs) of the graph. If the graph +// has no cycles then there will be 1 SCC per graph node, which we +// then walk topologically. When there is a choice as to which SCC to +// enter into next, a lexicographical comparison is done, and minimum +// feature chosen. // -// Whenever progress cannot be made due to needing to enter into -// cycles, the cycle to enter into, and the node of that cycle with -// which to start, is selected based on: -// -// 1. minimising the number of incoming edges that are violated -// 2. chosing a node which was reachable as early as possible -// 3. chosing a node with a smaller feature name (lexicographical) +// If the graph has cycles, then there will be at least one SCC +// containing several nodes. When we choose to enter this SCC, we use +// a lexicographical ordering of its nodes. This avoids the need for +// expensive and complex analysis of cycles: the maximum possible +// number of cycles rises with the factorial of the number of nodes in +// a component. func (graph *Graph) Sort(index adt.StringIndexer) []adt.Feature { indexCmp := &indexComparison{index} @@ -301,41 +194,8 @@ func (graph *Graph) Sort(index adt.StringIndexer) []adt.Feature { sccCurrent.visited = true sccVisitedCount++ debug("scc current: %p %v\n", sccCurrent, sccCurrent) - var cyclesCurrent []*Cycle - - var nodesReady Nodes - NextNode: - for _, node := range sccCurrent.Nodes { - node.position = NodeInCurrentScc - for _, required := range node.Incoming { - if !required.IsSorted() { - continue NextNode - } - } - nodesReady = append(nodesReady, node) - } - slices.SortFunc(nodesReady, indexCmp.compareNodeByName) - - requiredLen := len(nodesSorted) + len(sccCurrent.Nodes) - for requiredLen != len(nodesSorted) { - if len(nodesReady) == 0 { - debug("Stuck after: %v\n", nodesSorted) - if cyclesCurrent == nil { - cyclesCurrent = sccCurrent.ElementaryCycles() - debug("cycles current: %v\n", cyclesCurrent) - } - cycle := chooseCycle(indexCmp, cyclesCurrent) - if cycle == nil { - panic("No cycle found.") - } - nodesSorted, nodesReady = appendNodes( - indexCmp, nodesSorted, cycle.Nodes, nodesReady) - } else { - nodesSorted, nodesReady = appendNodes( - indexCmp, nodesSorted, nodesReady[:1], nodesReady[1:]) - } - } + nodesSorted = appendNodes(nodesSorted, sccCurrent.Nodes) sccReadyNeedsSorting := false SccNextOutgoing: @@ -356,35 +216,12 @@ func (graph *Graph) Sort(index adt.StringIndexer) []adt.Feature { return nodesSorted.Features() } -func appendNodes(indexCmp *indexComparison, nodesSorted, nodesReady, nodesEnabled Nodes) (nodesSortedOut, nodesEnabledOut Nodes) { - nodesReadyNeedsSorting := false - for _, node := range nodesReady { - if node.IsSorted() { - continue - } - node.position = len(nodesSorted) - nodesSorted = append(nodesSorted, node) - - NextOutgoing: - for _, next := range node.Outgoing { - if next.position != NodeInCurrentScc { - continue - } - for _, required := range next.Incoming { - if !required.IsSorted() { - continue NextOutgoing - } - } - debug("After %v, found new ready: %s\n", - nodesSorted, next.SafeName(indexCmp)) - nodesEnabled = append(nodesEnabled, next) - nodesReadyNeedsSorting = true - } - } - if nodesReadyNeedsSorting { - slices.SortFunc(nodesEnabled, indexCmp.compareNodeByName) +func appendNodes(nodesSorted, nodesReady Nodes) Nodes { + for i, node := range nodesReady { + node.position = len(nodesSorted) + i } - return nodesSorted, nodesEnabled + nodesSorted = append(nodesSorted, nodesReady...) + return nodesSorted } func debug(formatting string, args ...any) { diff --git a/vendor/cuelang.org/go/internal/core/toposort/vertex.go b/vendor/cuelang.org/go/internal/core/toposort/vertex.go index 014eec8c73..8a311f8645 100644 --- a/vendor/cuelang.org/go/internal/core/toposort/vertex.go +++ b/vendor/cuelang.org/go/internal/core/toposort/vertex.go @@ -128,9 +128,16 @@ package toposort // (including no position) will be treated as explicity unified, and // so no weight will be given to their relative position within the // Vertex's slice of StructInfos. +// +// TODO: Switch if possible to finding if a struct has been unified +// with a definition and as much as possible taking order from the +// definition. In order words, if a cycle is only created by edges +// that come from non-definitions, then we ignore those edges, and +// thus don't end up dealing with a cycle. import ( "fmt" + "maps" "slices" "cuelang.org/go/cue/token" @@ -144,8 +151,6 @@ type structMeta struct { // Should this struct be considered to be part of an explicit // unification (e.g. x & y)? isExplicit bool - // Does this struct have no incoming edges? - isRoot bool } func (sMeta *structMeta) String() string { @@ -153,8 +158,8 @@ func (sMeta *structMeta) String() string { if sMeta.structInfo != nil { sl = sMeta.structInfo.StructLit } - return fmt.Sprintf("{%p sl:%p %v (explicit? %v; root? %v)}", - sMeta, sl, sMeta.pos, sMeta.isExplicit, sMeta.isRoot) + return fmt.Sprintf("{%p sl:%p %v (explicit? %v)}", + sMeta, sl, sMeta.pos, sMeta.isExplicit) } func (sm *structMeta) hasDynamic(dynFieldsMap map[*adt.DynamicField][]adt.Feature) bool { @@ -212,42 +217,39 @@ func (sm *structMeta) hasDynamic(dynFieldsMap map[*adt.DynamicField][]adt.Featur // we look at the vertex's conjuncts. If a conjunct is a binary // expression &, then we look up the structMeta for the arguments to // the binary expression, and mark them as explicit unification. -func analyseStructs(v *adt.Vertex, builder *GraphBuilder) ([]*structMeta, map[adt.Decl][]*structMeta) { +func analyseStructs(v *adt.Vertex, builder *GraphBuilder) []*structMeta { structInfos := v.Structs - nodeToStructMeta := make(map[adt.Node][]*structMeta) - structMetas := make([]structMeta, len(structInfos)) - - // First pass: make sure we create all the structMetas and map to - // them from a StructInfo's StructLit, and all its internal - // Decls. Assume everything is a root. Initial attempt at recording - // a position, which will be correct only for direct use of literal - // structs in the calculation of vertex v. - for i, s := range structInfos { + // Note that it's important that nodeToStructMetas avoids duplicate entries, + // which cause significant slowness for some large configs. + nodeToStructMetas := make(map[adt.Node]map[*structMeta]bool) + // structMetaMap is heplful as we can't insert into a map unless we make it. + structMetaMap := func(node adt.Node) map[*structMeta]bool { + if m := nodeToStructMetas[node]; m != nil { + return m + } + m := make(map[*structMeta]bool) + nodeToStructMetas[node] = m + return m + } + structMetas := make([]*structMeta, 0, len(structInfos)) + + // Create all the structMetas and map to them from a StructInfo's + // StructLit, and all its internal Decls. Initial attempt at + // recording a position, which will be correct only for direct use + // of literal structs in the calculation of vertex v. + for _, s := range structInfos { sl := s.StructLit - sMeta := &structMetas[i] - sMeta.structInfo = s - sMeta.isRoot = true + sMeta := &structMeta{ + structInfo: s, + } + structMetas = append(structMetas, sMeta) + if src := sl.Source(); src != nil { sMeta.pos = src.Pos() } - nodeToStructMeta[sl] = append(nodeToStructMeta[sl], sMeta) + structMetaMap(sl)[sMeta] = true for _, decl := range sl.Decls { - nodeToStructMeta[decl] = append(nodeToStructMeta[decl], sMeta) - } - } - - roots := make([]*structMeta, 0, len(structMetas)) - outgoing := make(map[adt.Decl][]*structMeta) - // Second pass: build outgoing map based on the StructInfo - // parent-child relationship. Children are necessarily not roots. - for i := range structMetas { - sMeta := &structMetas[i] - parentDecl := sMeta.structInfo.Decl - if _, found := nodeToStructMeta[parentDecl]; found { - outgoing[parentDecl] = append(outgoing[parentDecl], sMeta) - sMeta.isRoot = false - } else { - roots = append(roots, sMeta) + structMetaMap(decl)[sMeta] = true } } @@ -256,22 +258,22 @@ func analyseStructs(v *adt.Vertex, builder *GraphBuilder) ([]*structMeta, map[ad // uncover the position of the earliest reference. for _, arc := range v.Arcs { builder.EnsureNode(arc.Label) - arc.VisitLeafConjuncts(func(c adt.Conjunct) bool { + for c := range arc.LeafConjuncts() { field := c.Field() debug("self arc conjunct field %p :: %T, expr %p :: %T (%v)\n", field, field, c.Expr(), c.Expr(), c.Expr().Source()) - sMetas, found := nodeToStructMeta[field] + sMetas, found := nodeToStructMetas[field] if !found { - return true + continue } if src := field.Source(); src != nil { - for _, sMeta := range sMetas { + for sMeta := range sMetas { sMeta.pos = src.Pos() } } refs := c.CloseInfo.CycleInfo.Refs if refs == nil { - return true + continue } debug(" ref %p :: %T (%v)\n", refs.Ref, refs.Ref, refs.Ref.Source().Pos()) @@ -280,26 +282,23 @@ func analyseStructs(v *adt.Vertex, builder *GraphBuilder) ([]*structMeta, map[ad debug(" ref %p :: %T (%v)\n", refs.Ref, refs.Ref, refs.Ref.Source().Pos()) } - nodeToStructMeta[refs.Ref] = append(nodeToStructMeta[refs.Ref], sMetas...) + maps.Insert(structMetaMap(refs.Ref), maps.All(sMetas)) if pos := refs.Ref.Source().Pos(); pos != token.NoPos { - for _, sMeta := range nodeToStructMeta[refs.Ref] { + for sMeta := range nodeToStructMetas[refs.Ref] { sMeta.pos = pos } } - - return true - }) + } } // Explore our own conjuncts, and the decls from our StructList, to // find explicit unifications, and mark structMetas accordingly. var worklist []adt.Expr - v.VisitLeafConjuncts(func(c adt.Conjunct) bool { + for c := range v.LeafConjuncts() { debug("self conjunct field %p :: %T, expr %p :: %T\n", c.Field(), c.Field(), c.Expr(), c.Expr()) worklist = append(worklist, c.Expr()) - return true - }) + } for _, si := range structInfos { for _, decl := range si.StructLit.Decls { if expr, ok := decl.(adt.Expr); ok { @@ -317,7 +316,7 @@ func analyseStructs(v *adt.Vertex, builder *GraphBuilder) ([]*structMeta, map[ad continue } for _, expr := range []adt.Expr{binExpr.X, binExpr.Y} { - for _, sMeta := range nodeToStructMeta[expr] { + for sMeta := range nodeToStructMetas[expr] { sMeta.isExplicit = true debug(" now explicit: %v\n", sMeta) } @@ -325,7 +324,7 @@ func analyseStructs(v *adt.Vertex, builder *GraphBuilder) ([]*structMeta, map[ad worklist = append(worklist, binExpr.X, binExpr.Y) } - return roots, outgoing + return structMetas } // Find all fields which have been created as a result of successful @@ -333,15 +332,14 @@ func analyseStructs(v *adt.Vertex, builder *GraphBuilder) ([]*structMeta, map[ad func dynamicFieldsFeatures(v *adt.Vertex) map[*adt.DynamicField][]adt.Feature { var m map[*adt.DynamicField][]adt.Feature for _, arc := range v.Arcs { - arc.VisitLeafConjuncts(func(c adt.Conjunct) bool { + for c := range arc.LeafConjuncts() { if dynField, ok := c.Field().(*adt.DynamicField); ok { if m == nil { m = make(map[*adt.DynamicField][]adt.Feature) } m[dynField] = append(m[dynField], arc.Label) } - return true - }) + } } return m } @@ -373,7 +371,6 @@ func (batchesPtr *structMetaBatches) appendBatch(batch structMetaBatch) { type vertexFeatures struct { builder *GraphBuilder dynFieldsMap map[*adt.DynamicField][]adt.Feature - outgoing map[adt.Decl][]*structMeta } func (vf *vertexFeatures) compareStructMeta(a, b *structMeta) int { @@ -397,12 +394,11 @@ func VertexFeatures(ctx *adt.OpContext, v *adt.Vertex) []adt.Feature { builder := NewGraphBuilder(!ctx.Config.SortFields) dynFieldsMap := dynamicFieldsFeatures(v) - roots, outgoing := analyseStructs(v, builder) + roots := analyseStructs(v, builder) vf := &vertexFeatures{ builder: builder, dynFieldsMap: dynFieldsMap, - outgoing: outgoing, } slices.SortFunc(roots, vf.compareStructMeta) @@ -445,9 +441,8 @@ func VertexFeatures(ctx *adt.OpContext, v *adt.Vertex) []adt.Feature { } func (vf *vertexFeatures) addEdges(previous []adt.Feature, sMeta *structMeta) []adt.Feature { - debug("--- S %p (%p :: %T) (sl: %p) (explicit? %v) ---\n", - sMeta, sMeta.structInfo.Decl, sMeta.structInfo.Decl, - sMeta.structInfo.StructLit, sMeta.isExplicit) + debug("--- S %p (sl: %p) (explicit? %v) ---\n", + sMeta, sMeta.structInfo.StructLit, sMeta.isExplicit) debug(" previous: %v\n", previous) var next []adt.Feature @@ -504,26 +499,6 @@ func (vf *vertexFeatures) addEdges(previous []adt.Feature, sMeta *structMeta) [] next = nil } } - - if nextStructMetas := vf.outgoing[decl]; len(nextStructMetas) != 0 { - debug(" nextStructs: %v\n", nextStructMetas) - binExpr, isBinary := decl.(*adt.BinaryExpr) - isBinary = isBinary && binExpr.Op == adt.AndOp - - for _, sMeta := range nextStructMetas { - sMeta.isExplicit = isBinary - edges := vf.addEdges(previous, sMeta) - if isBinary { - next = append(next, edges...) - } else { - previous = edges - } - } - if isBinary { - previous = next - next = nil - } - } } return previous diff --git a/vendor/cuelang.org/go/internal/core/validate/validate.go b/vendor/cuelang.org/go/internal/core/validate/validate.go deleted file mode 100644 index 4fba892236..0000000000 --- a/vendor/cuelang.org/go/internal/core/validate/validate.go +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2020 CUE Authors -// -// 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. - -// Package validate collects errors from an evaluated Vertex. -package validate - -import ( - "cuelang.org/go/internal/core/adt" -) - -type Config struct { - // Concrete, if true, requires that all values be concrete. - Concrete bool - - // Final, if true, checks that there are no required fields left. - Final bool - - // DisallowCycles indicates that there may not be cycles. - DisallowCycles bool - - // AllErrors continues descending into a Vertex, even if errors are found. - AllErrors bool - - // TODO: omitOptional, if this is becomes relevant. -} - -// Validate checks that a value has certain properties. The value must have -// been evaluated. -func Validate(ctx *adt.OpContext, v *adt.Vertex, cfg *Config) *adt.Bottom { - if cfg == nil { - cfg = &Config{} - } - x := validator{Config: *cfg, ctx: ctx} - x.validate(v) - return x.err -} - -type validator struct { - Config - ctx *adt.OpContext - err *adt.Bottom - inDefinition int -} - -func (v *validator) checkConcrete() bool { - return v.Concrete && v.inDefinition == 0 -} - -func (v *validator) checkFinal() bool { - return (v.Concrete || v.Final) && v.inDefinition == 0 -} - -func (v *validator) add(b *adt.Bottom) { - if !v.AllErrors { - v.err = adt.CombineErrors(nil, v.err, b) - return - } - if !b.ChildError { - v.err = adt.CombineErrors(nil, v.err, b) - } -} - -func (v *validator) validate(x *adt.Vertex) { - defer v.ctx.PopArc(v.ctx.PushArc(x)) - - // Dereference values, but only those that are not shared. This includes let - // values. This prevents us from processing structure-shared nodes more than - // once and prevents potential cycles. - x = x.DerefNonShared() - if b := x.Bottom(); b != nil { - switch b.Code { - case adt.CycleError: - if v.checkFinal() || v.DisallowCycles { - v.add(b) - } - - case adt.IncompleteError: - if v.checkFinal() { - v.add(b) - } - - default: - v.add(b) - } - if !b.HasRecursive { - return - } - - } else if v.checkConcrete() { - x = x.Default() - if !adt.IsConcrete(x) { - x := x.Value() - v.add(&adt.Bottom{ - Code: adt.IncompleteError, - Err: v.ctx.Newf("incomplete value %v", x), - }) - } - } - - for _, a := range x.Arcs { - if a.ArcType == adt.ArcRequired && v.Final && v.inDefinition == 0 { - v.add(adt.NewRequiredNotPresentError(v.ctx, a)) - continue - } - - if a.Label.IsLet() || !a.IsDefined(v.ctx) { - continue - } - if !v.AllErrors && v.err != nil { - break - } - if a.Label.IsRegular() { - v.validate(a) - } else { - v.inDefinition++ - v.validate(a) - v.inDefinition-- - } - } -} diff --git a/vendor/cuelang.org/go/internal/core/walk/walk.go b/vendor/cuelang.org/go/internal/core/walk/walk.go index fb4ac6bf3e..02545e22b4 100644 --- a/vendor/cuelang.org/go/internal/core/walk/walk.go +++ b/vendor/cuelang.org/go/internal/core/walk/walk.go @@ -123,6 +123,9 @@ func (w *Visitor) node(n adt.Node) { w.node(x.X) w.node(x.Y) + case *adt.OpenExpr: + w.node(x.X) + case *adt.CallExpr: w.node(x.Fun) for _, arg := range x.Args { diff --git a/vendor/cuelang.org/go/internal/cueconfig/config.go b/vendor/cuelang.org/go/internal/cueconfig/config.go index e9b5894fc1..b8ed40c1cb 100644 --- a/vendor/cuelang.org/go/internal/cueconfig/config.go +++ b/vendor/cuelang.org/go/internal/cueconfig/config.go @@ -10,10 +10,11 @@ import ( "path/filepath" "time" - "cuelang.org/go/internal/golangorgx/tools/robustio" - "cuelang.org/go/internal/mod/modresolve" "github.com/rogpeppe/go-internal/lockedfile" "golang.org/x/oauth2" + + "cuelang.org/go/internal/mod/modresolve" + "cuelang.org/go/internal/robustio" ) // Logins holds the login information as stored in $CUE_CONFIG_DIR/logins.cue. @@ -30,8 +31,6 @@ type Logins struct { type RegistryLogin struct { // These fields mirror [oauth2.Token]. // We don't directly reference the type so we can be in control of our file format. - // Note that Expiry is a pointer, so omitempty can work as intended. - // TODO(mvdan): drop the pointer once we can use json's omitzero: https://go.dev/issue/45669 // Note that we store Expiry at rest as an absolute timestamp in UTC, // rather than the ExpiresIn field following the RFC's wire format, // a duration in seconds relative to the current time which is not useful at rest. @@ -42,7 +41,7 @@ type RegistryLogin struct { RefreshToken string `json:"refresh_token,omitempty"` - Expiry *time.Time `json:"expiry,omitempty"` + Expiry time.Time `json:"expiry,omitzero"` } func LoginConfigPath(getenv func(string) string) (string, error) { @@ -200,25 +199,19 @@ func RegistryOAuthConfig(host modresolve.Host) oauth2.Config { // changed between reading and writing the file. func TokenFromLogin(login RegistryLogin) *oauth2.Token { - tok := &oauth2.Token{ + return &oauth2.Token{ AccessToken: login.AccessToken, TokenType: login.TokenType, RefreshToken: login.RefreshToken, + Expiry: login.Expiry, } - if login.Expiry != nil { - tok.Expiry = *login.Expiry - } - return tok } func LoginFromToken(tok *oauth2.Token) RegistryLogin { - login := RegistryLogin{ + return RegistryLogin{ AccessToken: tok.AccessToken, TokenType: tok.TokenType, RefreshToken: tok.RefreshToken, + Expiry: tok.Expiry, } - if !tok.Expiry.IsZero() { - login.Expiry = &tok.Expiry - } - return login } diff --git a/vendor/cuelang.org/go/internal/cuedebug/cuedebug.go b/vendor/cuelang.org/go/internal/cuedebug/cuedebug.go index 089d0be4c4..a71f575b8d 100644 --- a/vendor/cuelang.org/go/internal/cuedebug/cuedebug.go +++ b/vendor/cuelang.org/go/internal/cuedebug/cuedebug.go @@ -9,7 +9,7 @@ import ( // Flags holds the set of global CUE_DEBUG flags. It is initialized by Init. var Flags Config -// Flags holds the set of known CUE_DEBUG flags. +// Config holds the set of known CUE_DEBUG flags. // // When adding, deleting, or modifying entries below, // update cmd/cue/cmd/help.go as well for `cue help environment`. @@ -42,29 +42,14 @@ type Config struct { // lexicographically. SortFields bool - // OpenInline permits disallowed fields to be selected into literal structs - // that would normally result in a close error. For instance, - // - // #D: {a: 1} - // x: (#D & {b: 2}).b // allow this - // - // This behavior was erroneously permitted in the v2 evaluator and was fixed - // in v3. This allows users that rely on this behavior to use v3. This - // option also discards closedness of the resulting expression. As was - // reported in Issue #3534, this was another erroneous behavior in v2 that - // is otherwise fixed in v3. - // - // To aid the transition to v3, this is enabled by default for now. - // - // A possible solution for both incompatibilities would be the introduction - // of an openAll builtin to recursive open up a cue value. For the first - // issue, the example above could be rewritten as: - // - // x: (openAll(#D) & {b: 2}).b - // - // For the second issue, to open up the entire result of an inline struct, - // such an expression could be written as `openAll(expr).out`. - OpenInline bool `envflag:"default:true"` + // OpenDef disables the check for closedness of definitions. + OpenDef bool + + // ToolsFlow causes [cuelang.org/go/tools/flow] to print a task dependency mermaid graph. + ToolsFlow bool + + // ParserTrace causes [cuelang.org/go/cue/parser] to print a trace of parsed productions. + ParserTrace bool } // Init initializes Flags. Note: this isn't named "init" because we diff --git a/vendor/cuelang.org/go/internal/cueexperiment/exp.go b/vendor/cuelang.org/go/internal/cueexperiment/exp.go index 0f7f59154c..58b6c48662 100644 --- a/vendor/cuelang.org/go/internal/cueexperiment/exp.go +++ b/vendor/cuelang.org/go/internal/cueexperiment/exp.go @@ -1,41 +1,76 @@ package cueexperiment import ( + "fmt" + "os" + "strings" "sync" - - "cuelang.org/go/internal/envflag" ) // Flags holds the set of global CUE_EXPERIMENT flags. It is initialized by Init. +var Flags Config + +// Config holds the set of known CUE_EXPERIMENT flags. // // When adding, deleting, or modifying entries below, // update cmd/cue/cmd/help.go as well for `cue help environment`. -var Flags struct { - // EvalV3 enables the new evaluator. The new evaluator addresses various - // performance concerns. - EvalV3 bool - - // Embed enables file embedding. - Embed bool `envflag:"default:true"` - - // DecodeInt64 changes [cuelang.org/go/cue.Value.Decode] to choose - // `int64` rather than `int` as the default type for CUE integer values - // to ensure consistency with 32-bit platforms. - DecodeInt64 bool `envflag:"default:true"` +type Config struct { + // CmdReferencePkg requires referencing an imported tool package to declare tasks. + // Otherwise, declaring tasks via "$id" or "kind" string fields is allowed. + CmdReferencePkg bool `experiment:"preview:v0.13.0,default:v0.14.0"` - // Enable topological sorting of struct fields. - TopoSort bool `envflag:"default:true"` + // KeepValidators prevents validators from simplifying into concrete values, + // even if their concrete value could be derived, such as '>=1 & <=1' to '1'. + // Proposal: https://cuelang.org/discussion/3775. + // Spec change: https://cuelang.org/cl/1217013 + // Spec change: https://cuelang.org/cl/1217014 + KeepValidators bool `experiment:"preview:v0.14.0,default:v0.14.0,stable:v0.15.0"` // The flags below describe completed experiments; they can still be set // as long as the value aligns with the final behavior once the experiment finished. // Breaking users who set such a flag seems unnecessary, // and it simplifies using the same experiment flags across a range of CUE versions. - // Modules was an experiment which ran from early 2023 to late 2024. - Modules bool `envflag:"deprecated,default:true"` + // Modules enables support for the modules and package management proposal + // as described in https://cuelang.org/discussion/2939. + Modules bool `experiment:"preview:v0.8.0,default:v0.9.0,stable:v0.11.0"` + + // YAMLV3Decoder swaps the old internal/third_party/yaml decoder with the new + // decoder implemented in internal/encoding/yaml on top of yaml.v3. + YAMLV3Decoder bool `experiment:"preview:v0.9.0,default:v0.9.0,stable:v0.11.0"` + + // DecodeInt64 changes [cuelang.org/go/cue.Value.Decode] to choose + // 'int64' rather than 'int' as the default type for CUE integer values + // to ensure consistency with 32-bit platforms. + DecodeInt64 bool `experiment:"preview:v0.11.0,default:v0.12.0,stable:v0.13.0"` + + // Embed enables support for embedded data files as described in + // https://cuelang.org/discussion/3264. + Embed bool `experiment:"preview:v0.10.0,default:v0.12.0,stable:v0.14.0"` + + // TopoSort enables topological sorting of struct fields. + // Provide feedback via https://cuelang.org/issue/3558. + TopoSort bool `experiment:"preview:v0.11.0,default:v0.12.0,stable:v0.14.0"` + + // EvalV3 enables the new CUE evaluator, addressing performance issues + // and bringing better algorithms for disjunctions, closedness, and cycles. + EvalV3 bool `experiment:"preview:v0.9.0,default:v0.13.0,stable:v0.15.0"` +} + +// initExperimentFlags initializes the experiment flags by processing both +// the experiment lifecycle and environment variable overrides. +func initExperimentFlags() error { + a := strings.Split(os.Getenv("CUE_EXPERIMENT"), ",") + experiments, err := parseEnvExperiments(a...) + if err != nil { + return err + } - // YAMLV3Decoder was an experiment which ran from early 2024 to late 2024. - YAMLV3Decoder bool `envflag:"deprecated,default:true"` + // First, set defaults based on experiment lifecycle + if err := parseConfig(&Flags, "", experiments); err != nil { + return fmt.Errorf("error in CUE_EXPERIMENT: %w", err) + } + return nil } // Init initializes Flags. Note: this isn't named "init" because we @@ -47,6 +82,4 @@ func Init() error { return initOnce() } -var initOnce = sync.OnceValue(func() error { - return envflag.Init(&Flags, "CUE_EXPERIMENT") -}) +var initOnce = sync.OnceValue(initExperimentFlags) diff --git a/vendor/cuelang.org/go/internal/cueexperiment/file.go b/vendor/cuelang.org/go/internal/cueexperiment/file.go new file mode 100644 index 0000000000..636d745124 --- /dev/null +++ b/vendor/cuelang.org/go/internal/cueexperiment/file.go @@ -0,0 +1,318 @@ +// Copyright 2025 CUE Authors +// +// 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 +// +// https://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. + +package cueexperiment + +import ( + "fmt" + "maps" + "reflect" + "slices" + "strings" + + "cuelang.org/go/internal/mod/semver" +) + +// This contains experiments that are configured per file. + +// File defines the experiments that can be set per file. Users can activate +// experiments by setting them using a file-based attribute @experiment() in +// a CUE file. When an experiment is first introduced, it is disabled by +// default. +// +// preview: the version from when the experiment was introduced. +// stable: the version from when it is permanently set to true. +// withdrawn: results in an error if the user attempts to use the flag. +type File struct { + // version is the module version of the file that was compiled. + version string + + // experiments is a comma-separated list of experiments that are enabled + // for this file. This is for documentation purposes only, as the + // experiments are already set in the struct fields. + experiments string + + // Testing is used to enable experiments for testing. + // + // TODO: we could later use it for enabling testing features, such as + // testing-specific builtins. + Testing bool `experiment:"preview:v0.13.0"` + + // Accepted_ is for testing purposes only. It should be removed when an + // experiment is accepted and can be used to test this feature instead. + Accepted_ bool `experiment:"preview:v0.13.0,stable:v0.15.0"` + + // StructCmp enables comparison of structs. This also defines the == + // operator to be defined on all values. For instance, comparing 1 and + // "foo" will return false, whereas previously it would return an error. + // + // Proposal: https://cuelang.org/issue/2583 + // Spec change: https://cuelang.org/cl/1217013 + // Spec change: https://cuelang.org/cl/1217014 + StructCmp bool `experiment:"preview:v0.14.0,stable:v0.15.0"` + + // ExplicitOpen enables the postfix ... operator to explicitly open + // closed structs, allowing additional fields to be added. + // + // Proposal: https://cuelang.org/issue/4032 + // Spec change: https://cuelang.org/cl/1221642 + // Requires cue fix when upgrading + ExplicitOpen bool `experiment:"preview:v0.15.0"` + + // AliasV2 enables the use of 'self' identifier to refer to the + // enclosing struct and enables the postfix alias syntax (~X and ~(K,V)). + // The file where this experiment is enabled disallows the use of old prefix + // alias syntax (X=). + // + // Proposal: https://cuelang.org/issue/4014 + // Spec change: https://cuelang.org/cl/1222377 + // Requires cue fix when upgrading + AliasV2 bool `experiment:"preview:v0.15.0"` +} + +// LanguageVersion returns the language version of the file or "" if no language +// version is associated with it. +func (f *File) LanguageVersion() string { + return f.version +} + +// NewFile parses the given comma-separated list of experiments for +// the given version and returns a PerFile struct with the experiments enabled. +// A empty version indicates the default version. +func NewFile(version string, experiments ...string) (*File, error) { + // TODO: cash versions for a given version where there is no experiment + // string. + m := parseExperiments(experiments...) + f := &File{ + version: version, + experiments: strings.Join(slices.Sorted(maps.Keys(m)), ","), + } + + if err := parseConfig(f, version, m); err != nil { + return nil, err + } + return f, nil +} + +// IsPreview returns true if the experiment exists and can be used +// for the given version. +func IsPreview(experiment, version string) bool { + return isPreview(experiment, version, File{}) +} + +func isPreview(experiment, version string, t any) bool { + expInfo := getExperimentInfoT(experiment, t) + if expInfo == nil { + return false + } + return expInfo.isValidForVersion(version) +} + +func (e *experimentInfo) isValidForVersion(version string) bool { + // Check if experiment is available for this version + if version != "" && e.Preview != "" { + if semver.Compare(version, e.Preview) < 0 { + return false + } + } + + // Check if experiment is rejected for this version + if e.Withdrawn != "" { + if version == "" || semver.Compare(version, e.Withdrawn) >= 0 { + return false + } + } + + return true +} + +// IsStable returns true if the experiment is stable (no longer +// experimental) for the given version. +func IsStable(experiment, version string) bool { + expInfo := getExperimentInfo(experiment) + if expInfo == nil { + return false + } + return expInfo.isStableForVersion(version) +} + +func (e *experimentInfo) isStableForVersion(version string) bool { + if e.Stable == "" { + return false + } + return version == "" || semver.Compare(version, e.Stable) >= 0 +} + +// CanApplyFix validates whether an experiment fix can be applied +// to a file with the given version and existing experiments. +func CanApplyFix(experiment, version, target string) error { + return canApplyExperimentFix(experiment, version, target, File{}) +} + +func canApplyExperimentFix(experiment, version, target string, t any) error { + expInfo := getExperimentInfoT(experiment, t) + if expInfo == nil { + return fmt.Errorf("unknown experiment %q", experiment) + } + + // Check if experiment is valid for this version + if !expInfo.isValidForVersion(target) { + if version != "" && expInfo.Preview != "" && + semver.Compare(target, expInfo.Preview) < 0 { + const msg = "experiment %q requires language version %s or later, have %s" + return fmt.Errorf(msg, experiment, expInfo.Preview, version) + } + + if expInfo.Withdrawn != "" { + if version == "" || semver.Compare(target, expInfo.Withdrawn) >= 0 { + const msg = "experiment %q is withdrawn in language version %s" + return fmt.Errorf(msg, experiment, expInfo.Withdrawn) + } + } + } + + // Check if experiment is already stable (cannot fix) + if expInfo.isStableForVersion(version) { + const msg = "experiment %q is already stable as of language version %s - cannot apply fix" + return fmt.Errorf(msg, experiment, expInfo.Stable) + } + + return nil +} + +// GetActive returns all experiments that are active (can be enabled) +// for the given version, but not yet accepted. +func GetActive(origVersion, targetVersion string) []string { + return getActiveExperiments(origVersion, targetVersion, File{}) +} + +func getActiveExperiments(origVersion, targetVersion string, t any) []string { + var active []string + + ft := reflect.TypeOf(t) + for i := 0; i < ft.NumField(); i++ { + field := ft.Field(i) + tagStr, ok := field.Tag.Lookup("experiment") + if !ok { + continue + } + name := strings.ToLower(field.Name) + expInfo := parseExperimentTag(tagStr) + + // Skip if not yet available for this version + if targetVersion != "" && expInfo.Preview != "" && semver.Compare(targetVersion, expInfo.Preview) < 0 { + continue + } + + // Skip if already stable + if expInfo.Stable != "" && (targetVersion == "" || semver.Compare(origVersion, expInfo.Stable) >= 0) { + continue + } + + // Skip if withdrawn + if expInfo.Withdrawn != "" { + continue + } + + active = append(active, name) + } + + slices.Sort(active) + return active +} + +// GetUpgradable returns all experiments that are stable +// (possibly in later versions), that can be upgraded from the current +// version (must be lower than stable) to the desired version. +func GetUpgradable(origVersion, targetVersion string) []string { + return getUpgradeExperiments(origVersion, targetVersion, File{}) +} + +func getUpgradeExperiments(origVersion, targetVersion string, t any) []string { + var accepted []string + if origVersion == "" { + panic("original version is empty") + } + + ft := reflect.TypeOf(t) + for i := 0; i < ft.NumField(); i++ { + field := ft.Field(i) + tagStr, ok := field.Tag.Lookup("experiment") + if !ok { + continue + } + name := strings.ToLower(field.Name) + expInfo := parseExperimentTag(tagStr) + + if expInfo.Stable != "" && + semver.Compare(targetVersion, expInfo.Preview) >= 0 && + semver.Compare(origVersion, expInfo.Stable) < 0 { + accepted = append(accepted, name) + } + } + + slices.Sort(accepted) + return accepted +} + +// ShouldRemoveAttribute returns true if the experiment attribute +// should be removed because the experiment is stable for the given version. +func ShouldRemoveAttribute(experiment, version string) bool { + return IsStable(experiment, version) +} + +// experimentInfo holds parsed experiment lifecycle information +type experimentInfo struct { + Preview string + Stable string + Withdrawn string +} + +// getExperimentInfo returns experiment lifecycle info for the given experiment name +func getExperimentInfo(experiment string) *experimentInfo { + return getExperimentInfoT(experiment, File{}) +} + +func getExperimentInfoT(experiment string, t any) *experimentInfo { + ft := reflect.TypeOf(t) + for i := 0; i < ft.NumField(); i++ { + field := ft.Field(i) + if strings.EqualFold(field.Name, experiment) { + if tagStr, ok := field.Tag.Lookup("experiment"); ok { + return parseExperimentTag(tagStr) + } + } + } + return nil +} + +// parseExperimentTag parses experiment tag string into experimentInfo +func parseExperimentTag(tagStr string) *experimentInfo { + info := &experimentInfo{} + for f := range strings.SplitSeq(tagStr, ",") { + key, rest, _ := strings.Cut(f, ":") + if !semver.IsValid(rest) { + panic(fmt.Sprintf("invalid semver in experiment tag %q: %q", key, rest)) + } + switch key { + case "preview": + info.Preview = rest + case "stable": + info.Stable = rest + case "withdrawn": + info.Withdrawn = rest + } + } + return info +} diff --git a/vendor/cuelang.org/go/internal/cueexperiment/parse.go b/vendor/cuelang.org/go/internal/cueexperiment/parse.go new file mode 100644 index 0000000000..de5a5b93e6 --- /dev/null +++ b/vendor/cuelang.org/go/internal/cueexperiment/parse.go @@ -0,0 +1,143 @@ +// Copyright 2025 CUE Authors +// +// 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 +// +// https://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. + +package cueexperiment + +import ( + "errors" + "fmt" + "reflect" + "strconv" + "strings" + + "cuelang.org/go/internal/mod/semver" +) + +func parseExperiments(x ...string) (m map[string]bool) { + for _, a := range x { + if a == "" { + continue + } + if m == nil { + m = make(map[string]bool) + } + for elem := range strings.SplitSeq(a, ",") { + elem = strings.TrimSpace(elem) + m[elem] = true + } + } + return m +} + +func parseEnvExperiments(x ...string) (m map[string]bool, err error) { + for _, name := range x { + if name == "" { + continue + } + if m == nil { + m = make(map[string]bool) + } + name, valueStr, _ := strings.Cut(name, "=") + if valueStr == "" { + m[name] = true + } else if val, err := strconv.ParseBool(valueStr); err == nil { + m[name] = val + } else { + return nil, fmt.Errorf("cannot parse CUE_EXPERIMENT: invalid value %q for experiment %q", valueStr, name) + } + } + return m, nil +} + +// parseConfig initializes the fields in flags from the attached struct field +// tags as well as a set of experiment names. +// +// version is the language version associated with the module of a file. An +// empty version string indicates the latest language version supported by the +// compiler. +// +// experiments is a map of experiment names. +// +// The struct field tag indicates the life cycle of the experiment, starting +// with the version from when it was introduced, the version where it became +// default, and the version where it was rejected or accepted. +// +// Experiments are all lowercase. Field names are converted to lower case. +func parseConfig[T any](flags *T, version string, experiments map[string]bool) error { + var errs []error + + // Collect the field indices and set the default values. + fv := reflect.ValueOf(flags).Elem() + ft := fv.Type() + for i := range ft.NumField() { + field := ft.Field(i) + if tagStr, ok := field.Tag.Lookup("experiment"); ok { + name := strings.ToLower(field.Name) + explicitlyEnabled, hasExperiment := experiments[name] + explicitlyDisabled := hasExperiment && !explicitlyEnabled + for f := range strings.SplitSeq(tagStr, ",") { + key, rest, _ := strings.Cut(f, ":") + switch key { + case "preview": + switch { + case !explicitlyEnabled: + // Experiment not explicitly enabled, skip + case version != "" && semver.Compare(version, rest) < 0: + const msg = "cannot set experiment %q before version %s" + errs = append(errs, fmt.Errorf(msg, name, rest)) + default: + // Experiment is explicitly enabled and version allows it + fv.Field(i).Set(reflect.ValueOf(true)) + } + + case "default": + if version == "" || semver.Compare(version, rest) >= 0 { + if !explicitlyDisabled { + fv.Field(i).Set(reflect.ValueOf(true)) + } + } + + case "stable": + if version == "" || semver.Compare(version, rest) >= 0 { + fv.Field(i).Set(reflect.ValueOf(true)) + } + if explicitlyDisabled { + // We allow setting deprecated flags to their default + // value so that bold explorers will not be penalized + // for their experimentation. + errs = append(errs, fmt.Errorf("cannot disable stable experiment %q", name)) + continue + } + + case "withdrawn": + expired := (version == "" || semver.Compare(version, rest) >= 0) + if expired && explicitlyEnabled { + const msg = "cannot set rejected experiment %q" + errs = append(errs, fmt.Errorf(msg, name)) + } + + default: + panic(fmt.Errorf("unknown exp tag %q", f)) + } + } + delete(experiments, name) + } + } + + for name := range experiments { + errs = append(errs, fmt.Errorf("unknown experiment %q", name)) + } + + return errors.Join(errs...) +} diff --git a/vendor/cuelang.org/go/internal/cueversion/version.go b/vendor/cuelang.org/go/internal/cueversion/version.go index 73fc5622f9..d863fc363d 100644 --- a/vendor/cuelang.org/go/internal/cueversion/version.go +++ b/vendor/cuelang.org/go/internal/cueversion/version.go @@ -8,16 +8,13 @@ import ( "runtime/debug" "strings" "sync" - "time" - - "golang.org/x/mod/module" ) // LanguageVersion returns the CUE language version. // This determines the latest version of CUE that // is accepted by the module. func LanguageVersion() string { - return "v0.12.0" + return "v0.15.1" } // ModuleVersion returns the version of the cuelang.org/go module as best as can @@ -43,32 +40,7 @@ var moduleVersionOnce = sync.OnceValue(func() string { // module name; it also happens when running the cue tests. return "(no-cue-module)" } - version := cueMod.Version - if version != "(devel)" { - return version - } - // A specific version was not provided by the buildInfo - // so attempt to make our own. - var vcsTime time.Time - var vcsRevision string - for _, s := range bi.Settings { - switch s.Key { - case "vcs.time": - // If the format is invalid, we'll print a zero timestamp. - vcsTime, _ = time.Parse(time.RFC3339Nano, s.Value) - case "vcs.revision": - vcsRevision = s.Value - // module.PseudoVersion recommends the revision to be a 12-byte - // commit hash prefix, which is what cmd/go uses as well. - if len(vcsRevision) > 12 { - vcsRevision = vcsRevision[:12] - } - } - } - if vcsRevision != "" { - version = module.PseudoVersion("", "", vcsTime, vcsRevision) - } - return version + return cueMod.Version }) func findCUEModule(bi *debug.BuildInfo) *debug.Module { diff --git a/vendor/cuelang.org/go/internal/encoding/encoder.go b/vendor/cuelang.org/go/internal/encoding/encoder.go index ac8f83ffa5..f7b54a6ab6 100644 --- a/vendor/cuelang.org/go/internal/encoding/encoder.go +++ b/vendor/cuelang.org/go/internal/encoding/encoder.go @@ -29,6 +29,7 @@ import ( "cuelang.org/go/cue/errors" "cuelang.org/go/cue/format" "cuelang.org/go/cue/token" + "cuelang.org/go/encoding/jsonschema" "cuelang.org/go/encoding/openapi" "cuelang.org/go/encoding/protobuf/jsonpb" "cuelang.org/go/encoding/protobuf/textproto" @@ -84,18 +85,21 @@ func NewEncoder(ctx *cue.Context, f *build.File, cfg *Config) (*Encoder, error) e.interpret = func(v cue.Value) (*ast.File, error) { return openapi.Generate(v, cfg) } + case build.JSONSchema: + // TODO: get encoding options + cfg := &jsonschema.GenerateConfig{} + e.interpret = func(v cue.Value) (*ast.File, error) { + expr, err := jsonschema.Generate(v, cfg) + if err != nil { + return nil, err + } + return internal.ToFile(expr), nil + } case build.ProtobufJSON: e.interpret = func(v cue.Value) (*ast.File, error) { f := internal.ToFile(v.Syntax()) return f, jsonpb.NewEncoder(v).RewriteFile(f) } - - // case build.JSONSchema: - // // TODO: get encoding options - // cfg := openapi.Config{} - // i.interpret = func(inst *cue.Instance) (*ast.File, error) { - // return jsonschmea.Generate(inst, cfg) - // } default: return nil, fmt.Errorf("unsupported interpretation %q", f.Interpretation) } @@ -250,40 +254,37 @@ func NewEncoder(ctx *cue.Context, f *build.File, cfg *Config) (*Encoder, error) } func (e *Encoder) EncodeFile(f *ast.File) error { - e.autoSimplify = false - return e.encodeFile(f, e.interpret) + if e.interpret == nil && e.encFile != nil { + // TODO it's not clear that it's actually desirable to turn + // off simplification in this case. This case generally arises + // when we're producing CUE code with `cue eval` and + // simplified results seem generally preferable. + e.autoSimplify = false + return e.encFile(f) + } + e.autoSimplify = true + return e.Encode(e.ctx.BuildFile(f)) } func (e *Encoder) Encode(v cue.Value) error { e.autoSimplify = true - if err := v.Validate(cue.Concrete(e.concrete)); err != nil { - return err - } - if e.interpret != nil { - f, err := e.interpret(v) - if err != nil { + if e.interpret == nil { + if err := v.Validate(cue.Concrete(e.concrete)); err != nil { return err } - return e.encodeFile(f, nil) - } - if e.encValue != nil { return e.encValue(v) } - return e.encFile(internal.ToFile(v.Syntax())) -} - -func (e *Encoder) encodeFile(f *ast.File, interpret func(cue.Value) (*ast.File, error)) error { - if interpret == nil && e.encFile != nil { - return e.encFile(f) + if err := v.Validate(); err != nil { + return err } - e.autoSimplify = true - v := e.ctx.BuildFile(f) - if err := v.Err(); err != nil { + f, err := e.interpret(v) + if err != nil { return err } - if interpret != nil { - return e.Encode(v) + if e.encFile != nil { + return e.encFile(f) } + v = e.ctx.BuildFile(f) if err := v.Validate(cue.Concrete(e.concrete)); err != nil { return err } diff --git a/vendor/cuelang.org/go/internal/encoding/encoding.go b/vendor/cuelang.org/go/internal/encoding/encoding.go index eea6ab6a96..6d312f32d8 100644 --- a/vendor/cuelang.org/go/internal/encoding/encoding.go +++ b/vendor/cuelang.org/go/internal/encoding/encoding.go @@ -37,6 +37,7 @@ import ( "cuelang.org/go/encoding/protobuf/jsonpb" "cuelang.org/go/encoding/protobuf/textproto" "cuelang.org/go/encoding/toml" + "cuelang.org/go/encoding/xml/koala" "cuelang.org/go/internal" "cuelang.org/go/internal/encoding/yaml" "cuelang.org/go/internal/filetypes" @@ -148,7 +149,8 @@ type Config struct { InlineImports bool // expand references to non-core imports ProtoPath []string Format []format.Option - ParseFile func(name string, src interface{}) (*ast.File, error) + ParserConfig parser.Config + ParseFile func(name string, src interface{}, cfg parser.Config) (*ast.File, error) } // NewDecoder returns a stream of non-rooted data expressions. The encoding @@ -160,6 +162,10 @@ func NewDecoder(ctx *cue.Context, f *build.File, cfg *Config) *Decoder { if cfg == nil { cfg = &Config{} } + if !cfg.ParserConfig.IsValid() { + // Avoid mutating cfg. + cfg.ParserConfig = parser.NewConfig(parser.ParseComments) + } i := &Decoder{filename: f.Filename, ctx: ctx, cfg: cfg} i.next = func() (ast.Expr, error) { if i.err != nil { @@ -233,9 +239,9 @@ func NewDecoder(ctx *cue.Context, f *build.File, cfg *Config) *Decoder { switch f.Encoding { case build.CUE: if cfg.ParseFile == nil { - i.file, i.err = parser.ParseFile(path, r, parser.ParseComments) + i.file, i.err = parser.ParseFile(path, r, cfg.ParserConfig) } else { - i.file, i.err = cfg.ParseFile(path, r) + i.file, i.err = cfg.ParseFile(path, r, cfg.ParserConfig) } i.validate(i.file, f) if i.err == nil { @@ -262,6 +268,14 @@ func NewDecoder(ctx *cue.Context, f *build.File, cfg *Config) *Decoder { case build.TOML: i.next = toml.NewDecoder(path, r).Decode i.Next() + case build.XML: + switch { + case f.BoolTags["koala"]: + i.next = koala.NewDecoder(path, r).Decode + i.Next() + default: + i.err = fmt.Errorf("xml requires a variant, such as: xml+koala") + } case build.Text: b, err := io.ReadAll(r) i.err = err diff --git a/vendor/cuelang.org/go/internal/encoding/yaml/decode.go b/vendor/cuelang.org/go/internal/encoding/yaml/decode.go index bd8b4986a5..36a54885d5 100644 --- a/vendor/cuelang.org/go/internal/encoding/yaml/decode.go +++ b/vendor/cuelang.org/go/internal/encoding/yaml/decode.go @@ -7,16 +7,16 @@ import ( "fmt" "io" "regexp" + "slices" "strconv" "strings" "sync" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v3" "cuelang.org/go/cue/ast" "cuelang.org/go/cue/literal" "cuelang.org/go/cue/token" - "cuelang.org/go/internal" ) // TODO(mvdan): we should sanity check that the decoder always produces valid CUE, @@ -102,13 +102,28 @@ func (d *decoder) Decode() (ast.Expr, error) { // Any further Decode calls must return EOF to avoid an endless loop. d.decodeErr = io.EOF - // If the input is empty, we produce a single null literal with EOF. + // If the input is empty, we produce `*null | _` followed by EOF. // Note that when the input contains "---", we get an empty document // with a null scalar value inside instead. if !d.yamlNonEmpty { - return &ast.BasicLit{ - Kind: token.NULL, - Value: "null", + // Attach positions which at least point to the filename. + pos := d.tokFile.Pos(0, token.NoRelPos) + return &ast.BinaryExpr{ + Op: token.OR, + OpPos: pos, + X: &ast.UnaryExpr{ + Op: token.MUL, + OpPos: pos, + X: &ast.BasicLit{ + Kind: token.NULL, + ValuePos: pos, + Value: "null", + }, + }, + Y: &ast.Ident{ + Name: "_", + NamePos: pos, + }, }, nil } // If the input wasn't empty, we already decoded some CUE syntax nodes, @@ -192,7 +207,7 @@ func (d *decoder) comments(src string) []*ast.Comment { return nil } var comments []*ast.Comment - for _, line := range strings.Split(src, "\n") { + for line := range strings.SplitSeq(src, "\n") { if line == "" { continue // yaml.v3 comments have a trailing newline at times } @@ -374,9 +389,6 @@ outer: } continue } - if yk.Kind != yaml.ScalarNode { - return d.posErrorf(yn, "invalid map key: %v", yk.ShortTag()) - } field := &ast.Field{} label, err := d.label(yk) @@ -420,8 +432,8 @@ func (d *decoder) merge(yn *yaml.Node, m *ast.StructLit, multiline bool) error { return d.insertMap(yn.Alias, m, multiline, true) case yaml.SequenceNode: // Step backwards as earlier nodes take precedence. - for i := len(yn.Content) - 1; i >= 0; i-- { - if err := d.merge(yn.Content[i], m, multiline); err != nil { + for _, c := range slices.Backward(yn.Content) { + if err := d.merge(c, m, multiline); err != nil { return err } } @@ -434,31 +446,37 @@ func (d *decoder) merge(yn *yaml.Node, m *ast.StructLit, multiline bool) error { func (d *decoder) label(yn *yaml.Node) (ast.Label, error) { pos := d.pos(yn) - expr, err := d.scalar(yn) + var expr ast.Expr + var err error + var value string + switch yn.Kind { + case yaml.ScalarNode: + expr, err = d.scalar(yn) + value = yn.Value + case yaml.AliasNode: + if yn.Alias.Kind != yaml.ScalarNode { + return nil, d.posErrorf(yn, "invalid map key: %v", yn.Alias.ShortTag()) + } + expr, err = d.alias(yn) + value = yn.Alias.Value + default: + return nil, d.posErrorf(yn, "invalid map key: %v", yn.ShortTag()) + } if err != nil { return nil, err } + switch expr := expr.(type) { case *ast.BasicLit: - if expr.Kind == token.STRING { - if ast.IsValidIdent(yn.Value) && !internal.IsDefOrHidden(yn.Value) { - return &ast.Ident{ - NamePos: pos, - Name: yn.Value, - }, nil - } - ast.SetPos(expr, pos) - return expr, nil + if expr.Kind != token.STRING { + // With incoming YAML like `Null: 1`, the key scalar is normalized to "null". + value = expr.Value } - - return &ast.BasicLit{ - ValuePos: pos, - Kind: token.STRING, - Value: literal.Label.Quote(expr.Value), - }, nil - + label := ast.NewStringLabel(value) + ast.SetPos(label, pos) + return label, nil default: - return nil, d.posErrorf(yn, "invalid label "+yn.Value) + return nil, d.posErrorf(yn, "invalid label "+value) } } diff --git a/vendor/cuelang.org/go/internal/encoding/yaml/encode.go b/vendor/cuelang.org/go/internal/encoding/yaml/encode.go index be970c90e9..155182017b 100644 --- a/vendor/cuelang.org/go/internal/encoding/yaml/encode.go +++ b/vendor/cuelang.org/go/internal/encoding/yaml/encode.go @@ -23,7 +23,7 @@ import ( "strings" "sync" - "gopkg.in/yaml.v3" + "go.yaml.in/yaml/v3" "cuelang.org/go/cue/ast" "cuelang.org/go/cue/errors" @@ -267,8 +267,8 @@ func encodeDecls(decls []ast.Decl) (n *yaml.Node, err error) { if !internal.IsRegularField(x) { return nil, errors.Newf(x.TokenPos, "yaml: definition or hidden fields not allowed") } - if x.Optional != token.NoPos { - return nil, errors.Newf(x.Optional, "yaml: optional fields not allowed") + if x.Constraint != token.ILLEGAL { + return nil, errors.Newf(x.TokenPos, "yaml: optional fields not allowed") } if hasEmbed { return nil, errors.Newf(x.TokenPos, "yaml: embedding mixed with fields") diff --git a/vendor/cuelang.org/go/internal/encoding/yaml/validate.go b/vendor/cuelang.org/go/internal/encoding/yaml/validate.go new file mode 100644 index 0000000000..d4807446f2 --- /dev/null +++ b/vendor/cuelang.org/go/internal/encoding/yaml/validate.go @@ -0,0 +1,103 @@ +// Copyright 2025 CUE Authors +// +// 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 +// +// https://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. + +package yaml + +import ( + "errors" + "io" + + "cuelang.org/go/cue" + "cuelang.org/go/internal/core/adt" + "cuelang.org/go/internal/pkg" + "cuelang.org/go/internal/value" +) + +// Validate validates YAML and confirms it is an instance of schema. +// If the YAML source is a stream, every object must match v. +// +// If Validate is called in a broader context, like a validation or function +// call, the cycle context of n should be accumulated in c before this call. +// This can be done by using the Expr method on the CallContext. +func Validate(c *adt.OpContext, b []byte, v cue.Value) (bool, error) { + d := NewDecoder("yaml.Validate", b) + r := v.Context() + for { + expr, err := d.Decode() + if err != nil { + if err == io.EOF { + return true, nil + } + return false, err + } + + x := r.BuildExpr(expr) + if err := x.Err(); err != nil { + return false, err + } + + // TODO: consider using subsumption again here. + // Alternatives: + // - allow definition of non-concrete list, + // like list.Of(int), or []int. + // - Introduce ! in addition to ?, allowing: + // list!: [...] + // if err := v.Subsume(inst.Value(), cue.Final()); err != nil { + // return false, err + // } + vx := adt.Unify(c, value.Vertex(x), value.Vertex(v)) + x = value.Make(c, vx) + if err := x.Err(); err != nil { + return false, err + } + + if err := x.Validate(cue.Concrete(true)); err != nil { + // Strip error codes: incomplete errors are terminal in this case. + var b pkg.Bottomer + if errors.As(err, &b) { + err = b.Bottom().Err + } + return false, err + } + } +} + +// ValidatePartial validates YAML and confirms it matches the constraints +// specified by v using unification. This means that b must be consistent with, +// but does not have to be an instance of v. If the YAML source is a stream, +// every object must match v. +func ValidatePartial(c *adt.OpContext, b []byte, v cue.Value) (bool, error) { + d := NewDecoder("yaml.ValidatePartial", b) + r := v.Context() + for { + expr, err := d.Decode() + if err != nil { + if err == io.EOF { + return true, nil + } + return false, err + } + + x := r.BuildExpr(expr) + if err := x.Err(); err != nil { + return false, err + } + + vx := adt.Unify(c, value.Vertex(x), value.Vertex(v)) + x = value.Make(c, vx) + if err := x.Err(); err != nil { + return false, err + } + } +} diff --git a/vendor/cuelang.org/go/internal/envflag/flag.go b/vendor/cuelang.org/go/internal/envflag/flag.go index 3b57ea9fb9..18c3c86ef2 100644 --- a/vendor/cuelang.org/go/internal/envflag/flag.go +++ b/vendor/cuelang.org/go/internal/envflag/flag.go @@ -32,30 +32,27 @@ func Init[T any](flags *T, envVar string) error { // representing the boolean fields in the struct type T. If the value is omitted // entirely, the value is assumed to be name=true. // -// Names are treated case insensitively. Value strings are parsed as Go booleans -// via [strconv.ParseBool], meaning that they accept "true" and "false" but also -// the shorter "1" and "0". +// Names are treated case insensitively. Boolean values are parsed via [strconv.ParseBool], +// integers via [strconv.Atoi], and strings are accepted as-is. func Parse[T any](flags *T, env string) error { // Collect the field indices and set the default values. indexByName := make(map[string]int) deprecated := make(map[string]bool) fv := reflect.ValueOf(flags).Elem() ft := fv.Type() - for i := 0; i < ft.NumField(); i++ { + for i := range ft.NumField() { field := ft.Field(i) name := strings.ToLower(field.Name) - defaultValue := false if tagStr, ok := field.Tag.Lookup("envflag"); ok { - for _, f := range strings.Split(tagStr, ",") { + for f := range strings.SplitSeq(tagStr, ",") { key, rest, hasRest := strings.Cut(f, ":") switch key { case "default": - v, err := strconv.ParseBool(rest) + val, err := parseValue(name, field.Type.Kind(), rest) if err != nil { - return fmt.Errorf("invalid default bool value for %s: %v", field.Name, err) + return err } - defaultValue = v - fv.Field(i).SetBool(defaultValue) + fv.Field(i).Set(reflect.ValueOf(val)) case "deprecated": if hasRest { return fmt.Errorf("cannot have a value for deprecated tag") @@ -69,46 +66,75 @@ func Parse[T any](flags *T, env string) error { indexByName[name] = i } - if env == "" { - return nil - } var errs []error - for _, elem := range strings.Split(env, ",") { - name, valueStr, ok := strings.Cut(elem, "=") - // "somename" is short for "somename=true" or "somename=1". - value := true - if ok { - v, err := strconv.ParseBool(valueStr) + for elem := range strings.SplitSeq(env, ",") { + if elem == "" { + // Allow empty elements such as `,somename=true` so that env vars + // can be joined together like + // + // os.Setenv("CUE_EXPERIMENT", os.Getenv("CUE_EXPERIMENT")+",extra") + // + // even when the previous env var is empty. + continue + } + name, valueStr, hasValue := strings.Cut(elem, "=") + + index, knownFlag := indexByName[name] + if !knownFlag { + errs = append(errs, fmt.Errorf("unknown flag %q", elem)) + continue + } + field := fv.Field(index) + var val any + if hasValue { + var err error + val, err = parseValue(name, field.Kind(), valueStr) if err != nil { - // Invalid format, return an error immediately. - return errInvalid{ - fmt.Errorf("invalid bool value for %s: %v", name, err), - } + errs = append(errs, err) + continue } - value = v - } - index, ok := indexByName[name] - if !ok { - // Unknown option, proceed processing options as long as the format - // is valid. - errs = append(errs, fmt.Errorf("unknown %s", elem)) + } else if field.Kind() == reflect.Bool { + // For bools, "somename" is short for "somename=true" or "somename=1". + // This mimics how Go flags work, e.g. -knob is short for -knob=true. + val = true + } else { + // For any other type, a value must be specified. + // This mimics how Go flags work, e.g. -output=path does not allow -output. + errs = append(errs, fmt.Errorf("value needed for %s flag %q", field.Kind(), name)) continue } + if deprecated[name] { - // We allow setting deprecated flags to their default value so - // that bold explorers will not be penalised for their - // experimentation. - if fv.Field(index).Bool() != value { + // We allow setting deprecated flags to their default value so that + // bold explorers will not be penalized for their experimentation. + if field.Interface() != val { errs = append(errs, fmt.Errorf("cannot change default value of deprecated flag %q", name)) } continue } - fv.Field(index).SetBool(value) + field.Set(reflect.ValueOf(val)) } return errors.Join(errs...) } +func parseValue(name string, kind reflect.Kind, str string) (val any, err error) { + switch kind { + case reflect.Bool: + val, err = strconv.ParseBool(str) + case reflect.Int: + val, err = strconv.Atoi(str) + case reflect.String: + val = str + default: + return nil, errInvalid{fmt.Errorf("unsupported kind %s", kind)} + } + if err != nil { + return nil, errInvalid{fmt.Errorf("invalid %s value for %s: %v", kind, name, err)} + } + return val, nil +} + // An ErrInvalid indicates a malformed input string. var ErrInvalid = errors.New("invalid value") diff --git a/vendor/cuelang.org/go/internal/filetypes/fileinfo.dat b/vendor/cuelang.org/go/internal/filetypes/fileinfo.dat new file mode 100644 index 0000000000000000000000000000000000000000..6af2904c3cfa2f722ad115c8480fd8df557129e2 GIT binary patch literal 153648 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 DV$}CG literal 0 HcmV?d00001 diff --git a/vendor/cuelang.org/go/internal/filetypes/filetypes.go b/vendor/cuelang.org/go/internal/filetypes/filetypes.go index 6330c0eedf..fe2fd66f88 100644 --- a/vendor/cuelang.org/go/internal/filetypes/filetypes.go +++ b/vendor/cuelang.org/go/internal/filetypes/filetypes.go @@ -15,15 +15,14 @@ package filetypes import ( - "fmt" "path/filepath" "strconv" "strings" - "cuelang.org/go/cue" "cuelang.org/go/cue/build" "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" + "cuelang.org/go/internal/filetypes/internal" ) // Mode indicate the base mode of operation and indicates a different set of @@ -35,6 +34,7 @@ const ( Export Def Eval + NumModes ) func (m Mode) String() string { @@ -50,100 +50,7 @@ func (m Mode) String() string { } } -// FileInfo defines the parsing plan for a file. -type FileInfo struct { - *build.File - - Definitions bool `json:"definitions"` // include/allow definition fields - Data bool `json:"data"` // include/allow regular fields - Optional bool `json:"optional"` // include/allow definition fields - Constraints bool `json:"constraints"` // include/allow constraints - References bool `json:"references"` // don't resolve/allow references - Cycles bool `json:"cycles"` // cycles are permitted - KeepDefaults bool `json:"keepDefaults"` // select/allow default values - Incomplete bool `json:"incomplete"` // permit incomplete values - Imports bool `json:"imports"` // don't expand/allow imports - Stream bool `json:"stream"` // permit streaming - Docs bool `json:"docs"` // show/allow docs - Attributes bool `json:"attributes"` // include/allow attributes -} - -// TODO(mvdan): the funcs below make use of typesValue concurrently, -// even though we clearly document that cue.Values are not safe for concurrent use. -// It seems to be OK in practice, as otherwise we would run into `go test -race` failures. - -// FromFile return detailed file info for a given build file. -// Encoding must be specified. -// TODO: mode should probably not be necessary here. -func FromFile(b *build.File, mode Mode) (*FileInfo, error) { - // Handle common case. This allows certain test cases to be analyzed in - // isolation without interference from evaluating these files. - if mode == Input && - b.Encoding == build.CUE && - b.Form == "" && - b.Interpretation == "" { - return &FileInfo{ - File: b, - - Definitions: true, - Data: true, - Optional: true, - Constraints: true, - References: true, - Cycles: true, - KeepDefaults: true, - Incomplete: true, - Imports: true, - Docs: true, - Attributes: true, - }, nil - } - - typesInit() - modeVal := typesValue.LookupPath(cue.MakePath(cue.Str("modes"), cue.Str(mode.String()))) - fileVal := modeVal.LookupPath(cue.MakePath(cue.Str("FileInfo"))) - fileVal = fileVal.FillPath(cue.Path{}, b) - - if b.Encoding == "" { - ext := modeVal.LookupPath(cue.MakePath(cue.Str("extensions"), cue.Str(fileExt(b.Filename)))) - if ext.Exists() { - fileVal = fileVal.Unify(ext) - } - } - var errs errors.Error - - interpretation, _ := fileVal.LookupPath(cue.MakePath(cue.Str("interpretation"))).String() - if b.Form != "" { - fileVal, errs = unifyWith(errs, fileVal, typesValue, "forms", string(b.Form)) - // may leave some encoding-dependent options open in data mode. - } else if interpretation != "" { - // always sets schema form. - fileVal, errs = unifyWith(errs, fileVal, typesValue, "interpretations", interpretation) - } - if interpretation == "" { - s, err := fileVal.LookupPath(cue.MakePath(cue.Str("encoding"))).String() - if err != nil { - return nil, err - } - fileVal, errs = unifyWith(errs, fileVal, modeVal, "encodings", s) - } - - fi := &FileInfo{} - if err := fileVal.Decode(fi); err != nil { - return nil, errors.Wrapf(err, token.NoPos, "could not parse arguments") - } - return fi, errs -} - -// unifyWith returns the equivalent of `v1 & v2[field][value]`. -func unifyWith(errs errors.Error, v1, v2 cue.Value, field, value string) (cue.Value, errors.Error) { - v1 = v1.Unify(v2.LookupPath(cue.MakePath(cue.Str(field), cue.Str(value)))) - if err := v1.Err(); err != nil { - errs = errors.Append(errs, - errors.Newf(token.NoPos, "unknown %s %s", field, value)) - } - return v1, errs -} +type FileInfo = internal.FileInfo // ParseArgs converts a sequence of command line arguments representing // files into a sequence of build file specifications. @@ -163,35 +70,18 @@ func unifyWith(errs errors.Error, v1, v2 cue.Value, field, value string) (cue.Va // // json: foo.data bar.data json+schema: bar.schema func ParseArgs(args []string) (files []*build.File, err error) { - typesInit() - var modeVal, fileVal cue.Value - qualifier := "" hasFiles := false + sc := &scope{} for i, s := range args { a := strings.Split(s, ":") switch { case len(a) == 1 || len(a[0]) == 1: // filename - if !fileVal.Exists() { - if len(a) == 1 && strings.HasSuffix(a[0], ".cue") { - // Handle majority case. - f := *fileForCUE - f.Filename = a[0] - files = append(files, &f) - hasFiles = true - continue - } - - modeVal, fileVal, err = parseType("", Input) - if err != nil { - return nil, err - } - } if s == "" { return nil, errors.Newf(token.NoPos, "empty file name") } - f, err := toFile(modeVal, fileVal, s) + f, err := toFile(Input, sc, s) if err != nil { return nil, err } @@ -213,7 +103,7 @@ func ParseArgs(args []string) (files []*build.File, err error) { case qualifier != "" && !hasFiles: return nil, errors.Newf(token.NoPos, "scoped qualifier %q without file", qualifier+":") } - modeVal, fileVal, err = parseType(a[0], Input) + sc, err = parseScope(a[0]) if err != nil { return nil, err } @@ -231,15 +121,13 @@ func DefaultTagsForInterpretation(interp build.Interpretation, mode Mode) map[st if interp == "" { return nil } - // TODO this could be done once only. // This should never fail if called with a legitimate build.Interpretation constant. - - mv, fv, err := parseType(string(interp), mode) - if err != nil { - panic(err) - } - f, err := toFile(mv, fv, "-") + f, err := toFile(mode, &scope{ + topLevel: map[string]bool{ + string(interp): true, + }, + }, "-") if err != nil { panic(err) } @@ -276,123 +164,70 @@ func ParseFile(s string, mode Mode) (*build.File, error) { // ParseFileAndType parses a file and type combo. func ParseFileAndType(file, scope string, mode Mode) (*build.File, error) { - // Quickly discard files which we aren't interested in. - // These cases are very common when loading `./...` in a large repository. - typesInit() - if scope == "" && file != "-" { - ext := fileExt(file) - if ext == "" { - return nil, errors.Newf(token.NoPos, "no encoding specified for file %q", file) - } - f, ok := fileForExt[ext] - if !ok { - return nil, errors.Newf(token.NoPos, "unknown file extension %s", ext) - } - if mode == Input { - f1 := *f - f1.Filename = file - return &f1, nil - } - } - modeVal, fileVal, err := parseType(scope, mode) + sc, err := parseScope(scope) if err != nil { return nil, err } - return toFile(modeVal, fileVal, file) + return toFile(mode, sc, file) } -func hasEncoding(v cue.Value) bool { - enc := v.LookupPath(cue.MakePath(cue.Str("encoding"))) - d, _ := enc.Default() - return d.IsConcrete() +// scope holds attributes that influence encoding and decoding. +// Together with the mode and the file name, they determine +// a number of properties of the encoding process. +type scope struct { + topLevel map[string]bool + subsidiaryBool map[string]bool + subsidiaryString map[string]string } -func toFile(modeVal, fileVal cue.Value, filename string) (*build.File, error) { - if !hasEncoding(fileVal) { - if filename == "-" { - fileVal = fileVal.Unify(modeVal.LookupPath(cue.MakePath(cue.Str("Default")))) - } else if ext := fileExt(filename); ext != "" { - extFile := modeVal.LookupPath(cue.MakePath(cue.Str("extensions"), cue.Str(ext))) - fileVal = fileVal.Unify(extFile) - if err := fileVal.Err(); err != nil { - return nil, errors.Newf(token.NoPos, "unknown file extension %s", ext) - } - } else { - return nil, errors.Newf(token.NoPos, "no encoding specified for file %q", filename) - } - } - - // Note that the filename is only filled in the Go value, and not the CUE value. - // This makes no difference to the logic, but saves a non-trivial amount of evaluator work. - f := &build.File{Filename: filename} - if err := fileVal.Decode(&f); err != nil { - return nil, errors.Wrapf(err, token.NoPos, - "could not determine file type") +func parseScope(scopeStr string) (*scope, error) { + if scopeStr == "" { + return &scope{}, nil } - return f, nil -} - -func parseType(scope string, mode Mode) (modeVal, fileVal cue.Value, _ error) { - modeVal = typesValue.LookupPath(cue.MakePath(cue.Str("modes"), cue.Str(mode.String()))) - fileVal = modeVal.LookupPath(cue.MakePath(cue.Str("FileInfo"))) - - if scope == "" { - return modeVal, fileVal, nil + sc := scope{ + topLevel: make(map[string]bool), + subsidiaryBool: make(map[string]bool), + subsidiaryString: make(map[string]string), } - var otherTags []string - for _, tag := range strings.Split(scope, "+") { - tagName, _, ok := strings.Cut(tag, "=") - if ok { - otherTags = append(otherTags, tag) - } else { - info := typesValue.LookupPath(cue.MakePath(cue.Str("tagInfo"), cue.Str(tagName))) - if info.Exists() { - fileVal = fileVal.Unify(info) + for tag := range strings.SplitSeq(scopeStr, "+") { + tagName, tagVal, hasValue := strings.Cut(tag, "=") + switch tagTypes[tagName] { + case TagTopLevel: + if hasValue { + return nil, errors.Newf(token.NoPos, "cannot specify value for tag %q", tagName) + } + sc.topLevel[tagName] = true + case TagSubsidiaryBool: + if hasValue { + t, err := strconv.ParseBool(tagVal) + if err != nil { + return nil, errors.Newf(token.NoPos, "invalid boolean value for tag %q", tagName) + } + sc.subsidiaryBool[tagName] = t } else { - // The tag might only be available when all the - // other tags have been evaluated. - otherTags = append(otherTags, tag) + sc.subsidiaryBool[tagName] = true } - } - } - if len(otherTags) == 0 { - return modeVal, fileVal, nil - } - // There are tags that aren't mentioned in tagInfo. - // They might still be valid, but just only valid within the file types that - // have been specified above, so look at the schema that we've got - // and see if it specifies any tags. - allowedTags := fileVal.LookupPath(cue.MakePath(cue.Str("tags"))) - allowedBoolTags := fileVal.LookupPath(cue.MakePath(cue.Str("boolTags"))) - for _, tag := range otherTags { - tagName, tagVal, hasValue := strings.Cut(tag, "=") - tagNamePath := cue.MakePath(cue.Str(tagName)).Optional() - tagSchema := allowedTags.LookupPath(tagNamePath) - if tagSchema.Exists() { - fileVal = fileVal.FillPath(cue.MakePath(cue.Str("tags"), cue.Str(tagName)), tagVal) - continue - } - if !allowedBoolTags.LookupPath(tagNamePath).Exists() { - return cue.Value{}, cue.Value{}, errors.Newf(token.NoPos, "unknown filetype %s", tagName) - } - tagValBool := true - if hasValue { - // It's a boolean tag and an explicit value has been specified. - // Allow the usual boolean string values. - t, err := strconv.ParseBool(tagVal) - if err != nil { - return cue.Value{}, cue.Value{}, fmt.Errorf("invalid boolean value for tag %q", tagName) + case TagSubsidiaryString: + if !hasValue { + return nil, errors.Newf(token.NoPos, "tag %q must have value (%s=)", tagName, tagName) } - tagValBool = t + sc.subsidiaryString[tagName] = tagVal + default: + return nil, errors.Newf(token.NoPos, "unknown filetype %s", tagName) } - fileVal = fileVal.FillPath(cue.MakePath(cue.Str("boolTags"), cue.Str(tagName)), tagValBool) } - return modeVal, fileVal, nil + return &sc, nil } // fileExt is like filepath.Ext except we don't treat file names starting with "." as having an extension // unless there's also another . in the name. +// +// It also treats "-" as a special case, so we treat stdin/stdout as +// a regular file. func fileExt(f string) string { + if f == "-" { + return "-" + } e := filepath.Ext(f) if e == "" || e == filepath.Base(f) { return "" diff --git a/vendor/cuelang.org/go/internal/filetypes/fromfile.dat b/vendor/cuelang.org/go/internal/filetypes/fromfile.dat new file mode 100644 index 0000000000000000000000000000000000000000..87868b118851b043574a2de5f044dc5ab8d24248 GIT binary patch literal 11502 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 QSoWmNqOyOIVW(;H|D}DoA^-pY literal 0 HcmV?d00001 diff --git a/vendor/cuelang.org/go/internal/filetypes/internal/genstruct/gen.go b/vendor/cuelang.org/go/internal/filetypes/internal/genstruct/gen.go new file mode 100644 index 0000000000..7ff9559491 --- /dev/null +++ b/vendor/cuelang.org/go/internal/filetypes/internal/genstruct/gen.go @@ -0,0 +1,244 @@ +// Copyright 2025 CUE Authors +// +// 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. + +package genstruct + +import ( + "bytes" + "encoding/binary" + "fmt" + "iter" + "math/bits" + "sort" +) + +// GetEnum returns the enum value held in data +// at the given offset and size, where values holds all +// the possible values of the enum. +// +// This is designed to be used in the generated code target, not the generator. +func GetEnum[T any](data []byte, offset, size int, values []T) T { + return values[GetUint64(data, offset, size)] +} + +// PutEnum writes the enum value x to data at the given offset and size, using valueMap +// to determine the actual numeric value to be written. If defaultIndex is non-negative, +// it determines the value to use if x is not present. +func PutEnum[T comparable](data []byte, offset, size int, valueMap map[T]int, defaultIndex int, x T) error { + i, ok := valueMap[x] + if !ok { + if defaultIndex >= 0 { + i = defaultIndex + } else { + return fmt.Errorf("value %#v not found in enum", x) + } + } + PutUint64(data, offset, size, uint64(i)) + return nil +} + +// GetSet returns an iterator through all the items in the set stored +// in data[offset:offset+size], where values holds all the members of the +// set in index order. +func GetSet[T comparable](data []byte, offset, size int, values []T) iter.Seq[T] { + return ElemsFromBits(GetUint64(data, offset, size), values) +} + +// GetEnumMap returns an iterator through all the keys and values in +// data[offset:offset+size], where keys and values hold the possible +// keys and values respectively, in index order. +func GetEnumMap(data []byte, offset, size int, keys, values []string) iter.Seq2[string, string] { + return func(yield func(k, v string) bool) { + x := GetUint64(data, offset, size) + valueBits := bits.Len64(uint64(len(values))) + mask := uint64(1)<>shift)&mask - 1 + if !yield(keys[keyIndex], values[valueIndex]) { + return + } + x &^= mask << shift + } + } +} + +// PutEnumMap puts the keys and values in x into data at the given offset and size, where valueBits holds +// the number of bits per value in the map and valueMap and keyMap give indexes for each possible +// key and value, and defaultKeyIndex/defaultValueIndex provide values to use in case a given +// value isn't one of the allowed keys or values. +func PutEnumMap(data []byte, offset, size int, valueBits int, valueMap, keyMap map[string]int, defaultKeyIndex, defaultValueIndex int, x iter.Seq2[string, string]) error { + var bits uint64 + mask := (uint64(1) << valueBits) - 1 + for k, v := range x { + ki, ok := keyMap[k] + if !ok { + if defaultKeyIndex == -1 { + return fmt.Errorf("unknown key %#v", k) + } + ki = defaultKeyIndex + } + vi, ok := valueMap[v] + if !ok { + if defaultValueIndex == -1 { + return fmt.Errorf("unknown value %#v", v) + } + vi = defaultValueIndex + } + shift := ki * valueBits + bits &^= mask << shift + bits |= (uint64(vi) + 1) << shift + } + PutUint64(data, offset, size, bits) + return nil +} + +// ElemsFromBits returns an iterator over all the items in the bitset +// x, where bit 1< 0 { + writeTable(&buf, a.goValuesIdent, a.goValueType, a.goValues) + } else { + writeTable(&buf, a.goValuesIdent, a.goValueType, a.values) + } + return buf.String() +} + +func (a enumAccessor[T]) Put(data []byte, x T) { + i, ok := a.valueToIndex[x] + if !ok { + panic(fmt.Errorf("set of value %#v outside enum set %v", x, a.values)) + } + a.a.Put(data, uint64(i)) +} + +// AddSet adds a set field to s with the given possible values (index ordered). +// The variable with name goValuesIdent will be assigned the values, +// of type slice of goValueType. +func AddSet(s *Struct, values []string, goValuesIdent string) Accessor[iter.Seq[string]] { + if len(values) == 0 { + panic("empty set") + } + if len(values) > 64 { + panic("more than 64 values in set") + } + valueToBit := make(map[string]uint64) + for i, v := range values { + valueToBit[v] = uint64(1 << i) + } + a := setAccessor{ + a: AddInt(s, (uint64(1)< 64 { + // TODO allow for arbitrary length + panic("more than 2^64 possible values in map") + } + a := enumMapAccessor[T]{ + a: AddInt(s, (uint64(1)<= len(_TagType_index)-1 { + return "TagType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _TagType_name[_TagType_index[idx]:_TagType_index[idx+1]] +} diff --git a/vendor/cuelang.org/go/internal/filetypes/tofile.go b/vendor/cuelang.org/go/internal/filetypes/tofile.go new file mode 100644 index 0000000000..572d1ef760 --- /dev/null +++ b/vendor/cuelang.org/go/internal/filetypes/tofile.go @@ -0,0 +1,33 @@ +// Copyright CUE Authors +// +// 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. + +package filetypes + +import ( + "cuelang.org/go/cue/build" +) + +//go:generate go run -tags cuebootstrap ./generate.go + +func toFile(mode Mode, sc *scope, filename string) (*build.File, error) { + return toFileGenerated(mode, sc, filename) +} + +// FromFile returns detailed file info for a given build file. It ignores b.Tags and +// b.BoolTags, instead assuming that any tag handling has already been processed +// by [ParseArgs] or similar. +// The b.Encoding field must be non-empty. +func FromFile(b *build.File, mode Mode) (*FileInfo, error) { + return fromFileGenerated(b, mode) +} diff --git a/vendor/cuelang.org/go/internal/filetypes/tofile_bootstrap.go b/vendor/cuelang.org/go/internal/filetypes/tofile_bootstrap.go new file mode 100644 index 0000000000..97dc156041 --- /dev/null +++ b/vendor/cuelang.org/go/internal/filetypes/tofile_bootstrap.go @@ -0,0 +1,27 @@ +// Copyright 2025 CUE Authors +// +// 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. + +//go:build cuebootstrap + +package filetypes + +import "cuelang.org/go/cue/build" + +func toFileGenerated(mode Mode, sc *scope, filename string) (*build.File, error) { + panic("never called") +} + +func fromFileGenerated(b *build.File, mode Mode) (*FileInfo, error) { + panic("never called") +} diff --git a/vendor/cuelang.org/go/internal/filetypes/types.cue b/vendor/cuelang.org/go/internal/filetypes/types.cue index 3597c1a420..0b2bea8f69 100644 --- a/vendor/cuelang.org/go/internal/filetypes/types.cue +++ b/vendor/cuelang.org/go/internal/filetypes/types.cue @@ -27,16 +27,10 @@ package build interpretation?: #Interpretation form?: #Form // Note: tags includes values for non-boolean tags only. - tags?: [string]: string + tags?: [string]: string boolTags?: [string]: bool } -// Default is the file used for stdin and stdout. The settings depend -// on the file mode. -#Default: #FileInfo & { - filename: *"-" | string -} - // A FileInfo defines how a file is encoded and interpreted. #FileInfo: { #File @@ -68,71 +62,73 @@ package build // to change this. fileForExtVanilla: modes.input.extensions -// modes sets defaults for different operational modes. -// The key corresponds to the Go internal/filetypes.Mode type. -modes: [string]: { +// #Mode represents an overall mode that CUE is being run in +// (e.g. eval, export). +#Mode: { // FileInfo holds the base file information for this mode. // This will be unified with information derived from the // file extension and any filetype tags explicitly provided. FileInfo!: #FileInfo - // Default holds the base file information for standard input - // or output, where we don't have any file extension available. - Default!: #Default + // extensions holds the set of file extensions that are defined + // for this mode. + extensions!: [_]: #FileInfo + + // encodings holds the set of encodings defined for this mode. + encodings!: [_]: #FileInfo } +// modes sets defaults for different operational modes. +// The key corresponds to the Go internal/filetypes.Mode type. +modes: [string]: #Mode + // input defines modes for input, such as import, eval, vet or def. // In input mode, settings flags are interpreted as what is allowed to occur // in the input. The default settings, therefore, tend to be permissive. modes: input: { - Default: { - encoding: *"cue" | _ - } + // FileInfo holds a value that's unified with the file value. FileInfo: { docs: *true | false attributes: *true | false } + // encodings is unified to the file value when interpretation is empty. encodings: cue: { *forms.schema | _ } + extensions: "-": encoding: *"cue" | _ extensions: ".json": interpretation: *"auto" | _ extensions: ".yaml": interpretation: *"auto" | _ extensions: ".yml": interpretation: *"auto" | _ extensions: ".toml": interpretation: *"auto" | _ + extensions: ".xml": interpretation: *"auto" | _ } modes: export: { - Default: { - encoding: *"json" | _ - } FileInfo: { docs: true | *false attributes: true | *false } encodings: cue: forms.data + extensions: "-": encoding: *"json" | _ } // eval is a legacy mode modes: eval: { - Default: { - encoding: *"cue" | _ - } FileInfo: { docs: true | *false attributes: true | *false } encodings: cue: forms.final + extensions: "-": encoding: *"cue" | _ } modes: def: { - Default: { - encoding: *"cue" | _ - } FileInfo: { docs: *true | false attributes: *true | false } encodings: cue: forms.schema + extensions: "-": encoding: *"cue" | _ } // A Encoding indicates a file format for representing a program. @@ -148,10 +144,26 @@ modes: def: { // It corresponds to the Go cue/build.Form type. #Form: string +all: { + for m in modes { + for name, _ in m.encodings { + encodings: (name): true + } + for name, _ in m.extensions { + extensions: (name): true + } + } + for name, _ in interpretations { + interpretations: (name): true + } + for name, _ in forms { + forms: (name): true + } +} + modes: [string]: { // extensions maps a file extension to its associated default file properties. extensions: { - // "": _ ".cue": tagInfo.cue ".json": tagInfo.json ".jsonl": tagInfo.jsonl @@ -160,6 +172,7 @@ modes: [string]: { ".yaml": tagInfo.yaml ".yml": tagInfo.yaml ".toml": tagInfo.toml + ".xml": tagInfo.xml ".txt": tagInfo.text ".go": tagInfo.go ".wasm": tagInfo.binary @@ -209,6 +222,11 @@ modes: [string]: { stream: false } + encodings: xml: { + forms.data + stream: false + } + encodings: proto: { forms.schema encoding: "proto" @@ -297,7 +315,7 @@ interpretations: jsonschema: { boolTags: { strict: *false | bool strictKeywords: *strict | bool - // TODO(v0.12): enable strictFeatures by default + // TODO: enable strictFeatures by default? (see https://cuelang.org/issue/3923). strictFeatures: *strict | bool } } @@ -317,6 +335,8 @@ interpretations: pb: { stream: true } +tagInfo: [_]: #FileInfo + // tagInfo maps command line tags to file properties. tagInfo: { schema: form: "schema" @@ -324,11 +344,21 @@ tagInfo: { dag: form: "dag" data: form: "data" - cue: encoding: "cue" - json: encoding: "json" - jsonl: encoding: "jsonl" - yaml: encoding: "yaml" - toml: encoding: "toml" + cue: encoding: "cue" + json: encoding: "json" + jsonl: encoding: "jsonl" + yaml: encoding: "yaml" + toml: encoding: "toml" + xml: { + encoding: "xml" + boolTags: { + // We implement XML variants as boolean tags, such that "koala" is not accessible + // as a top-level filetype, and can only be used via "xml+koala". + // These effectively behave like a "one of", but we enforce this via the Go code + // so that we can provide the users with good error messages. + koala: *false | bool + } + } proto: encoding: "proto" textproto: encoding: "textproto" // "binpb": encodings.binproto diff --git a/vendor/cuelang.org/go/internal/filetypes/types.go b/vendor/cuelang.org/go/internal/filetypes/types.go index 22d390c6be..3aaab10e3d 100644 --- a/vendor/cuelang.org/go/internal/filetypes/types.go +++ b/vendor/cuelang.org/go/internal/filetypes/types.go @@ -16,38 +16,18 @@ package filetypes import ( _ "embed" - "fmt" - "sync" - - "cuelang.org/go/cue" - "cuelang.org/go/cue/build" - "cuelang.org/go/cue/cuecontext" ) -//go:embed types.cue -var typesCUE string +//go:generate go tool stringer -type=TagType -linecomment + +type TagType int -var ( - typesValue cue.Value - fileForExt map[string]*build.File - fileForCUE *build.File +const ( + TagUnknown TagType = iota + TagTopLevel + TagSubsidiaryBool + TagSubsidiaryString ) -var typesInit = sync.OnceFunc(func() { - ctx := cuecontext.New() - typesValue = ctx.CompileString(typesCUE, cue.Filename("types.cue")) - if err := typesValue.Err(); err != nil { - panic(err) - } - // Reading a file in input mode with a non-explicit scope is a very - // common operation, so cache the build.File value for all - // the known file extensions. - if err := typesValue.LookupPath(cue.MakePath(cue.Str("fileForExtVanilla"))).Decode(&fileForExt); err != nil { - panic(err) - } - fileForCUE = fileForExt[".cue"] - // Check invariants assumed by FromFile - if fileForCUE.Form != "" || fileForCUE.Interpretation != "" || fileForCUE.Encoding != build.CUE { - panic(fmt.Errorf("unexpected value for CUE file type: %#v", fileForCUE)) - } -}) +// initialized by types_gen.go +var tagTypes map[string]TagType diff --git a/vendor/cuelang.org/go/internal/filetypes/types_gen.go b/vendor/cuelang.org/go/internal/filetypes/types_gen.go new file mode 100644 index 0000000000..02a7b5c8c1 --- /dev/null +++ b/vendor/cuelang.org/go/internal/filetypes/types_gen.go @@ -0,0 +1,446 @@ +// Code generated by cuelang.org/go/pkg/gen. DO NOT EDIT. + +//go:build !cuebootstrap + +package filetypes + +import ( + "cmp" + _ "embed" + "fmt" + "maps" + "slices" + + "cuelang.org/go/cue/build" + "cuelang.org/go/cue/errors" + "cuelang.org/go/cue/token" + "cuelang.org/go/internal/filetypes/internal" + "cuelang.org/go/internal/filetypes/internal/genstruct" + "cuelang.org/go/internal/filetypes/internal/opt" +) + +// TODO use string instead of []byte so that we can +// use the init data directly without copying into +// read-write memory. + +//go:embed fileinfo.dat +var fileInfoDataBytes []byte + +//go:embed fromfile.dat +var fromFileDataBytes []byte + +func init() { + tagTypes = map[string]TagType{ + "auto": TagTopLevel, + "binary": TagTopLevel, + "code": TagTopLevel, + "cue": TagTopLevel, + "dag": TagTopLevel, + "data": TagTopLevel, + "go": TagTopLevel, + "graph": TagTopLevel, + "json": TagTopLevel, + "jsonl": TagTopLevel, + "jsonschema": TagTopLevel, + "koala": TagSubsidiaryBool, + "lang": TagSubsidiaryString, + "openapi": TagTopLevel, + "pb": TagTopLevel, + "proto": TagTopLevel, + "schema": TagTopLevel, + "strict": TagSubsidiaryBool, + "strictFeatures": TagSubsidiaryBool, + "strictKeywords": TagSubsidiaryBool, + "text": TagTopLevel, + "textproto": TagTopLevel, + "toml": TagTopLevel, + "xml": TagTopLevel, + "yaml": TagTopLevel, + } +} + +var ( + allFileExts = []string{ + "-", + ".cue", + ".go", + ".json", + ".jsonl", + ".ldjson", + ".ndjson", + ".proto", + ".textpb", + ".textproto", + ".toml", + ".txt", + ".wasm", + ".xml", + ".yaml", + ".yml", + ".unknown", + "", + } + allFileExts_rev = genstruct.IndexMap(allFileExts) +) +var ( + allTopLevelTags = []string{ + "auto", + "binary", + "code", + "cue", + "dag", + "data", + "go", + "graph", + "json", + "jsonl", + "jsonschema", + "openapi", + "pb", + "proto", + "schema", + "text", + "textproto", + "toml", + "xml", + "yaml", + } + allTopLevelTags_rev = genstruct.IndexMap(allTopLevelTags) +) + +var ( + allEncodings = []build.Encoding{ + "binary", + "binarypb", + "code", + "cue", + "json", + "jsonl", + "proto", + "text", + "textproto", + "toml", + "xml", + "yaml", + "", + } + allEncodings_rev = genstruct.IndexMap(allEncodings) +) +var ( + allInterpretations = []build.Interpretation{ + "auto", + "jsonschema", + "openapi", + "pb", + "", + } + allInterpretations_rev = genstruct.IndexMap(allInterpretations) +) +var ( + allForms = []build.Form{ + "dag", + "data", + "final", + "graph", + "schema", + "", + } + allForms_rev = genstruct.IndexMap(allForms) +) + +func toFileGenerated(mode Mode, sc *scope, filename string) (*build.File, errors.Error) { + key := make([]byte, 5) + genstruct.PutSet(key, 2, 3, allTopLevelTags_rev, maps.Keys(sc.topLevel)) + genstruct.PutEnum(key, 1, 1, allFileExts_rev, 16, fileExt(filename)) + genstruct.PutUint64(key, 0, 1, uint64(mode)) + + data, ok := genstruct.FindRecord(fileInfoDataBytes, 5+6, key) + if !ok { + return nil, errors.Newf(token.NoPos, "invalid tag combination") // TODO what error would be best? + } + + switch e := internal.ErrorKind(genstruct.GetUint64(data, 3, 1)); e { + default: + return nil, errors.Newf(token.NoPos, "unknown filetype error %d", e) + case internal.ErrUnknownFileExtension: + return nil, errors.Newf(token.NoPos, "unknown file extension %s", fileExt(filename)) + case internal.ErrCouldNotDetermineFileType: + return nil, errors.Newf(token.NoPos, "could not determine file type for file %q", filename) + case internal.ErrNoEncodingSpecified: + return nil, errors.Newf(token.NoPos, "no encoding specified for file %q", filename) + case 0: + // no error + } + + var f build.File + f.Filename = filename + f.Encoding = genstruct.GetEnum(data, 0, 1, allEncodings) + f.Interpretation = genstruct.GetEnum(data, 1, 1, allInterpretations) + f.Form = genstruct.GetEnum(data, 2, 1, allForms) + if index := int(genstruct.GetUint64(data, 4, 1)); index > 0 { + tagFunc := subsidiaryTagFuncs[index-1] + var t subsidiaryTags + if err := t.unmarshalFromMap(sc.subsidiaryString); err != nil { + return nil, errors.Promote(err, "") + } + t, err := tagFunc(t) + if err != nil { + return nil, errors.Promote(err, "") + } + f.Tags = t.marshalToMap() + + } else if len(sc.subsidiaryString) > 0 { + return nil, errors.Newf(token.NoPos, "tag %s is not allowed in this context", someKey(sc.subsidiaryString)) + } + if index := int(genstruct.GetUint64(data, 5, 1)); index > 0 { + tagFunc := subsidiaryBoolTagFuncs[index-1] + var t subsidiaryBoolTags + if err := t.unmarshalFromMap(sc.subsidiaryBool); err != nil { + return nil, errors.Promote(err, "") + } + t, err := tagFunc(t) + if err != nil { + return nil, errors.Promote(err, "") + } + f.BoolTags = t.marshalToMap() + } else if len(sc.subsidiaryBool) > 0 { + return nil, errors.Newf(token.NoPos, "tag %s is not allowed in this context", someKey(sc.subsidiaryBool)) + } + + return &f, nil +} + +func fromFileGenerated(b *build.File, mode Mode) (*FileInfo, error) { + key := make([]byte, 4) + genstruct.PutUint64(key, 0, 1, uint64(mode)) + genstruct.PutEnum(key, 1, 1, allEncodings_rev, 12, b.Encoding) + genstruct.PutEnum(key, 2, 1, allInterpretations_rev, 4, b.Interpretation) + genstruct.PutEnum(key, 3, 1, allForms_rev, 5, b.Form) + + data, ok := genstruct.FindRecord(fromFileDataBytes, 4+5, key) + if !ok { + return nil, errors.Newf(token.NoPos, "no encoding specified") + } + fi := &FileInfo{ + Filename: b.Filename, + Encoding: genstruct.GetEnum(data, 0, 1, allEncodings), + Interpretation: genstruct.GetEnum(data, 1, 1, allInterpretations), + Form: genstruct.GetEnum(data, 2, 1, allForms), + } + fi.SetAspects(internal.Aspects(genstruct.GetUint64(data, 3, 2))) + return fi, nil +} + +func someKey[K cmp.Ordered, V any](m map[K]V) K { + return slices.Sorted(maps.Keys(m))[0] +} + +var subsidiaryBoolTagFuncs = []func(subsidiaryBoolTags) (subsidiaryBoolTags, error){ + unifySubsidiaryBoolTags_0, + unifySubsidiaryBoolTags_1, + unifySubsidiaryBoolTags_2, +} + +var subsidiaryTagFuncs = []func(subsidiaryTags) (subsidiaryTags, error){ + unifySubsidiaryTags_0, + unifySubsidiaryTags_1, + unifySubsidiaryTags_2, +} + +type subsidiaryTags struct { + lang opt.Opt[string] +} + +func (t *subsidiaryTags) unmarshalFromMap(m map[string]string) error { + if x, ok := m["lang"]; ok { + t.lang = opt.Some(x) + } + return nil +} +func (t subsidiaryTags) marshalToMap() map[string]string { + m := make(map[string]string) + if t.lang.IsPresent() { + m["lang"] = t.lang.Value() + } + return m +} + +type subsidiaryBoolTags struct { + koala opt.Opt[bool] + strict opt.Opt[bool] + strictFeatures opt.Opt[bool] + strictKeywords opt.Opt[bool] +} + +func (t *subsidiaryBoolTags) unmarshalFromMap(m map[string]bool) error { + if x, ok := m["koala"]; ok { + t.koala = opt.Some(x) + } + if x, ok := m["strict"]; ok { + t.strict = opt.Some(x) + } + if x, ok := m["strictFeatures"]; ok { + t.strictFeatures = opt.Some(x) + } + if x, ok := m["strictKeywords"]; ok { + t.strictKeywords = opt.Some(x) + } + return nil +} +func (t subsidiaryBoolTags) marshalToMap() map[string]bool { + m := make(map[string]bool) + if t.koala.IsPresent() { + m["koala"] = t.koala.Value() + } + if t.strict.IsPresent() { + m["strict"] = t.strict.Value() + } + if t.strictFeatures.IsPresent() { + m["strictFeatures"] = t.strictFeatures.Value() + } + if t.strictKeywords.IsPresent() { + m["strictKeywords"] = t.strictKeywords.Value() + } + return m +} + +// unifySubsidiaryTags_0 unifies subsidiaryTags values according to the following CUE logic: +// +// { +// { +// [string]: string +// } +// lang: "go" +// } +func unifySubsidiaryTags_0(t subsidiaryTags) (subsidiaryTags, error) { + var r subsidiaryTags + r.lang = opt.Some("go") + if t.lang.IsPresent() && t.lang.Value() != r.lang.Value() { + return subsidiaryTags{}, fmt.Errorf("conflict on lang; %#v provided but need %#v", t.lang.Value(), r.lang.Value()) + } + return r, nil +} + +// unifySubsidiaryTags_2 unifies subsidiaryTags values according to the following CUE logic: +// +// { +// { +// [string]: string +// } +// lang: (*"" | string) & { +// "go" +// } +// } +func unifySubsidiaryTags_2(t subsidiaryTags) (subsidiaryTags, error) { + var r subsidiaryTags + r.lang = opt.Some("go") + if t.lang.IsPresent() && t.lang.Value() != r.lang.Value() { + return subsidiaryTags{}, fmt.Errorf("conflict on lang; %#v provided but need %#v", t.lang.Value(), r.lang.Value()) + } + return r, nil +} + +// unifySubsidiaryTags_1 unifies subsidiaryTags values according to the following CUE logic: +// +// { +// { +// [string]: string +// } +// lang: *"" | string +// } +func unifySubsidiaryTags_1(t subsidiaryTags) (subsidiaryTags, error) { + var r subsidiaryTags + r.lang = opt.Some("") + if t.lang.IsPresent() { + r.lang = t.lang + } + return r, nil +} + +// unifySubsidiaryBoolTags_2 unifies subsidiaryBoolTags values according to the following CUE logic: +// +// { +// { +// [string]: bool +// } +// koala: *false | bool +// strict: *false | bool +// strictKeywords: *strict | bool +// strictFeatures: *strict | bool +// } +func unifySubsidiaryBoolTags_2(t subsidiaryBoolTags) (subsidiaryBoolTags, error) { + var r subsidiaryBoolTags + r.koala = opt.Some(false) + if t.koala.IsPresent() { + r.koala = t.koala + } + r.strict = opt.Some(false) + if t.strict.IsPresent() { + r.strict = t.strict + } + r.strictFeatures = r.strict + if t.strictFeatures.IsPresent() { + r.strictFeatures = t.strictFeatures + } + r.strictKeywords = r.strict + if t.strictKeywords.IsPresent() { + r.strictKeywords = t.strictKeywords + } + return r, nil +} + +// unifySubsidiaryBoolTags_0 unifies subsidiaryBoolTags values according to the following CUE logic: +// +// { +// { +// [string]: bool +// } +// koala: *false | bool +// } +func unifySubsidiaryBoolTags_0(t subsidiaryBoolTags) (subsidiaryBoolTags, error) { + var r subsidiaryBoolTags + r.koala = opt.Some(false) + if t.koala.IsPresent() { + r.koala = t.koala + } + if t.strict.IsPresent() { + return subsidiaryBoolTags{}, fmt.Errorf("field %q not allowed", "strict") + } + if t.strictFeatures.IsPresent() { + return subsidiaryBoolTags{}, fmt.Errorf("field %q not allowed", "strictFeatures") + } + if t.strictKeywords.IsPresent() { + return subsidiaryBoolTags{}, fmt.Errorf("field %q not allowed", "strictKeywords") + } + return r, nil +} + +// unifySubsidiaryBoolTags_1 unifies subsidiaryBoolTags values according to the following CUE logic: +// +// { +// { +// [string]: bool +// } +// strict: *false | bool +// strictKeywords: *strict | bool +// strictFeatures: *strict | bool +// } +func unifySubsidiaryBoolTags_1(t subsidiaryBoolTags) (subsidiaryBoolTags, error) { + var r subsidiaryBoolTags + if t.koala.IsPresent() { + return subsidiaryBoolTags{}, fmt.Errorf("field %q not allowed", "koala") + } + r.strict = opt.Some(false) + if t.strict.IsPresent() { + r.strict = t.strict + } + r.strictFeatures = r.strict + if t.strictFeatures.IsPresent() { + r.strictFeatures = t.strictFeatures + } + r.strictKeywords = r.strict + if t.strictKeywords.IsPresent() { + r.strictKeywords = t.strictKeywords + } + return r, nil +} diff --git a/vendor/cuelang.org/go/internal/filetypes/types_gen.go.tmpl b/vendor/cuelang.org/go/internal/filetypes/types_gen.go.tmpl new file mode 100644 index 0000000000..7ab68ed016 --- /dev/null +++ b/vendor/cuelang.org/go/internal/filetypes/types_gen.go.tmpl @@ -0,0 +1,141 @@ +// Code generated by cuelang.org/go/pkg/gen. DO NOT EDIT. + +//go:build !cuebootstrap + +package filetypes + +import ( + _ "embed" + "cmp" + "maps" + "fmt" + "slices" + + "cuelang.org/go/cue/build" + "cuelang.org/go/cue/errors" + "cuelang.org/go/cue/token" + "cuelang.org/go/internal/filetypes/internal" + "cuelang.org/go/internal/filetypes/internal/opt" + "cuelang.org/go/internal/filetypes/internal/genstruct" +) + +// TODO use string instead of []byte so that we can +// use the init data directly without copying into +// read-write memory. + +//go:embed fileinfo.dat +var fileInfoDataBytes []byte + +//go:embed fromfile.dat +var fromFileDataBytes []byte + +func init() { + tagTypes = map[string]TagType{ + {{range $k, $v := .TagTypes}}{{printf "\t%q: %v,\n" $k $v}}{{end}} + } +} + +{{.ToFileParams.GenInit .Generated}} + +{{.ToFileResult.GenInit .Generated}} + +{{.FromFileParams.GenInit .Generated}} + +{{.FromFileResult.GenInit .Generated}} + +func toFileGenerated(mode Mode, sc *scope, filename string) (*build.File, errors.Error) { + key := make([]byte, {{.ToFileParams.Size}}) + {{.ToFileParams.Tags.GenPut "key" "maps.Keys(sc.topLevel)"}} + {{.ToFileParams.FileExt.GenPut "key" "fileExt(filename)"}} + {{.ToFileParams.Mode.GenPut "key" "mode"}} + + data, ok := genstruct.FindRecord(fileInfoDataBytes, {{.ToFileParams.Size}}+{{.ToFileResult.Size}}, key) + if !ok { + return nil, errors.Newf(token.NoPos, "invalid tag combination") // TODO what error would be best? + } + + switch e := {{.ToFileResult.Error.GenGet "data"}}; e { + default: + return nil, errors.Newf(token.NoPos, "unknown filetype error %d", e) + case internal.ErrUnknownFileExtension: + return nil, errors.Newf(token.NoPos, "unknown file extension %s", fileExt(filename)) + case internal.ErrCouldNotDetermineFileType: + return nil, errors.Newf(token.NoPos, "could not determine file type for file %q", filename) + case internal.ErrNoEncodingSpecified: + return nil, errors.Newf(token.NoPos, "no encoding specified for file %q", filename) + case 0: + // no error + } + + var f build.File + f.Filename = filename + f.Encoding = {{.ToFileResult.Encoding.GenGet "data"}} + f.Interpretation = {{.ToFileResult.Interpretation.GenGet "data"}} + f.Form = {{.ToFileResult.Form.GenGet "data"}} + if index := {{.ToFileResult.SubsidiaryTagFuncIndex.GenGet "data"}}; index > 0 { + tagFunc := subsidiaryTagFuncs[index-1] + var t subsidiaryTags + if err := t.unmarshalFromMap(sc.subsidiaryString); err != nil { + return nil, errors.Promote(err, "") + } + t, err := tagFunc(t) + if err != nil { + return nil, errors.Promote(err, "") + } + f.Tags = t.marshalToMap() + + } else if len(sc.subsidiaryString) > 0 { + return nil, errors.Newf(token.NoPos, "tag %s is not allowed in this context", someKey(sc.subsidiaryString)) + } + if index := {{.ToFileResult.SubsidiaryBoolTagFuncIndex.GenGet "data"}}; index > 0 { + tagFunc := subsidiaryBoolTagFuncs[index-1] + var t subsidiaryBoolTags + if err := t.unmarshalFromMap(sc.subsidiaryBool); err != nil { + return nil, errors.Promote(err, "") + } + t, err := tagFunc(t) + if err != nil { + return nil, errors.Promote(err, "") + } + f.BoolTags = t.marshalToMap() + } else if len(sc.subsidiaryBool) > 0 { + return nil, errors.Newf(token.NoPos, "tag %s is not allowed in this context", someKey(sc.subsidiaryBool)) + } + + return &f, nil +} + +func fromFileGenerated(b *build.File, mode Mode) (*FileInfo, error) { + key := make([]byte, {{.FromFileParams.Size}}) + {{.FromFileParams.Mode.GenPut "key" "mode"}} + {{.FromFileParams.Encoding.GenPut "key" "b.Encoding"}} + {{.FromFileParams.Interpretation.GenPut "key" "b.Interpretation"}} + {{.FromFileParams.Form.GenPut "key" "b.Form"}} + + data, ok := genstruct.FindRecord(fromFileDataBytes, {{.FromFileParams.Size}}+{{.FromFileResult.Size}}, key) + if !ok { + return nil, errors.Newf(token.NoPos, "no encoding specified") + } + fi := &FileInfo{ + Filename: b.Filename, + Encoding: {{.FromFileResult.Encoding.GenGet "data"}}, + Interpretation: {{.FromFileResult.Interpretation.GenGet "data"}}, + Form: {{.FromFileResult.Form.GenGet "data"}}, + } + fi.SetAspects({{.FromFileResult.Aspects.GenGet "data"}}) + return fi, nil +} + +func someKey[K cmp.Ordered, V any](m map[K] V) K { + return slices.Sorted(maps.Keys(m))[0] +} + +var subsidiaryBoolTagFuncs = []func(subsidiaryBoolTags) (subsidiaryBoolTags, error) { +{{range .SubsidiaryBoolTagFuncCount}}unifySubsidiaryBoolTags_{{.}}, +{{end}} +} + +var subsidiaryTagFuncs = []func(subsidiaryTags) (subsidiaryTags, error) { +{{range .SubsidiaryTagFuncCount}}unifySubsidiaryTags_{{.}}, +{{end}} +} diff --git a/vendor/cuelang.org/go/internal/filetypes/util.go b/vendor/cuelang.org/go/internal/filetypes/util.go index e40becfd4b..74859b3ed4 100644 --- a/vendor/cuelang.org/go/internal/filetypes/util.go +++ b/vendor/cuelang.org/go/internal/filetypes/util.go @@ -30,20 +30,31 @@ func IsPackage(s string) bool { return false } - // This goes off the assumption that file names may not have a `:` in their - // name in cue. - // A filename must have an extension or be preceded by a qualifier argument. - // So strings of the form foo/bar:baz, where bar is a valid identifier and - // absolute package - if p := strings.LastIndexByte(s, ':'); p > 0 { - if !ast.IsValidIdent(s[p+1:]) { + ip := ast.ParseImportPath(s) + if ip.ExplicitQualifier { + if !ast.IsValidIdent(ip.Qualifier) || strings.Contains(ip.Path, ":") || ip.Path == "-" { + // TODO potentially widen the scope of "file-like" + // paths here to include more invalid package paths? return false } - // For a non-pkg, the part before : may only be lowercase and '+'. - // In addition, a package necessarily must have a slash of some form. - return strings.ContainsAny(s[:p], `/.\`) + // If it's got an explicit qualifier, the path has a colon in + // which isn't generally allowed in CUE file names. + return true + } + if ip.Version != "" { + if strings.Contains(ip.Version, "/") { + // We'll definitely not allow slashes in the version string + // so treat it as a file name. + return false + } + // Looks like an explicit version suffix. + // Deliberately leave the syntax fairly open so that + // we get reasonable error messages when invalid version + // queries are specified. + return true } + // No version and no qualifier. // Assuming we terminate search for packages once a scoped qualifier is // found, we know that any file without an extension (except maybe '-') // is invalid. We can therefore assume it is a package. diff --git a/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_flaky.go b/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_flaky.go deleted file mode 100644 index d5c241857b..0000000000 --- a/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_flaky.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build windows || darwin -// +build windows darwin - -package robustio - -import ( - "errors" - "math/rand" - "os" - "syscall" - "time" -) - -const arbitraryTimeout = 2000 * time.Millisecond - -// retry retries ephemeral errors from f up to an arbitrary timeout -// to work around filesystem flakiness on Windows and Darwin. -func retry(f func() (err error, mayRetry bool)) error { - var ( - bestErr error - lowestErrno syscall.Errno - start time.Time - nextSleep time.Duration = 1 * time.Millisecond - ) - for { - err, mayRetry := f() - if err == nil || !mayRetry { - return err - } - - var errno syscall.Errno - if errors.As(err, &errno) && (lowestErrno == 0 || errno < lowestErrno) { - bestErr = err - lowestErrno = errno - } else if bestErr == nil { - bestErr = err - } - - if start.IsZero() { - start = time.Now() - } else if d := time.Since(start) + nextSleep; d >= arbitraryTimeout { - break - } - time.Sleep(nextSleep) - nextSleep += time.Duration(rand.Int63n(int64(nextSleep))) - } - - return bestErr -} - -// rename is like os.Rename, but retries ephemeral errors. -// -// On Windows it wraps os.Rename, which (as of 2019-06-04) uses MoveFileEx with -// MOVEFILE_REPLACE_EXISTING. -// -// Windows also provides a different system call, ReplaceFile, -// that provides similar semantics, but perhaps preserves more metadata. (The -// documentation on the differences between the two is very sparse.) -// -// Empirical error rates with MoveFileEx are lower under modest concurrency, so -// for now we're sticking with what the os package already provides. -func rename(oldpath, newpath string) (err error) { - return retry(func() (err error, mayRetry bool) { - err = os.Rename(oldpath, newpath) - return err, isEphemeralError(err) - }) -} - -// readFile is like os.ReadFile, but retries ephemeral errors. -func readFile(filename string) ([]byte, error) { - var b []byte - err := retry(func() (err error, mayRetry bool) { - b, err = os.ReadFile(filename) - - // Unlike in rename, we do not retry errFileNotFound here: it can occur - // as a spurious error, but the file may also genuinely not exist, so the - // increase in robustness is probably not worth the extra latency. - return err, isEphemeralError(err) && !errors.Is(err, errFileNotFound) - }) - return b, err -} - -func removeAll(path string) error { - return retry(func() (err error, mayRetry bool) { - err = os.RemoveAll(path) - return err, isEphemeralError(err) - }) -} diff --git a/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_other.go b/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_other.go deleted file mode 100644 index 3a20cac6cf..0000000000 --- a/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_other.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !windows && !darwin -// +build !windows,!darwin - -package robustio - -import ( - "os" -) - -func rename(oldpath, newpath string) error { - return os.Rename(oldpath, newpath) -} - -func readFile(filename string) ([]byte, error) { - return os.ReadFile(filename) -} - -func removeAll(path string) error { - return os.RemoveAll(path) -} - -func isEphemeralError(err error) bool { - return false -} diff --git a/vendor/cuelang.org/go/internal/internal.go b/vendor/cuelang.org/go/internal/internal.go index bb23caf51f..1a0935dc79 100644 --- a/vendor/cuelang.org/go/internal/internal.go +++ b/vendor/cuelang.org/go/internal/internal.go @@ -23,14 +23,12 @@ import ( "bufio" "fmt" "path/filepath" - "slices" "strings" + "unicode/utf8" "github.com/cockroachdb/apd/v3" "cuelang.org/go/cue/ast" - "cuelang.org/go/cue/ast/astutil" - "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" ) @@ -87,27 +85,9 @@ func (c Context) Sqrt(d, x *apd.Decimal) (apd.Condition, error) { return res, err } -// ErrIncomplete can be used by builtins to signal the evaluation was -// incomplete. -var ErrIncomplete = errors.New("incomplete value") - // BaseContext is used as CUE's default context for arbitrary-precision decimals. var BaseContext = Context{*apd.BaseContext.WithPrecision(34)} -// APIVersionSupported is the back version until which deprecated features -// are still supported. -var APIVersionSupported = Version(MinorSupported, PatchSupported) - -const ( - MinorCurrent = 5 - MinorSupported = 4 - PatchSupported = 0 -) - -func Version(minor, patch int) int { - return -1000 + 100*minor + patch -} - // EvaluatorVersion is declared here so it can be used everywhere without import cycles, // but the canonical documentation lives at [cuelang.org/go/cue/cuecontext.EvalVersion]. // @@ -118,6 +98,12 @@ const ( // EvalVersionUnset is the zero value, which signals that no evaluator version is provided. EvalVersionUnset EvaluatorVersion = 0 + // DefaultVersion is a special value as it selects a version depending on the current + // value of CUE_EXPERIMENT. It exists separately to [EvalVersionUnset], even though both + // implement the same version selection logic, so that we can distinguish between + // a user explicitly asking for the default version versus an entirely unset version. + DefaultVersion EvaluatorVersion = -1 // TODO(mvdan): rename to EvalDefault for consistency with cuecontext + // The values below are documented under [cuelang.org/go/cue/cuecontext.EvalVersion]. // We should never change or delete the values below, as they describe all known past versions // which is useful for understanding old debug output. @@ -125,68 +111,29 @@ const ( EvalV2 EvaluatorVersion = 2 EvalV3 EvaluatorVersion = 3 - // The current default and experimental versions. + // The current default, stable, and experimental versions. - DefaultVersion = EvalV2 // TODO(mvdan): rename to EvalDefault for consistency with cuecontext - DevVersion = EvalV3 // TODO(mvdan): rename to EvalExperiment for consistency with cuecontext + StableVersion = EvalV3 // TODO(mvdan): rename to EvalStable for consistency with cuecontext + DevVersion = EvalV3 // TODO(mvdan): rename to EvalExperiment for consistency with cuecontext ) -// ListEllipsis reports the list type and remaining elements of a list. If we -// ever relax the usage of ellipsis, this function will likely change. Using -// this function will ensure keeping correct behavior or causing a compiler -// failure. -func ListEllipsis(n *ast.ListLit) (elts []ast.Expr, e *ast.Ellipsis) { - elts = n.Elts - if n := len(elts); n > 0 { - var ok bool - if e, ok = elts[n-1].(*ast.Ellipsis); ok { - elts = elts[:n-1] - } - } - return elts, e -} - -// Package finds the package declaration from the preamble of a file. -func Package(f *ast.File) *ast.Package { - for _, d := range f.Decls { +// Package finds the package declaration from the preamble of a file, +// returning it, and its index within the file's Decls. +func Package(f *ast.File) (*ast.Package, int) { + for i, d := range f.Decls { switch d := d.(type) { case *ast.CommentGroup: case *ast.Attribute: case *ast.Package: if d.Name == nil { // malformed package declaration - return nil + return nil, -1 } - return d + return d, i default: - return nil - } - } - return nil -} - -func SetPackage(f *ast.File, name string, overwrite bool) { - if pkg := Package(f); pkg != nil { - if !overwrite || pkg.Name.Name == name { - return + return nil, -1 } - ident := ast.NewIdent(name) - astutil.CopyMeta(ident, pkg.Name) - return } - - decls := make([]ast.Decl, len(f.Decls)+1) - k := 0 - for _, d := range f.Decls { - if _, ok := d.(*ast.CommentGroup); ok { - decls[k] = d - k++ - continue - } - break - } - decls[k] = &ast.Package{Name: ast.NewIdent(name)} - copy(decls[k+1:], f.Decls[k:]) - f.Decls = decls + return nil, -1 } // NewComment creates a new CommentGroup from the given text. @@ -211,7 +158,7 @@ func NewComment(isDoc bool, s string) *ast.CommentGroup { buf.WriteString("//") for scanner.Scan() { s := scanner.Text() - n := len([]rune(s)) + 1 + n := utf8.RuneCountInString(s) + 1 if count+n > maxRunesPerLine && count > 3 { cg.List = append(cg.List, &ast.Comment{Text: buf.String()}) count = 3 @@ -232,7 +179,7 @@ func NewComment(isDoc bool, s string) *ast.CommentGroup { func FileComments(f *ast.File) (docs, rest []*ast.CommentGroup) { hasPkg := false - if pkg := Package(f); pkg != nil { + if pkg, _ := Package(f); pkg != nil { hasPkg = true docs = pkg.Comments() } @@ -254,49 +201,6 @@ func FileComments(f *ast.File) (docs, rest []*ast.CommentGroup) { return } -// MergeDocs merges multiple doc comments into one single doc comment. -func MergeDocs(comments []*ast.CommentGroup) []*ast.CommentGroup { - if len(comments) <= 1 || !hasDocComment(comments) { - return comments - } - - comments1 := make([]*ast.CommentGroup, 0, len(comments)) - comments1 = append(comments1, nil) - var docComment *ast.CommentGroup - for _, c := range comments { - switch { - case !c.Doc: - comments1 = append(comments1, c) - case docComment == nil: - docComment = c - default: - docComment.List = append(slices.Clip(docComment.List), &ast.Comment{Text: "//"}) - docComment.List = append(docComment.List, c.List...) - } - } - comments1[0] = docComment - return comments1 -} - -func hasDocComment(comments []*ast.CommentGroup) bool { - for _, c := range comments { - if c.Doc { - return true - } - } - return false -} - -func NewAttr(name, str string) *ast.Attribute { - buf := &strings.Builder{} - buf.WriteByte('@') - buf.WriteString(name) - buf.WriteByte('(') - buf.WriteString(str) - buf.WriteByte(')') - return &ast.Attribute{Text: buf.String()} -} - // ToExpr converts a node to an expression. If it is a file, it will return // it as a struct. If is an expression, it will return it as is. Otherwise // it panics. @@ -397,19 +301,6 @@ func IsRegularField(f *ast.Field) bool { return true } -// ConstraintToken reports which constraint token (? or !) is associated -// with a field (if any), taking into account compatibility of deprecated -// fields. -func ConstraintToken(f *ast.Field) (t token.Token, ok bool) { - if f.Constraint != token.ILLEGAL { - return f.Constraint, true - } - if f.Optional != token.NoPos { - return token.OPTION, true - } - return f.Constraint, false -} - // SetConstraints sets both the main and deprecated fields of f according to the // given constraint token. func SetConstraint(f *ast.Field, t token.Token) { @@ -421,53 +312,7 @@ func SetConstraint(f *ast.Field, t token.Token) { } } -func EmbedStruct(s *ast.StructLit) *ast.EmbedDecl { - e := &ast.EmbedDecl{Expr: s} - if len(s.Elts) == 1 { - d := s.Elts[0] - astutil.CopyPosition(e, d) - ast.SetRelPos(d, token.NoSpace) - astutil.CopyComments(e, d) - ast.SetComments(d, nil) - if f, ok := d.(*ast.Field); ok { - ast.SetRelPos(f.Label, token.NoSpace) - } - } - s.Lbrace = token.Newline.Pos() - s.Rbrace = token.NoSpace.Pos() - return e -} - -// IsEllipsis reports whether the declaration can be represented as an ellipsis. -func IsEllipsis(x ast.Decl) bool { - // ... - if _, ok := x.(*ast.Ellipsis); ok { - return true - } - - // [string]: _ or [_]: _ - f, ok := x.(*ast.Field) - if !ok { - return false - } - v, ok := f.Value.(*ast.Ident) - if !ok || v.Name != "_" { - return false - } - l, ok := f.Label.(*ast.ListLit) - if !ok || len(l.Elts) != 1 { - return false - } - i, ok := l.Elts[0].(*ast.Ident) - if !ok { - return false - } - return i.Name == "string" || i.Name == "_" -} - // GenPath reports the directory in which to store generated files. func GenPath(root string) string { return filepath.Join(root, "cue.mod", "gen") } - -var ErrInexact = errors.New("inexact subsumption") diff --git a/vendor/cuelang.org/go/internal/iterutil/iter.go b/vendor/cuelang.org/go/internal/iterutil/iter.go new file mode 100644 index 0000000000..991678b897 --- /dev/null +++ b/vendor/cuelang.org/go/internal/iterutil/iter.go @@ -0,0 +1,25 @@ +// Copyright 2025 CUE Authors +// +// 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. + +package iterutil + +import "iter" + +func Count[E any](seq iter.Seq[E]) int { + n := 0 + for range seq { + n++ + } + return n +} diff --git a/vendor/cuelang.org/go/internal/mod/modfiledata/modfile.go b/vendor/cuelang.org/go/internal/mod/modfiledata/modfile.go new file mode 100644 index 0000000000..bf4de1d333 --- /dev/null +++ b/vendor/cuelang.org/go/internal/mod/modfiledata/modfile.go @@ -0,0 +1,249 @@ +// Copyright 2025 CUE Authors +// +// 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. + +// Package modfiledata holds the underlying module.cue file +// representation. It is separate from the [cuelang.org/go/mod/modfile] +// package to allow the type to be used without incurring the +// dependency on the CUE evaluator brought in by the +// [modfile.Parse] and [modfile.Format] functions. +// +// WARNING: THIS PACKAGE IS EXPERIMENTAL. +// ITS API MAY CHANGE AT ANY TIME. +package modfiledata + +import ( + "fmt" + "path" + "slices" + "strings" + + "cuelang.org/go/cue/ast" + "cuelang.org/go/internal/mod/semver" + "cuelang.org/go/mod/module" +) + +// TODO merge this back into [cuelang.org/go/mod/modfile] when +// we can remove the evaluator dependency from that package. + +// Note that [File] and the types that it depends on are considered +// to be public types even though they are defined in an internal +// package because they are aliased in the [cuelang.org/go/mod/modfile] +// package. + +// File represents the contents of a cue.mod/module.cue file. +// Use [cuelang.org/go/mod/modfile.Parse] to parse the file in +// its standard format. +type File struct { + // Module holds the module path, which may + // not contain a major version suffix. + // Use the [File.QualifiedModule] method to obtain a module + // path that's always qualified. See also the + // [File.ModulePath] and [File.MajorVersion] methods. + Module string `json:"module"` + Language *Language `json:"language,omitempty"` + Source *Source `json:"source,omitempty"` + Deps map[string]*Dep `json:"deps,omitempty"` + Custom map[string]map[string]any `json:"custom,omitempty"` + versions []module.Version + versionByModule map[string]module.Version + + // defaultMajorVersions maps from module base path (the path + // without its major version) to the major version default for that path. + defaultMajorVersions map[string]string +} + +// QualifiedModule returns the fully qualified module path +// if there is one. It returns the empty string when [ParseLegacy] +// has been used and the module field is empty. +// +// Note that when the module field does not contain a major +// version suffix, "@v0" is assumed. +func (f *File) QualifiedModule() string { + if strings.Contains(f.Module, "@") { + return f.Module + } + if f.Module == "" { + return "" + } + return f.Module + "@v0" +} + +// Deprecated: this method is misnamed; use [File.ModuleRootPath] +// instead. +func (f *File) ModulePath() string { + return f.ModuleRootPath() +} + +// ModuleRootPath returns the path part of the module without +// its major version suffix. +func (f *File) ModuleRootPath() string { + path, _, _ := ast.SplitPackageVersion(f.QualifiedModule()) + return path +} + +// Source represents how to transform from a module's +// source to its actual contents. +type Source struct { + Kind string `json:"kind"` +} + +// Validate checks that src is well formed. +func (src *Source) Validate() error { + switch src.Kind { + case "git", "self": + return nil + } + return fmt.Errorf("unrecognized source kind %q", src.Kind) +} + +type Language struct { + Version string `json:"version,omitempty"` +} + +type Dep struct { + Version string `json:"v"` + Default bool `json:"default,omitempty"` +} + +// Init initializes the private dependency-related fields of f from +// the public fields. +func (f *File) Init() error { + return f.init(true) +} + +// InitNonStrict is like [File.Init] but does not enforce full strictness +// in dependencies (for example, it allows dependency module paths +// without major version suffixes). +func (f *File) InitNonStrict() error { + return f.init(false) +} + +func (mf *File) init(strict bool) error { + mainPath, mainMajor, ok := ast.SplitPackageVersion(mf.Module) + if ok { + if semver.Major(mainMajor) != mainMajor { + return fmt.Errorf("module path %s should contain the major version only", mf.Module) + } + } else if mainPath != "" { + if err := module.CheckPathWithoutVersion(mainPath); err != nil { + return fmt.Errorf("module path %q is not valid: %v", mainPath, err) + } + // There's no main module major version: default to v0. + mainMajor = "v0" + } else { + return fmt.Errorf("empty module path") + } + if mf.Language != nil { + vers := mf.Language.Version + if !semver.IsValid(vers) { + return fmt.Errorf("language version %q is not well formed", vers) + } + if semver.Canonical(vers) != vers { + return fmt.Errorf("language version %v is not canonical", vers) + } + } + versionByModule := make(map[string]module.Version) + var versions []module.Version + defaultMajorVersions := make(map[string]string) + if mainPath != "" { + // The main module is always the default for its own major version. + defaultMajorVersions[mainPath] = mainMajor + } + // Check that major versions match dependency versions. + for m, dep := range mf.Deps { + vers, err := module.NewVersion(m, dep.Version) + if err != nil { + return fmt.Errorf("cannot make version from module %q, version %q: %v", m, dep.Version, err) + } + versions = append(versions, vers) + if strict && vers.Path() != m { + return fmt.Errorf("no major version in %q", m) + } + if dep.Default { + mp := vers.BasePath() + if _, ok := defaultMajorVersions[mp]; ok { + return fmt.Errorf("multiple default major versions found for %v", mp) + } + defaultMajorVersions[mp] = semver.Major(vers.Version()) + } + versionByModule[vers.Path()] = vers + } + if mainPath != "" { + // We don't necessarily have a full version for the main module. + mainWithMajor := mainPath + "@" + mainMajor + mainVersion, err := module.NewVersion(mainWithMajor, "") + if err != nil { + return err + } + versionByModule[mainWithMajor] = mainVersion + } + if len(defaultMajorVersions) == 0 { + defaultMajorVersions = nil + } + mf.versions = versions[:len(versions):len(versions)] + slices.SortFunc(mf.versions, module.Version.Compare) + mf.versionByModule = versionByModule + mf.defaultMajorVersions = defaultMajorVersions + return nil +} + +// MajorVersion returns the major version of the module, +// not including the "@". +// If there is no module (which can happen when [ParseLegacy] +// is used or if Module is explicitly set to an empty string), +// it returns the empty string. +func (f *File) MajorVersion() string { + _, vers, _ := ast.SplitPackageVersion(f.QualifiedModule()) + return vers +} + +// DepVersions returns the versions of all the modules depended on by the +// file. The caller should not modify the returned slice. +// +// This always returns the same value, even if the contents +// of f are changed. If f was not created with [Parse], it returns nil. +func (f *File) DepVersions() []module.Version { + return slices.Clip(f.versions) +} + +// DefaultMajorVersions returns a map from module base path +// to the major version that's specified as the default for that module. +// The caller should not modify the returned map. +func (f *File) DefaultMajorVersions() map[string]string { + return f.defaultMajorVersions +} + +// ModuleForImportPath returns the module that should contain the given +// import path and reports whether the module was found. +// It does not check to see if the import path actually exists within the module. +// +// It works entirely from information in f, meaning that it does +// not consult a registry to resolve a package whose module is not +// mentioned in the file, which means it will not work in general unless +// the module is tidy (as with `cue mod tidy`). +func (f *File) ModuleForImportPath(importPath string) (module.Version, bool) { + ip := ast.ParseImportPath(importPath) + for prefix := ip.Path; prefix != "."; prefix = path.Dir(prefix) { + pkgVersion := ip.Version + if pkgVersion == "" { + if pkgVersion = f.defaultMajorVersions[prefix]; pkgVersion == "" { + continue + } + } + if mv, ok := f.versionByModule[prefix+"@"+pkgVersion]; ok { + return mv, true + } + } + return module.Version{}, false +} diff --git a/vendor/cuelang.org/go/internal/mod/modimports/modimports.go b/vendor/cuelang.org/go/internal/mod/modimports/modimports.go index 2f7640ca1d..774f2f7523 100644 --- a/vendor/cuelang.org/go/internal/mod/modimports/modimports.go +++ b/vendor/cuelang.org/go/internal/mod/modimports/modimports.go @@ -4,6 +4,8 @@ import ( "errors" "fmt" "io/fs" + "iter" + "maps" "path" "slices" "strconv" @@ -23,54 +25,49 @@ type ModuleFile struct { // If there's an error, it might not a be CUE file. FilePath string - // Syntax includes only the portion of the file up to and including - // the imports. It will be nil if there was an error reading the file. - Syntax *ast.File + // Syntax (and SyntaxError) are the results from invoking + // [parser.ParseFile] + Syntax *ast.File + SyntaxError error } // AllImports returns a sorted list of all the package paths // imported by the module files produced by modFilesIter // in canonical form. -func AllImports(modFilesIter func(func(ModuleFile, error) bool)) (_ []string, retErr error) { +// +// If the modFilesIter yields an err then AllImports immediately stops +// and returns the accumulated package paths. +func AllImports(modFilesIter iter.Seq2[ModuleFile, error]) ([]string, error) { pkgPaths := make(map[string]bool) - modFilesIter(func(mf ModuleFile, err error) bool { + for mf, err := range modFilesIter { if err != nil { - retErr = fmt.Errorf("cannot read %q: %v", mf.FilePath, err) - return false + return nil, fmt.Errorf("cannot read %q: %v", mf.FilePath, err) } // TODO look at build tags and omit files with "ignore" tags. - for _, imp := range mf.Syntax.Imports { + for imp := range mf.Syntax.ImportSpecs() { pkgPath, err := strconv.Unquote(imp.Path.Value) if err != nil { // TODO location formatting - retErr = fmt.Errorf("invalid import path %q in %s", imp.Path.Value, mf.FilePath) - return false + return nil, fmt.Errorf("invalid import path %q in %s", imp.Path.Value, mf.FilePath) } // Canonicalize the path. - pkgPath = module.ParseImportPath(pkgPath).Canonical().String() + pkgPath = ast.ParseImportPath(pkgPath).Canonical().String() pkgPaths[pkgPath] = true } - return true - }) - if retErr != nil { - return nil, retErr } - // TODO use maps.Keys when we can. - pkgPathSlice := make([]string, 0, len(pkgPaths)) - for p := range pkgPaths { - pkgPathSlice = append(pkgPathSlice, p) - } - slices.Sort(pkgPathSlice) - return pkgPathSlice, nil + return slices.Sorted(maps.Keys(pkgPaths)), nil } // PackageFiles returns an iterator that produces all the CUE files // inside the package with the given name at the given location. // If pkgQualifier is "*", files from all packages in the directory will be produced. // +// The iterator will yield an error if an I/O error is encountered +// when accessing the fsys. +// // TODO(mvdan): this should now be called InstanceFiles, to follow the naming from // https://cuelang.org/docs/concept/modules-packages-instances/#instances. -func PackageFiles(fsys fs.FS, dir string, pkgQualifier string) func(func(ModuleFile, error) bool) { +func PackageFiles(fsys fs.FS, dir string, pkgQualifier string) iter.Seq2[ModuleFile, error] { return func(yield func(ModuleFile, error) bool) { // Start at the target directory, but also include package files // from packages with the same name(s) in parent directories. @@ -110,6 +107,9 @@ func PackageFiles(fsys fs.FS, dir string, pkgQualifier string) func(func(ModuleF // Directories are never package files, even when their filename ends with ".cue". continue } + if isHidden(e.Name()) { + continue + } pkgName, cont := yieldPackageFile(fsys, path.Join(dir, e.Name()), selectPackage, yield) if !cont { return @@ -148,7 +148,7 @@ func PackageFiles(fsys fs.FS, dir string, pkgQualifier string) func(func(ModuleF // module at the given root. // // The caller may assume that files from the same package are always adjacent. -func AllModuleFiles(fsys fs.FS, root string) func(func(ModuleFile, error) bool) { +func AllModuleFiles(fsys fs.FS, root string) iter.Seq2[ModuleFile, error] { return func(yield func(ModuleFile, error) bool) { yieldAllModFiles(fsys, root, true, yield) } @@ -184,6 +184,9 @@ func yieldAllModFiles(fsys fs.FS, fpath string, topDir bool, yield func(ModuleFi if entry.IsDir() { continue } + if isHidden(entry.Name()) { + continue + } fpath := path.Join(fpath, entry.Name()) if _, ok := yieldPackageFile(fsys, fpath, func(string) bool { return true }, yield); !ok { return false @@ -195,7 +198,7 @@ func yieldAllModFiles(fsys fs.FS, fpath string, topDir bool, yield func(ModuleFi if !entry.IsDir() { continue } - if name == "cue.mod" || strings.HasPrefix(name, ".") || strings.HasPrefix(name, "_") { + if name == "cue.mod" || isHidden(name) { continue } fpath := path.Join(fpath, name) @@ -210,6 +213,10 @@ func yieldAllModFiles(fsys fs.FS, fpath string, topDir bool, yield func(ModuleFi // at the given path if selectPackage returns true for the file's // package name. // +// yield is only invoked with a non-nil error if that error originates +// within fsys. In particular, errors from the parser are found via +// the [ModuleFile.SyntaxError] field. +// // It returns the yielded package name (if any) and reports whether // the iteration should continue. func yieldPackageFile(fsys fs.FS, fpath string, selectPackage func(pkgName string) bool, yield func(ModuleFile, error) bool) (pkgName string, cont bool) { @@ -220,15 +227,18 @@ func yieldPackageFile(fsys fs.FS, fpath string, selectPackage func(pkgName strin FilePath: fpath, } var syntax *ast.File - var err error + var syntaxErr error if cueFS, ok := fsys.(module.ReadCUEFS); ok { // The FS implementation supports reading CUE syntax directly. // A notable FS implementation that does this is the one // provided by cue/load, allowing that package to cache // the parsed CUE. - syntax, err = cueFS.ReadCUEFile(fpath) - if err != nil && !errors.Is(err, errors.ErrUnsupported) { - return "", yield(pf, err) + // TODO maybe we should make the options here match + // the default parser options used by cue/load for better + // cache behavior. + syntax, syntaxErr = cueFS.ReadCUEFile(fpath, parser.NewConfig(parser.ImportsOnly)) + if syntax == nil && !errors.Is(syntaxErr, errors.ErrUnsupported) { + return "", yield(pf, syntaxErr) } } if syntax == nil { @@ -253,9 +263,9 @@ func yieldPackageFile(fsys fs.FS, fpath string, selectPackage func(pkgName strin } // Add a leading "./" so that a parse error filename is consistent // with the other error filenames created elsewhere in the codebase. - syntax, err = parser.ParseFile("./"+fpath, data, parser.ImportsOnly) - if err != nil { - return "", yield(pf, err) + syntax, syntaxErr = parser.ParseFile("./"+fpath, data, parser.ImportsOnly) + if syntax == nil { + return "", yield(pf, syntaxErr) } } @@ -263,5 +273,10 @@ func yieldPackageFile(fsys fs.FS, fpath string, selectPackage func(pkgName strin return "", true } pf.Syntax = syntax + pf.SyntaxError = syntaxErr return syntax.PackageName(), yield(pf, nil) } + +func isHidden(name string) bool { + return name == "" || name[0] == '.' || name[0] == '_' +} diff --git a/vendor/cuelang.org/go/internal/mod/modload/query.go b/vendor/cuelang.org/go/internal/mod/modload/query.go index 9895183134..60ad09fa85 100644 --- a/vendor/cuelang.org/go/internal/mod/modload/query.go +++ b/vendor/cuelang.org/go/internal/mod/modload/query.go @@ -7,6 +7,7 @@ import ( "runtime" "sync" + "cuelang.org/go/cue/ast" "cuelang.org/go/internal/mod/modpkgload" "cuelang.org/go/internal/mod/modrequirements" "cuelang.org/go/internal/mod/semver" @@ -55,7 +56,7 @@ func (ld *loader) queryImport(ctx context.Context, pkgPath string, rs *modrequir // It does not return modules that are already present in the given requirements. // It also reports whether a default major version will be required. func (ld *loader) queryLatestModules(ctx context.Context, pkgPath string, rs *modrequirements.Requirements) ([]module.Version, bool, error) { - parts := module.ParseImportPath(pkgPath) + parts := ast.ParseImportPath(pkgPath) latestModuleForPrefix := func(prefix string) (module.Version, error) { mv := parts.Version if mv == "" { @@ -82,7 +83,7 @@ func (ld *loader) queryLatestModules(ctx context.Context, pkgPath string, rs *mo return module.Version{}, err } logf("-> %q", versions) - if v := latestVersion(versions); v != "" { + if v := LatestVersion(versions); v != "" { return module.NewVersion(prefix, v) } return module.Version{}, nil @@ -114,9 +115,9 @@ func (ld *loader) queryLatestModules(ctx context.Context, pkgPath string, rs *mo return candidates, parts.Version == "", queryErr } -// latestVersion returns the latest of any of the given versions, +// LatestVersion returns the latest of any of the given versions, // ignoring prerelease versions if there is any stable version. -func latestVersion(versions []string) string { +func LatestVersion(versions []string) string { maxStable := "" maxAny := "" for _, v := range versions { diff --git a/vendor/cuelang.org/go/internal/mod/modload/tidy.go b/vendor/cuelang.org/go/internal/mod/modload/tidy.go index 6106fb2d0b..ddd4b5a639 100644 --- a/vendor/cuelang.org/go/internal/mod/modload/tidy.go +++ b/vendor/cuelang.org/go/internal/mod/modload/tidy.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io/fs" + "iter" "log" "maps" "path" @@ -156,6 +157,7 @@ func modfileFromRequirements(old *modfile.File, rs *modrequirements.Requirements Language: old.Language, Deps: make(map[string]*modfile.Dep), Source: old.Source, + Custom: old.Custom, } defaults := rs.DefaultMajorVersions() for _, v := range rs.RootModules() { @@ -240,13 +242,10 @@ func (ld *loader) resolveDependencies(ctx context.Context, rootPkgPaths []string logf("dependencies are stable at %q", rs.RootModules()) return rs, pkgs, nil } - toAdd := make([]module.Version, 0, len(modAddedBy)) - // TODO use maps.Keys when we can. for m, p := range modAddedBy { - logf("added: %v (by %v)", modAddedBy, p.ImportPath()) - toAdd = append(toAdd, m) + logf("added: %v (by %v)", m, p.ImportPath()) } - module.Sort(toAdd) // to make errors deterministic + toAdd := slices.SortedFunc(maps.Keys(modAddedBy), module.Version.Compare) // to make errors deterministic oldRs := rs var err error rs, err = ld.updateRoots(ctx, rs, pkgs, toAdd) @@ -408,7 +407,7 @@ func (ld *loader) updateRoots(ctx context.Context, rs *modrequirements.Requireme } } if needSort { - module.Sort(roots) + slices.SortFunc(roots, module.Version.Compare) } // "Each root appears only once, at the selected version of its path ….” @@ -565,10 +564,7 @@ func (ld *loader) resolveMissingImports(ctx context.Context, pkgs *modpkgload.Pa <-work.Idle() modAddedBy = map[module.Version]*modpkgload.Package{} - defaultMajorVersions = make(map[string]string) - for m, v := range rs.DefaultMajorVersions() { - defaultMajorVersions[m] = v - } + defaultMajorVersions = maps.Clone(rs.DefaultMajorVersions()) for _, pm := range pkgMods { pkg, mods, needsDefault := pm.pkg, *pm.mods, *pm.needsDefault for _, mod := range mods { @@ -632,7 +628,7 @@ func (ld *loader) tidyRoots(ctx context.Context, old *modrequirements.Requiremen queue = append(queue, pkg) queued[pkg] = true } - module.Sort(roots) + slices.SortFunc(roots, module.Version.Compare) tidy := modrequirements.NewRequirements(ld.mainModule.Path(), ld.registry, roots, old.DefaultMajorVersions()) for len(queue) > 0 { @@ -664,7 +660,7 @@ func (ld *loader) tidyRoots(ctx context.Context, old *modrequirements.Requiremen } if tidyRoots := tidy.RootModules(); len(roots) > len(tidyRoots) { - module.Sort(roots) + slices.SortFunc(roots, module.Version.Compare) tidy = modrequirements.NewRequirements(ld.mainModule.Path(), ld.registry, roots, tidy.DefaultMajorVersions()) } } @@ -718,15 +714,16 @@ func (ld *loader) spotCheckRoots(ctx context.Context, rs *modrequirements.Requir return true } -func withoutIgnoredFiles(iter func(func(modimports.ModuleFile, error) bool)) func(func(modimports.ModuleFile, error) bool) { +func withoutIgnoredFiles(modFiles iter.Seq2[modimports.ModuleFile, error]) iter.Seq2[modimports.ModuleFile, error] { return func(yield func(modimports.ModuleFile, error) bool) { - // TODO for mf, err := range iter { - iter(func(mf modimports.ModuleFile, err error) bool { + for mf, err := range modFiles { if err == nil && buildattr.ShouldIgnoreFile(mf.Syntax) { - return true + continue } - return yield(mf, err) - }) + if !yield(mf, err) { + break + } + } } } diff --git a/vendor/cuelang.org/go/internal/mod/modload/update.go b/vendor/cuelang.org/go/internal/mod/modload/update.go index 5bc585cb27..5d6d63f2d5 100644 --- a/vendor/cuelang.org/go/internal/mod/modload/update.go +++ b/vendor/cuelang.org/go/internal/mod/modload/update.go @@ -2,16 +2,24 @@ package modload import ( "context" + "errors" "fmt" "io/fs" + "maps" + "path" + "path/filepath" "runtime" + "slices" "strings" "sync/atomic" + "cuelang.org/go/cue/ast" + "cuelang.org/go/internal/mod/modpkgload" "cuelang.org/go/internal/mod/modrequirements" "cuelang.org/go/internal/mod/semver" "cuelang.org/go/internal/par" "cuelang.org/go/mod/modfile" + "cuelang.org/go/mod/modregistry" "cuelang.org/go/mod/module" ) @@ -70,10 +78,8 @@ func UpdateVersions(ctx context.Context, fsys fs.FS, modRoot string, reg Registr newVersions = append(newVersions, v) } } - for _, v := range mversionsMap { - newVersions = append(newVersions, v) - } - module.Sort(newVersions) + newVersions = slices.AppendSeq(newVersions, maps.Values(mversionsMap)) + slices.SortFunc(newVersions, module.Version.Compare) rs = modrequirements.NewRequirements(mf.QualifiedModule(), reg, newVersions, mf.DefaultMajorVersions()) g, err = rs.Graph(ctx) if err != nil { @@ -97,6 +103,160 @@ func UpdateVersions(ctx context.Context, fsys fs.FS, modRoot string, reg Registr return modfileFromRequirements(mf, rs), nil } +// ResolveAbsolutePackage resolves a package in a standalone fashion, irrespective +// of a module file. It returns the module containing that package and the location of the package. +// +// It tries to avoid hitting the network unless necessary by using cached results where available. +func ResolveAbsolutePackage(ctx context.Context, reg Registry, p string) (module.Version, module.SourceLoc, error) { + fail := func(err error) (module.Version, module.SourceLoc, error) { + return module.Version{}, module.SourceLoc{}, err + } + failf := func(format string, args ...interface{}) (module.Version, module.SourceLoc, error) { + return fail(fmt.Errorf(format, args...)) + } + if filepath.IsAbs(p) || path.IsAbs(p) { + return failf("%q is not a package path", p) + } + ip := ast.ParseImportPath(p) + // Before any further lookup, check that the path without the version specifier is valid; + // for example foo.com/bar/@latest would be an example of an invalid path. + ip1 := ip + ip1.Version = "" + if err := module.CheckImportPath(ip1.String()); err != nil { + return fail(err) + } + + tryResolve := func(fetch func(m module.Version) (module.SourceLoc, error)) (module.Version, module.SourceLoc, error) { + locs, err := modpkgload.FindPackageLocations(ctx, p, func(ctx context.Context, prefixPath string) (module.Version, error) { + mv, err := resolveModuleVersion(ctx, reg, nil, prefixPath+"@"+ip.Version) + if errors.Is(err, errNoVersionsFound) { + return module.Version{}, nil + } + return mv, err + }, func(ctx context.Context, m module.Version) (loc module.SourceLoc, isLocal bool, err error) { + loc, err = fetch(m) + if errors.Is(err, modregistry.ErrNotFound) { + err = nil + } + return loc, false, err + }) + if err != nil { + return fail(err) + } + if len(locs) == 1 { + // We've got exactly one cache hit. Use it. + return locs[0].Module, locs[0].Locs[0], nil + } + if len(locs) > 1 { + return fail(&modpkgload.AmbiguousImportError{ImportPath: p, Locations: locs}) + } + return fail(&modpkgload.ImportMissingError{Path: p}) + } + + if reg, ok := reg.(modpkgload.CachedRegistry); ok && ip.Version != "" && semver.Canonical(ip.Version) == ip.Version { + // It's a canonical version and we're using a caching registry implementation. + // We might be able to avoid hitting the network. + mv, loc, err := tryResolve(reg.FetchFromCache) + if err == nil || !errors.As(err, new(*modpkgload.ImportMissingError)) { + return mv, loc, err + } + // Not found in cache. Try again with the non-cached version. + } + return tryResolve(func(m module.Version) (module.SourceLoc, error) { + return reg.Fetch(ctx, m) + }) +} + +var errNoVersionsFound = fmt.Errorf("no versions found") + +// resolveModuleVersion resolves a module/version query to a canonical module version. +// +// The version may take any of the following forms: +// +// $module@v1.2.3 - absolute version. +// $module - latest version +// $module@v1 - latest version at v1 +// $module@v1.2 - latest version within v1.1 +// $module@latest - same as $module +// $module@v1.latest - same as @v1 +// +// If rs is non-nil, it will be used to choose a default major version when no +// major version is specified. +// +// It returns an errNoVersionsFound error if there are no versions for the query but +// all else is OK. +// +// TODO could support queries like <=v1.2.3 etc +func resolveModuleVersion(ctx context.Context, reg Registry, rs *modrequirements.Requirements, v string) (module.Version, error) { + if mv, err := module.ParseVersion(v); err == nil { + // It's already a canonical version; nothing to do. + return mv, nil + } + mpath, vers, ok := strings.Cut(v, "@") + if !ok { + if rs != nil { + if major, status := rs.DefaultMajorVersion(mpath); status == modrequirements.ExplicitDefault { + // TODO allow a non-explicit default too? + vers = major + } + } + if vers == "" { + vers = "latest" + } + } + + if err := module.CheckPathWithoutVersion(mpath); err != nil { + return module.Version{}, fmt.Errorf("%w: invalid module path in %q", errNoVersionsFound, v) + } + versionPrefix := "" + switch { + case vers == "latest": + case strings.HasSuffix(vers, ".latest"): + versionPrefix = strings.TrimSuffix(vers, ".latest") + if !semver.IsValid(versionPrefix) { + return module.Version{}, fmt.Errorf("invalid version specified %q", vers) + } + if semver.Canonical(versionPrefix) == versionPrefix { + // TODO maybe relax this a bit to allow v1.2.3.latest ? + return module.Version{}, fmt.Errorf("cannot use .latest on canonical version %q", vers) + } + default: + if !semver.IsValid(vers) { + return module.Version{}, fmt.Errorf("%q does not specify a valid semantic version", v) + } + if semver.Build(vers) != "" { + return module.Version{}, fmt.Errorf("build version suffixes not supported (%v)", v) + } + // It's a valid version but has no build suffix and it's not canonical, + // which means it must be either a major-only or major-minor, so + // the conforming canonical versions must have it as a prefix, with + // a dot separating the last component and the next. + versionPrefix = vers + "." + } + allVersions, err := reg.ModuleVersions(ctx, mpath) + if err != nil { + return module.Version{}, err + } + possibleVersions := make([]string, 0, len(allVersions)) + for _, v := range allVersions { + if strings.HasPrefix(v, versionPrefix) { + possibleVersions = append(possibleVersions, v) + } + } + if len(possibleVersions) == 0 { + return module.Version{}, fmt.Errorf("%w for module %v", errNoVersionsFound, v) + } + chosen := LatestVersion(possibleVersions) + mv, err := module.NewVersion(mpath, chosen) + if err != nil { + // Should never happen, because we've checked that + // mpath is valid and ModuleVersions + // should always return valid semver versions. + return module.Version{}, err + } + return mv, nil +} + // resolveUpdateVersions resolves a set of version strings as accepted by [UpdateVersions] // into the actual module versions they represent. func resolveUpdateVersions(ctx context.Context, reg Registry, rs *modrequirements.Requirements, mainModuleVersion module.Version, versions []string) ([]module.Version, error) { @@ -107,64 +267,18 @@ func resolveUpdateVersions(ctx context.Context, reg Registry, rs *modrequirement queryErr.CompareAndSwap(nil, &err) } for i, v := range versions { - i, v := i, v if mv, err := module.ParseVersion(v); err == nil { // It's already canonical: nothing more to do. mversions[i] = mv continue } - mpath, vers, ok := strings.Cut(v, "@") - if !ok { - if major, status := rs.DefaultMajorVersion(mpath); status == modrequirements.ExplicitDefault { - // TODO allow a non-explicit default too? - vers = major - } else { - vers = "latest" - } - } - if err := module.CheckPathWithoutVersion(mpath); err != nil { - return nil, fmt.Errorf("invalid module path in %q", v) - } - versionPrefix := "" - if vers != "latest" { - if !semver.IsValid(vers) { - return nil, fmt.Errorf("%q does not specify a valid semantic version", v) - } - if semver.Build(vers) != "" { - return nil, fmt.Errorf("build version suffixes not supported (%v)", v) - } - // It's a valid version but has no build suffix and it's not canonical, - // which means it must be either a major-only or major-minor, so - // the conforming canonical versions must have it as a prefix, with - // a dot separating the last component and the next. - versionPrefix = vers + "." - } work.Add(func() { - allVersions, err := reg.ModuleVersions(ctx, mpath) - if err != nil { - setError(err) - return - } - possibleVersions := make([]string, 0, len(allVersions)) - for _, v := range allVersions { - if strings.HasPrefix(v, versionPrefix) { - possibleVersions = append(possibleVersions, v) - } - } - if len(possibleVersions) == 0 { - setError(fmt.Errorf("no versions found for module %s", v)) - return - } - chosen := latestVersion(possibleVersions) - mv, err := module.NewVersion(mpath, chosen) + mv, err := resolveModuleVersion(ctx, reg, rs, v) if err != nil { - // Should never happen, because we've checked that - // mpath is valid and ModuleVersions - // should always return valid semver versions. setError(err) - return + } else { + mversions[i] = mv } - mversions[i] = mv }) } <-work.Idle() diff --git a/vendor/cuelang.org/go/internal/mod/modpkgload/import.go b/vendor/cuelang.org/go/internal/mod/modpkgload/import.go index 6dc51d1f1d..1b430ccffa 100644 --- a/vendor/cuelang.org/go/internal/mod/modpkgload/import.go +++ b/vendor/cuelang.org/go/internal/mod/modpkgload/import.go @@ -5,11 +5,13 @@ import ( "errors" "fmt" "io/fs" + "iter" "path" "path/filepath" "slices" "strings" + "cuelang.org/go/cue/ast" "cuelang.org/go/internal/mod/modrequirements" "cuelang.org/go/mod/module" ) @@ -29,17 +31,22 @@ import ( // If the package is present in exactly one module, importFromModules will // return the module, its root directory, and a list of other modules that // lexically could have provided the package but did not. -func (pkgs *Packages) importFromModules(ctx context.Context, pkgPath string) (m module.Version, pkgLocs []module.SourceLoc, altMods []module.Version, err error) { - fail := func(err error) (module.Version, []module.SourceLoc, []module.Version, error) { - return module.Version{}, []module.SourceLoc(nil), nil, err +func (pkgs *Packages) importFromModules(ctx context.Context, pkgPath string) ( + m module.Version, + mroot module.SourceLoc, + pkgLocs []module.SourceLoc, + err error, +) { + fail := func(err error) (module.Version, module.SourceLoc, []module.SourceLoc, error) { + return module.Version{}, module.SourceLoc{}, nil, err } - failf := func(format string, args ...interface{}) (module.Version, []module.SourceLoc, []module.Version, error) { + failf := func(format string, args ...interface{}) (module.Version, module.SourceLoc, []module.SourceLoc, error) { return fail(fmt.Errorf(format, args...)) } // Note: we don't care about the package qualifier at this point // because any directory with CUE files in counts as a possible // candidate, regardless of what packages are in it. - pathParts := module.ParseImportPath(pkgPath) + pathParts := ast.ParseImportPath(pkgPath) pkgPathOnly := pathParts.Path if filepath.IsAbs(pkgPathOnly) || path.IsAbs(pkgPathOnly) { @@ -54,16 +61,48 @@ func (pkgs *Packages) importFromModules(ctx context.Context, pkgPath string) (m } // Check each module on the build list. - var locs [][]module.SourceLoc - var mods []module.Version + var locs []PackageLoc var mg *modrequirements.ModuleGraph + versionForModule := func(ctx context.Context, prefix string) (module.Version, error) { + var ( + v string + ok bool + ) + pkgVersion := pathParts.Version + if pkgVersion == "" { + if pkgVersion, _ = pkgs.requirements.DefaultMajorVersion(prefix); pkgVersion == "" { + return module.Version{}, nil + } + } + prefixPath := prefix + "@" + pkgVersion + // Note: mg is nil the first time around the loop. + if mg == nil { + v, ok = pkgs.requirements.RootSelected(prefixPath) + } else { + v, ok = mg.Selected(prefixPath), true + } + if !ok || v == "none" { + // No possible module + return module.Version{}, nil + } + m, err := module.NewVersion(prefixPath, v) + if err != nil { + // Not all package paths are valid module versions, + // but a parent might be. + return module.Version{}, nil + } + return m, nil + } localPkgLocs, err := pkgs.findLocalPackage(pkgPathOnly) if err != nil { return fail(err) } if len(localPkgLocs) > 0 { - mods = append(mods, module.MustNewVersion("local", "")) - locs = append(locs, localPkgLocs) + locs = append(locs, PackageLoc{ + Module: module.MustNewVersion("local", ""), + ModuleRoot: pkgs.mainModuleLoc, + Locs: localPkgLocs, + }) } // Iterate over possible modules for the path, not all selected modules. @@ -80,67 +119,27 @@ func (pkgs *Packages) importFromModules(ctx context.Context, pkgPath string) (m // to load the package using the full // requirements in mg. for { - var altMods []module.Version - // TODO we could probably do this loop concurrently. - - for prefix := pkgPathOnly; prefix != "."; prefix = path.Dir(prefix) { - var ( - v string - ok bool - ) - pkgVersion := pathParts.Version - if pkgVersion == "" { - if pkgVersion, _ = pkgs.requirements.DefaultMajorVersion(prefix); pkgVersion == "" { - continue - } - } - prefixPath := prefix + "@" + pkgVersion - if mg == nil { - v, ok = pkgs.requirements.RootSelected(prefixPath) - } else { - v, ok = mg.Selected(prefixPath), true - } - if !ok || v == "none" { - continue - } - m, err := module.NewVersion(prefixPath, v) - if err != nil { - // Not all package paths are valid module versions, - // but a parent might be. - continue - } - mloc, isLocal, err := pkgs.fetch(ctx, m) - if err != nil { - // Report fetch error. - // Note that we don't know for sure this module is necessary, - // but it certainly _could_ provide the package, and even if we - // continue the loop and find the package in some other module, - // we need to look at this module to make sure the import is - // not ambiguous. - return fail(fmt.Errorf("cannot fetch %v: %v", m, err)) - } - if loc, ok, err := locInModule(pkgPathOnly, prefix, mloc, isLocal); err != nil { - return fail(fmt.Errorf("cannot find package: %v", err)) - } else if ok { - mods = append(mods, m) - locs = append(locs, []module.SourceLoc{loc}) - } else { - altMods = append(altMods, m) - } + // Note: if fetch fails, we return an error: + // we don't know for sure this module is necessary, + // but it certainly _could_ provide the package, and even if we + // continue the loop and find the package in some other module, + // we need to look at this module to make sure the import is + // not ambiguous. + plocs, err := FindPackageLocations(ctx, pkgPath, versionForModule, pkgs.fetch) + if err != nil { + return fail(err) } - - if len(mods) > 1 { + locs = append(locs, plocs...) + if len(locs) > 1 { // We produce the list of directories from longest to shortest candidate // module path, but the AmbiguousImportError should report them from // shortest to longest. Reverse them now. - slices.Reverse(mods) slices.Reverse(locs) - return fail(&AmbiguousImportError{ImportPath: pkgPath, Locations: locs, Modules: mods}) + return fail(&AmbiguousImportError{ImportPath: pkgPath, Locations: locs}) } - - if len(mods) == 1 { + if len(locs) == 1 { // We've found the unique module containing the package. - return mods[0], locs[0], altMods, nil + return locs[0].Module, locs[0].ModuleRoot, locs[0].Locs, nil } if mg != nil { @@ -162,18 +161,83 @@ func (pkgs *Packages) importFromModules(ctx context.Context, pkgPath string) (m } } -// locInModule returns the location that would hold the package named by the given path, -// if it were in the module with module path mpath and root location mloc. -// If pkgPath is syntactically not within mpath, -// or if mdir is a local file tree (isLocal == true) and the directory -// that would hold path is in a sub-module (covered by a go.mod below mdir), +// PackageLoc holds a module version and the module root location, and a location of a package +// within that module. +type PackageLoc struct { + Module module.Version + ModuleRoot module.SourceLoc + // Locs holds the source locations of the package. There is always + // at least one element; there can be more than one when the + // module path is "local" (for exampe packages inside cue.mod/pkg). + Locs []module.SourceLoc +} + +// FindPackageLocations finds possible module candidates for a given import path. +// +// It tries each parent of the import path as a possible module location, +// using versionForModule to determine a version for that module +// and fetch to fetch the location for a given module version. +// +// versionForModule may indicate that there is no possible module +// for a given path by returning the zero version and a nil error. +// +// The fetch function also reports whether the location is "local" +// to the current module, allowing some checks to be skipped when false. +// +// It returns possible locations for the package. Each location may or may +// not contain the package itself, although it will hold some CUE files. +func FindPackageLocations( + ctx context.Context, + importPath string, + versionForModule func(ctx context.Context, prefixPath string) (module.Version, error), + fetch func(ctx context.Context, m module.Version) (loc module.SourceLoc, isLocal bool, err error), +) ([]PackageLoc, error) { + ip := ast.ParseImportPath(importPath) + var locs []PackageLoc + for prefix := range pathAncestors(ip.Path) { + v, err := versionForModule(ctx, prefix) + if err != nil { + return nil, err + } + if !v.IsValid() { + continue + } + mloc, isLocal, err := fetch(ctx, v) + if err != nil { + return nil, fmt.Errorf("cannot fetch %v: %w", v, err) + } + if mloc.FS == nil { + // Not found but not an error. + continue + } + loc, ok, err := locInModule(ip.Path, prefix, mloc, isLocal) + if err != nil { + return nil, fmt.Errorf("cannot find package: %v", err) + } + if ok { + locs = append(locs, PackageLoc{ + Module: v, + ModuleRoot: mloc, + Locs: []module.SourceLoc{loc}, + }) + } + } + return locs, nil +} + +// locInModule returns the location that would hold the package named by +// the given path, if it were in the module with module path mpath and +// root location mloc. If pkgPath is syntactically not within mpath, or +// if mdir is a local file tree (isLocal == true) and the directory that +// would hold path is in a sub-module (covered by a cue.mod below mdir), // locInModule returns "", false, nil. // -// Otherwise, locInModule returns the name of the directory where -// CUE source files would be expected, along with a boolean indicating -// whether there are in fact CUE source files in that directory. -// A non-nil error indicates that the existence of the directory and/or -// source files could not be determined, for example due to a permission error. +// Otherwise, locInModule returns the name of the directory where CUE +// source files would be expected, along with a boolean indicating +// whether there are in fact CUE source files in that directory. A +// non-nil error indicates that the existence of the directory and/or +// source files could not be determined, for example due to a permission +// error. func locInModule(pkgPath, mpath string, mloc module.SourceLoc, isLocal bool) (loc module.SourceLoc, haveCUEFiles bool, err error) { loc.FS = mloc.FS @@ -278,44 +342,48 @@ func (pkgs *Packages) fetch(ctx context.Context, mod module.Version) (loc module if mod == pkgs.mainModuleVersion { return pkgs.mainModuleLoc, true, nil } - loc, err = pkgs.registry.Fetch(ctx, mod) return loc, false, err } +// pathAncestors returns an iterator over all the ancestors +// of p, including p itself. +func pathAncestors(p string) iter.Seq[string] { + return func(yield func(s string) bool) { + for { + if !yield(p) { + return + } + prev := p + p = path.Dir(p) + if p == "." || p == prev { + return + } + } + } +} + // An AmbiguousImportError indicates an import of a package found in multiple // modules in the build list, or found in both the main module and its vendor // directory. type AmbiguousImportError struct { ImportPath string - Locations [][]module.SourceLoc - Modules []module.Version // Either empty or 1:1 with Dirs. + Locations []PackageLoc } func (e *AmbiguousImportError) Error() string { - locType := "modules" - if len(e.Modules) == 0 { - locType = "locations" - } - var buf strings.Builder - fmt.Fprintf(&buf, "ambiguous import: found package %s in multiple %s:", e.ImportPath, locType) + fmt.Fprintf(&buf, "ambiguous import: found package %s in multiple locations:", e.ImportPath) - for i, loc := range e.Locations { + for _, loc := range e.Locations { buf.WriteString("\n\t") - if i < len(e.Modules) { - m := e.Modules[i] - buf.WriteString(m.Path()) - if m.Version() != "" { - fmt.Fprintf(&buf, " %s", m.Version()) - } - // TODO work out how to present source locations in error messages. - fmt.Fprintf(&buf, " (%s)", loc[0].Dir) - } else { - buf.WriteString(loc[0].Dir) + buf.WriteString(loc.Module.Path()) + if v := loc.Module.Version(); v != "" { + fmt.Fprintf(&buf, " %s", v) } + // TODO work out how to present source locations in error messages. + fmt.Fprintf(&buf, " (%s)", loc.Locs[0].Dir) } - return buf.String() } diff --git a/vendor/cuelang.org/go/internal/mod/modpkgload/pkgload.go b/vendor/cuelang.org/go/internal/mod/modpkgload/pkgload.go index 15d936035e..7d01157b47 100644 --- a/vendor/cuelang.org/go/internal/mod/modpkgload/pkgload.go +++ b/vendor/cuelang.org/go/internal/mod/modpkgload/pkgload.go @@ -4,11 +4,13 @@ import ( "context" "fmt" "io/fs" + "maps" "runtime" "slices" "strings" "sync/atomic" + "cuelang.org/go/cue/ast" "cuelang.org/go/internal/mod/modimports" "cuelang.org/go/internal/mod/modrequirements" "cuelang.org/go/internal/par" @@ -19,9 +21,21 @@ import ( type Registry interface { // Fetch returns the location of the contents for the given module // version, downloading it if necessary. + // It returns an error that satisfies [errors.Is]([modregistry.ErrNotFound]) if the + // module is not present in the store at this version. Fetch(ctx context.Context, m module.Version) (module.SourceLoc, error) } +// CachedRegistry is optionally implemented by a registry that +// implements a cache. +type CachedRegistry interface { + // FetchFromCache looks up the given module in the cache. + // It returns an error that satisfies [errors.Is]([modregistry.ErrNotFound]) if the + // module is not present in the cache at this version or if there + // is no cache. + FetchFromCache(mv module.Version) (module.SourceLoc, error) +} + // Flags is a set of flags tracking metadata about a package. type Flags int8 @@ -95,13 +109,14 @@ type Package struct { flags atomicLoadPkgFlags // Populated by [loader.load]. - mod module.Version // module providing package + mod module.Version // module providing package + modRoot module.SourceLoc // root location of module + files []modimports.ModuleFile locs []module.SourceLoc // location of source code directories err error // error loading package imports []*Package // packages imported by this one inStd bool fromExternal bool - altMods []module.Version // modules that could have contained the package but did not // Populated by postprocessing in [Packages.buildStacks]: stack *Package // package importing this one in minimal import stack for this pkg @@ -115,10 +130,18 @@ func (pkg *Package) FromExternalModule() bool { return pkg.fromExternal } +func (pkg *Package) IsStdlibPackage() bool { + return pkg.inStd +} + func (pkg *Package) Locations() []module.SourceLoc { return pkg.locs } +func (pkg *Package) Files() []modimports.ModuleFile { + return pkg.files +} + func (pkg *Package) Error() error { return pkg.err } @@ -143,6 +166,10 @@ func (pkg *Package) Mod() module.Version { return pkg.mod } +func (pkg *Package) ModRoot() module.SourceLoc { + return pkg.modRoot +} + // LoadPackages loads information about all the given packages and the // packages they import, recursively, using modules from the given // requirements to determine which modules they might be obtained from, @@ -164,6 +191,9 @@ func LoadPackages( rootPkgPaths []string, shouldIncludePkgFile func(pkgPath string, mod module.Version, fsys fs.FS, mf modimports.ModuleFile) bool, ) *Packages { + if shouldIncludePkgFile == nil { + shouldIncludePkgFile = func(pkgPath string, mod module.Version, fsys fs.FS, mf modimports.ModuleFile) bool { return true } + } pkgs := &Packages{ mainModuleVersion: module.MustNewVersion(mainModulePath, ""), mainModuleLoc: mainModuleLoc, @@ -248,15 +278,15 @@ func (pkgs *Packages) load(ctx context.Context, pkg *Package) { pkg.inStd = true return } - pkg.fromExternal = pkg.mod != pkgs.mainModuleVersion - pkg.mod, pkg.locs, pkg.altMods, pkg.err = pkgs.importFromModules(ctx, pkg.path) + pkg.mod, pkg.modRoot, pkg.locs, pkg.err = pkgs.importFromModules(ctx, pkg.path) if pkg.err != nil { return } + pkg.fromExternal = pkg.mod != pkgs.mainModuleVersion if pkgs.mainModuleVersion.Path() == pkg.mod.Path() { pkgs.applyPkgFlags(pkg, PkgInAll) } - ip := module.ParseImportPath(pkg.path) + ip := ast.ParseImportPath(pkg.path) pkgQual := ip.Qualifier switch pkgQual { case "": @@ -274,6 +304,7 @@ func (pkgs *Packages) load(ctx context.Context, pkg *Package) { importsMap := make(map[string]bool) foundPackageFile := false excludedPackageFiles := 0 + var files []modimports.ModuleFile for _, loc := range pkg.locs { // Layer an iterator whose yield function keeps track of whether we have seen // a single valid CUE file in the package directory. @@ -290,6 +321,7 @@ func (pkgs *Packages) load(ctx context.Context, pkg *Package) { return true } foundPackageFile = true + files = append(files, mf) return yield(mf, err) }) } @@ -310,11 +342,9 @@ func (pkgs *Packages) load(ctx context.Context, pkg *Package) { } return } - imports := make([]string, 0, len(importsMap)) - for imp := range importsMap { - imports = append(imports, imp) - } - slices.Sort(imports) // Make the algorithm deterministic for tests. + pkg.files = files + // Make the algorithm deterministic for tests. + imports := slices.Sorted(maps.Keys(importsMap)) pkg.imports = make([]*Package, 0, len(imports)) var importFlags Flags diff --git a/vendor/cuelang.org/go/internal/mod/modrequirements/requirements.go b/vendor/cuelang.org/go/internal/mod/modrequirements/requirements.go index c62347da88..66640d1344 100644 --- a/vendor/cuelang.org/go/internal/mod/modrequirements/requirements.go +++ b/vendor/cuelang.org/go/internal/mod/modrequirements/requirements.go @@ -8,6 +8,7 @@ import ( "sync" "sync/atomic" + "cuelang.org/go/cue/ast" "cuelang.org/go/internal/mod/mvs" "cuelang.org/go/internal/mod/semver" "cuelang.org/go/internal/par" @@ -128,7 +129,7 @@ func (rs *Requirements) initDefaultMajorVersions(defaultMajorVersions map[string rs.origDefaultMajorVersions = defaultMajorVersions rs.defaultMajorVersions = make(map[string]majorVersionDefault) for mpath, v := range defaultMajorVersions { - if _, _, ok := module.SplitPathVersion(mpath); ok { + if _, _, ok := ast.SplitPackageVersion(mpath); ok { panic(fmt.Sprintf("NewRequirements called with major version in defaultMajorVersions %q", mpath)) } if semver.Major(v) != v { diff --git a/vendor/cuelang.org/go/internal/mod/modresolve/resolve.go b/vendor/cuelang.org/go/internal/mod/modresolve/resolve.go index 60253eb476..501d304cc3 100644 --- a/vendor/cuelang.org/go/internal/mod/modresolve/resolve.go +++ b/vendor/cuelang.org/go/internal/mod/modresolve/resolve.go @@ -288,8 +288,8 @@ func ParseCUERegistry(s string, catchAllDefault string) (LocationResolver, error cfg := config{ ModuleRegistries: make(map[string]*registryConfig), } - parts := strings.Split(s, ",") - for _, part := range parts { + parts := strings.SplitSeq(s, ",") + for part := range parts { key, val, ok := strings.Cut(part, "=") if !ok { if part == "" { diff --git a/vendor/cuelang.org/go/internal/mod/mvs/mvs.go b/vendor/cuelang.org/go/internal/mod/mvs/mvs.go index 4003b71bd6..b1499e9619 100644 --- a/vendor/cuelang.org/go/internal/mod/mvs/mvs.go +++ b/vendor/cuelang.org/go/internal/mod/mvs/mvs.go @@ -257,8 +257,7 @@ func Req[V comparable](mainModule V, base []string, reqs Reqs[V]) ([]V, error) { haveBase[path] = true } // Now the reverse postorder to bring in anything else. - for i := len(postorder) - 1; i >= 0; i-- { - m := postorder[i] + for _, m := range slices.Backward(postorder) { if max[reqs.Path(m)] != reqs.Version(m) { // Older version. continue @@ -298,7 +297,7 @@ func Upgrade[V comparable](target V, reqs UpgradeReqs[V], upgrade ...V) ([]V, er for _, m := range list { pathInList[reqs.Path(m)] = true } - list = append([]V(nil), list...) + list = slices.Clone(list) upgradeTo := make(map[string]string, len(upgrade)) for _, u := range upgrade { diff --git a/vendor/cuelang.org/go/internal/mod/semver/semver.go b/vendor/cuelang.org/go/internal/mod/semver/semver.go index 0d33ac41cf..7450d2c6b2 100644 --- a/vendor/cuelang.org/go/internal/mod/semver/semver.go +++ b/vendor/cuelang.org/go/internal/mod/semver/semver.go @@ -295,20 +295,10 @@ func isNum(v string) bool { } func compareInt(x, y string) int { - if x == y { - return 0 - } - if len(x) < len(y) { - return -1 - } - if len(x) > len(y) { - return +1 - } - if x < y { - return -1 - } else { - return +1 + if c := cmp.Compare(len(x), len(y)); c != 0 { + return c } + return cmp.Compare(x, y) } func comparePrerelease(x, y string) int { @@ -352,18 +342,11 @@ func comparePrerelease(x, y string) int { } } if ix { - if len(dx) < len(dy) { - return -1 + if c := cmp.Compare(len(dx), len(dy)); c != 0 { + return c } - if len(dx) > len(dy) { - return +1 - } - } - if dx < dy { - return -1 - } else { - return +1 } + return cmp.Compare(dx, dy) } } if x == "" { diff --git a/vendor/cuelang.org/go/internal/par/work.go b/vendor/cuelang.org/go/internal/par/work.go index 4a03e89be9..61b1747d07 100644 --- a/vendor/cuelang.org/go/internal/par/work.go +++ b/vendor/cuelang.org/go/internal/par/work.go @@ -7,7 +7,7 @@ package par import ( "errors" - "math/rand" + "math/rand/v2" "sync" "sync/atomic" ) @@ -93,7 +93,7 @@ func (w *Work[T]) runner() { // to eliminate pathological contention // in case items added at about the same time // are most likely to contend. - i := rand.Intn(len(w.todo)) + i := rand.IntN(len(w.todo)) item := w.todo[i] w.todo[i] = w.todo[len(w.todo)-1] w.todo = w.todo[:len(w.todo)-1] @@ -180,44 +180,3 @@ func (c *Cache[K, V]) Get(key K) (V, bool) { } return e.result, true } - -// Clear removes all entries in the cache. -// -// Concurrent calls to Get may return old values. Concurrent calls to Do -// may return old values or store results in entries that have been deleted. -// -// TODO(jayconrod): Delete this after the package cache clearing functions -// in internal/load have been removed. -func (c *Cache[K, V]) Clear() { - c.m.Range(func(key, value any) bool { - c.m.Delete(key) - return true - }) -} - -// Delete removes an entry from the map. It is safe to call Delete for an -// entry that does not exist. Delete will return quickly, even if the result -// for a key is still being computed; the computation will finish, but the -// result won't be accessible through the cache. -// -// TODO(jayconrod): Delete this after the package cache clearing functions -// in internal/load have been removed. -func (c *Cache[K, V]) Delete(key K) { - c.m.Delete(key) -} - -// DeleteIf calls pred for each key in the map. If pred returns true for a key, -// DeleteIf removes the corresponding entry. If the result for a key is -// still being computed, DeleteIf will remove the entry without waiting for -// the computation to finish. The result won't be accessible through the cache. -// -// TODO(jayconrod): Delete this after the package cache clearing functions -// in internal/load have been removed. -func (c *Cache[K, V]) DeleteIf(pred func(key K) bool) { - c.m.Range(func(key, _ any) bool { - if key := key.(K); pred(key) { - c.Delete(key) - } - return true - }) -} diff --git a/vendor/cuelang.org/go/internal/pkg/builtin.go b/vendor/cuelang.org/go/internal/pkg/builtin.go index 6795df32c2..67ded3e8d8 100644 --- a/vendor/cuelang.org/go/internal/pkg/builtin.go +++ b/vendor/cuelang.org/go/internal/pkg/builtin.go @@ -20,7 +20,6 @@ import ( "cuelang.org/go/cue/errors" "cuelang.org/go/cue/parser" - "cuelang.org/go/internal" "cuelang.org/go/internal/core/adt" "cuelang.org/go/internal/core/compile" "cuelang.org/go/internal/core/convert" @@ -70,7 +69,12 @@ func (p *Package) MustCompile(ctx *adt.OpContext, importPath string) *adt.Vertex if len(p.Native) > 0 { obj.AddConjunct(adt.MakeRootConjunct(nil, st)) } - for _, b := range p.Native { + for _, bref := range p.Native { + // Make a copy of each Builtin object; otherwise concurrent use by separate + // contexts will lead to data races when setting [Builtin.Pkg] below. + // TODO(perf): avoid copying the builtins, e.g. by using a sync.Once. + b := *bref + b.Pkg = pkgLabel f := ctx.StringLabel(b.Name) // never starts with _ @@ -79,7 +83,7 @@ func (p *Package) MustCompile(ctx *adt.OpContext, importPath string) *adt.Vertex if b.Const != "" { v = mustParseConstBuiltin(ctx, b.Name, b.Const) } else { - v = ToBuiltin(b) + v = ToBuiltin(&b) } st.Decls = append(st.Decls, &adt.Field{ Label: f, @@ -126,12 +130,16 @@ func ToBuiltin(b *Builtin) *adt.Builtin { Package: b.Pkg, Name: b.Name, } - x.Func = func(ctx *adt.OpContext, args []adt.Value) (ret adt.Expr) { + x.Func = func(call *adt.CallContext) (ret adt.Expr) { + ctx := call.OpContext() + args := call.Args() + // call, _ := ctx.Source().(*ast.CallExpr) c := &CallCtxt{ - ctx: ctx, - args: args, - builtin: b, + CallContext: call, + ctx: ctx, + args: args, + builtin: b, } defer func() { var errVal interface{} = c.Err @@ -193,7 +201,6 @@ func (x *Builtin) name(ctx *adt.OpContext) string { } func processErr(call *CallCtxt, errVal interface{}, ret adt.Expr) adt.Expr { - ctx := call.ctx switch err := errVal.(type) { case nil: case ValidationError: @@ -229,19 +236,18 @@ func processErr(call *CallCtxt, errVal interface{}, ret adt.Expr) adt.Expr { ret = wrapCallErr(call, &adt.Bottom{Err: err}) case error: - if call.Err == internal.ErrIncomplete { - err := ctx.NewErrf("incomplete value") - err.Code = adt.IncompleteError - ret = err - } else { - // TODO: store the underlying error explicitly - ret = wrapCallErr(call, &adt.Bottom{Err: errors.Promote(err, "")}) - } - default: - // Likely a string passed to panic. + // TODO: store the underlying error explicitly + ret = wrapCallErr(call, &adt.Bottom{Err: errors.Promote(err, "")}) + case string, fmt.Stringer: + // A string or a stringer likely used as a panic value. ret = wrapCallErr(call, &adt.Bottom{ Err: errors.Newf(call.Pos(), "%s", err), }) + default: + // Some other value used when panicking; likely a bug. + ret = wrapCallErr(call, &adt.Bottom{ + Err: errors.Newf(call.Pos(), "BUG: non-stringifiable %T", err), + }) } return ret } diff --git a/vendor/cuelang.org/go/internal/pkg/context.go b/vendor/cuelang.org/go/internal/pkg/context.go index f8e3634152..991767d528 100644 --- a/vendor/cuelang.org/go/internal/pkg/context.go +++ b/vendor/cuelang.org/go/internal/pkg/context.go @@ -28,6 +28,7 @@ import ( // CallCtxt is passed to builtin implementations that need to use a cue.Value. This is an internal type. Its interface may change. type CallCtxt struct { + *adt.CallContext ctx *adt.OpContext builtin *Builtin Err interface{} @@ -50,8 +51,13 @@ func (c *CallCtxt) Do() bool { } // Schema returns the ith argument as is, without converting it to a cue.Value. +// +// TODO: Schema should use CallContext.Expr to capture cycle information. +// However, this only makes sense if functions also use the same OpContext for +// further evaluation. We should enforce as we port the old calls. func (c *CallCtxt) Schema(i int) Schema { - return value.Make(c.ctx, c.args[i]) + v := c.Arg(i) + return value.Make(c.ctx, v) } // Value returns a finalized cue.Value for the ith argument. @@ -103,7 +109,7 @@ func (c *CallCtxt) Int8(i int) int8 { return int8(c.intValue(i, 8, "int8")) } func (c *CallCtxt) Int16(i int) int16 { return int16(c.intValue(i, 16, "int16")) } func (c *CallCtxt) Int32(i int) int32 { return int32(c.intValue(i, 32, "int32")) } func (c *CallCtxt) Rune(i int) rune { return rune(c.intValue(i, 32, "rune")) } -func (c *CallCtxt) Int64(i int) int64 { return int64(c.intValue(i, 64, "int64")) } +func (c *CallCtxt) Int64(i int) int64 { return c.intValue(i, 64, "int64") } func (c *CallCtxt) intValue(i, bits int, typ string) int64 { arg := c.args[i] @@ -126,7 +132,7 @@ func (c *CallCtxt) Uint8(i int) uint8 { return uint8(c.uintValue(i, 8, "uint8" func (c *CallCtxt) Byte(i int) uint8 { return byte(c.uintValue(i, 8, "byte")) } func (c *CallCtxt) Uint16(i int) uint16 { return uint16(c.uintValue(i, 16, "uint16")) } func (c *CallCtxt) Uint32(i int) uint32 { return uint32(c.uintValue(i, 32, "uint32")) } -func (c *CallCtxt) Uint64(i int) uint64 { return uint64(c.uintValue(i, 64, "uint64")) } +func (c *CallCtxt) Uint64(i int) uint64 { return c.uintValue(i, 64, "uint64") } func (c *CallCtxt) uintValue(i, bits int, typ string) uint64 { x := value.Make(c.ctx, c.args[i]) @@ -305,7 +311,8 @@ func (c *CallCtxt) DecimalList(i int) (a []*apd.Decimal) { return nil } - for j, w := range v.Elems() { + j := 0 + for w := range v.Elems() { w.Finalize(c.ctx) // defensive switch x := adt.Unwrap(adt.Default(w.Value())).(type) { case *adt.Num: @@ -333,6 +340,7 @@ func (c *CallCtxt) DecimalList(i int) (a []*apd.Decimal) { c.Err = &callError{err} return nil } + j++ } return a } @@ -343,7 +351,8 @@ func (c *CallCtxt) StringList(i int) (a []string) { return nil } - for j, w := range v.Elems() { + j := 0 + for w := range v.Elems() { w.Finalize(c.ctx) // defensive switch x := adt.Unwrap(adt.Default(w.Value())).(type) { case *adt.String: @@ -371,6 +380,7 @@ func (c *CallCtxt) StringList(i int) (a []string) { c.Err = &callError{err} return nil } + j++ } return a } diff --git a/vendor/cuelang.org/go/internal/pkg/types.go b/vendor/cuelang.org/go/internal/pkg/types.go index 801971bcce..63fc40923b 100644 --- a/vendor/cuelang.org/go/internal/pkg/types.go +++ b/vendor/cuelang.org/go/internal/pkg/types.go @@ -15,6 +15,8 @@ package pkg import ( + "iter" + "cuelang.org/go/cue" "cuelang.org/go/internal/core/adt" ) @@ -31,7 +33,7 @@ type List struct { } // Elems returns the elements of a list. -func (l *List) Elems() []*adt.Vertex { +func (l *List) Elems() iter.Seq[*adt.Vertex] { return l.node.Elems() } @@ -64,17 +66,15 @@ func (s *Struct) Len() int { // IsOpen reports whether s is open or has pattern constraints. func (s *Struct) IsOpen() bool { - if !s.node.IsClosedStruct() { + if s.node.IsOpenStruct() { return true } - // Technically this is not correct, but it is in the context of where - // it is used. + // Check for pattern constraints which indicate openness. if s.node.PatternConstraints != nil && len(s.node.PatternConstraints.Pairs) > 0 { return true } - // The equivalent code for the old implementation. - ot := s.node.OptionalTypes() - return ot&^adt.HasDynamic != 0 + // After removing OptionalTypes, we rely on other checks for openness. + return false } // NumConstraintFields reports the number of explicit optional and required diff --git a/vendor/cuelang.org/go/internal/robustio/doc.go b/vendor/cuelang.org/go/internal/robustio/doc.go new file mode 100644 index 0000000000..74b1fd4895 --- /dev/null +++ b/vendor/cuelang.org/go/internal/robustio/doc.go @@ -0,0 +1,4 @@ +// This directory contains a copy of +// "golang.org/x/tools/internal/robustio", from the commit tagged with +// v0.34.0 (commit 578c1213983a83e6411536ddf6bbf3a1faf97aea) +package robustio diff --git a/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/gopls_windows.go b/vendor/cuelang.org/go/internal/robustio/gopls_windows.go similarity index 100% rename from vendor/cuelang.org/go/internal/golangorgx/tools/robustio/gopls_windows.go rename to vendor/cuelang.org/go/internal/robustio/gopls_windows.go diff --git a/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio.go b/vendor/cuelang.org/go/internal/robustio/robustio.go similarity index 100% rename from vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio.go rename to vendor/cuelang.org/go/internal/robustio/robustio.go diff --git a/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_darwin.go b/vendor/cuelang.org/go/internal/robustio/robustio_darwin.go similarity index 100% rename from vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_darwin.go rename to vendor/cuelang.org/go/internal/robustio/robustio_darwin.go diff --git a/vendor/github.com/rogpeppe/go-internal/robustio/robustio_flaky.go b/vendor/cuelang.org/go/internal/robustio/robustio_flaky.go similarity index 100% rename from vendor/github.com/rogpeppe/go-internal/robustio/robustio_flaky.go rename to vendor/cuelang.org/go/internal/robustio/robustio_flaky.go diff --git a/vendor/cuelang.org/go/internal/robustio/robustio_js.go b/vendor/cuelang.org/go/internal/robustio/robustio_js.go new file mode 100644 index 0000000000..e402432685 --- /dev/null +++ b/vendor/cuelang.org/go/internal/robustio/robustio_js.go @@ -0,0 +1,24 @@ +// Copyright 2025 CUE Authors +// +// 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. + +package robustio + +import ( + "errors" + "time" +) + +func getFileID(filename string) (FileID, time.Time, error) { + return FileID{}, time.Time{}, errors.ErrUnsupported +} diff --git a/vendor/github.com/rogpeppe/go-internal/robustio/robustio_other.go b/vendor/cuelang.org/go/internal/robustio/robustio_other.go similarity index 100% rename from vendor/github.com/rogpeppe/go-internal/robustio/robustio_other.go rename to vendor/cuelang.org/go/internal/robustio/robustio_other.go diff --git a/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_plan9.go b/vendor/cuelang.org/go/internal/robustio/robustio_plan9.go similarity index 93% rename from vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_plan9.go rename to vendor/cuelang.org/go/internal/robustio/robustio_plan9.go index 9fa4cacb5a..d90a2417c6 100644 --- a/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_plan9.go +++ b/vendor/cuelang.org/go/internal/robustio/robustio_plan9.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build plan9 -// +build plan9 - package robustio import ( diff --git a/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_posix.go b/vendor/cuelang.org/go/internal/robustio/robustio_unix.go similarity index 81% rename from vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_posix.go rename to vendor/cuelang.org/go/internal/robustio/robustio_unix.go index 8aa13d0278..9b88c14eb4 100644 --- a/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_posix.go +++ b/vendor/cuelang.org/go/internal/robustio/robustio_unix.go @@ -2,10 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !windows && !plan9 -// +build !windows,!plan9 - -// TODO(adonovan): use 'unix' tag when go1.19 can be assumed. +//go:build unix package robustio diff --git a/vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_windows.go b/vendor/cuelang.org/go/internal/robustio/robustio_windows.go similarity index 100% rename from vendor/cuelang.org/go/internal/golangorgx/tools/robustio/robustio_windows.go rename to vendor/cuelang.org/go/internal/robustio/robustio_windows.go diff --git a/vendor/cuelang.org/go/internal/source/source.go b/vendor/cuelang.org/go/internal/source/source.go index 8ba8c96084..33e367e9aa 100644 --- a/vendor/cuelang.org/go/internal/source/source.go +++ b/vendor/cuelang.org/go/internal/source/source.go @@ -37,15 +37,9 @@ func ReadAll(filename string, src any) ([]byte, error) { return src, nil case *bytes.Buffer: // is io.Reader, but src is already available in []byte form - if src != nil { - return src.Bytes(), nil - } + return src.Bytes(), nil case io.Reader: - var buf bytes.Buffer - if _, err := io.Copy(&buf, src); err != nil { - return nil, err - } - return buf.Bytes(), nil + return io.ReadAll(src) } return nil, fmt.Errorf("invalid source type %T", src) } @@ -63,6 +57,8 @@ func Open(filename string, src any) (io.ReadCloser, error) { return io.NopCloser(strings.NewReader(src)), nil case []byte: return io.NopCloser(bytes.NewReader(src)), nil + case io.ReadCloser: + return src, nil case io.Reader: return io.NopCloser(src), nil } diff --git a/vendor/cuelang.org/go/internal/task/task.go b/vendor/cuelang.org/go/internal/task/task.go index 78885d328c..f70cc4d361 100644 --- a/vendor/cuelang.org/go/internal/task/task.go +++ b/vendor/cuelang.org/go/internal/task/task.go @@ -19,18 +19,22 @@ import ( "context" "io" "sync" + "sync/atomic" "cuelang.org/go/cue" "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" - "cuelang.org/go/internal/core/adt" "cuelang.org/go/internal/value" + "cuelang.org/go/tools/flow" ) // A Context provides context for running a task. type Context struct { Context context.Context + TaskKey func(v cue.Value) (string, error) + + Root cue.Value Stdin io.Reader Stdout io.Writer Stderr io.Writer @@ -90,6 +94,74 @@ func (c *Context) addErr(v cue.Value, wrap error, format string, args ...interfa c.Err = errors.Append(c.Err, errors.Wrap(err, wrap)) } +// ErrLegacy is a sentinel error value that may be returned by a TaskKey +// function to indicate that the task is a legacy task. This will cause the +// configuration value to be passed to the RunnerFunc instead of an empty +// value. +var ErrLegacy error = errors.New("legacy task error") + +// NewTaskFunc creates a flow.TaskFunc that uses global settings from Context +// and a taskKey function to determine the kind of task to run. +func (c Context) TaskFunc(didWork *atomic.Bool) flow.TaskFunc { + return func(v cue.Value) (flow.Runner, error) { + kind, err := c.TaskKey(v) + var isLegacy bool + if err == ErrLegacy { + err = nil + isLegacy = true + } + if err != nil || kind == "" { + return nil, err + } + + didWork.Store(true) + + rf := Lookup(kind) + if rf == nil { + return nil, errors.Newf(v.Pos(), "runner of kind %q not found", kind) + } + + // Verify entry against template. + v = value.UnifyBuiltin(v, kind) + if err := v.Err(); err != nil { + err = v.Validate() + return nil, errors.Promote(err, "newTask") + } + + runner, err := rf(v) + if err != nil { + return nil, errors.Promote(err, "errors running task") + } + + if !isLegacy { + v = cue.Value{} + } + + return c.flowFunc(runner, v), nil + } +} + +// flowFunc takes a Runner and a schema v, which should only be defined for +// legacy task ids. +func (c Context) flowFunc(runner Runner, v cue.Value) flow.RunnerFunc { + return flow.RunnerFunc(func(t *flow.Task) error { + // Set task-specific values. + c.Context = t.Context() + c.Obj = t.Value() + if v.Exists() { + c.Obj = c.Obj.Unify(v) + } + value, err := runner.Run(&c) + if err != nil { + return err + } + if value != nil { + _ = t.Fill(value) + } + return nil + }) +} + // taskError wraps some error values to retain position information about the // error. type taskError struct { @@ -114,12 +186,11 @@ func (t *taskError) Position() token.Pos { func (t *taskError) InputPositions() (a []token.Pos) { _, nx := value.ToInternal(t.v) - nx.VisitLeafConjuncts(func(x adt.Conjunct) bool { + for x := range nx.LeafConjuncts() { if src := x.Source(); src != nil { a = append(a, src.Pos()) } - return true - }) + } return a } diff --git a/vendor/cuelang.org/go/internal/tools.mod b/vendor/cuelang.org/go/internal/tools.mod new file mode 100644 index 0000000000..fe77db5f74 --- /dev/null +++ b/vendor/cuelang.org/go/internal/tools.mod @@ -0,0 +1,17 @@ +// This module exists just so that we can track extra tooling dependencies +// to be used via `go tool` without polluting the main go.mod file. +// TODO(mvdan): once we stabilize on this model, have CI ensure this module is tidy too. +module test/tools + +go 1.24.0 + +tool honnef.co/go/tools/cmd/staticcheck + +require ( + github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect + golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 // indirect + golang.org/x/mod v0.23.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/tools v0.30.0 // indirect + honnef.co/go/tools v0.6.1 // indirect +) diff --git a/vendor/cuelang.org/go/internal/tools.sum b/vendor/cuelang.org/go/internal/tools.sum new file mode 100644 index 0000000000..7843cd99aa --- /dev/null +++ b/vendor/cuelang.org/go/internal/tools.sum @@ -0,0 +1,13 @@ +github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs= +github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678 h1:1P7xPZEwZMoBoz0Yze5Nx2/4pxj6nw9ZqHWXqP0iRgQ= +golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= +golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= +golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +honnef.co/go/tools v0.6.1 h1:R094WgE8K4JirYjBaOpz/AvTyUu/3wbmAoskKN/pxTI= +honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4= diff --git a/vendor/cuelang.org/go/internal/value/value.go b/vendor/cuelang.org/go/internal/value/value.go index 4757b32e96..d7db51503a 100644 --- a/vendor/cuelang.org/go/internal/value/value.go +++ b/vendor/cuelang.org/go/internal/value/value.go @@ -27,11 +27,40 @@ import ( "cuelang.org/go/internal/types" ) -func ConvertToContext[Ctx *cue.Runtime | *cue.Context](ctx Ctx) *cue.Context { - if ctx, ok := any(ctx).(*cue.Runtime); ok { - (*runtime.Runtime)(ctx).Init() +// Context returns the cue.Context of the given argument. +func Context[Ctx *cue.Runtime | *cue.Context | cue.Value | *adt.OpContext](ctx Ctx) *cue.Context { + switch x := any(ctx).(type) { + case *cue.Runtime: + (*runtime.Runtime)(x).Init() + return (*cue.Context)(x) + case *cue.Context: + return x + case cue.Value: + r, _ := ToInternal(x) + return (*cue.Context)(r) + case *adt.OpContext: + r := x.Runtime.(*runtime.Runtime) + return (*cue.Context)(r) } - return (*cue.Context)(ctx) + panic("unreachable") +} + +// OpContext returns an OpContext with proper node formatting initialized. +func OpContext[Ctx *cue.Runtime | *cue.Context | cue.Value](c Ctx) *adt.OpContext { + var r *runtime.Runtime + var v *adt.Vertex + switch x := any(c).(type) { + case *cue.Runtime: + r = (*runtime.Runtime)(x) + r.Init() + case *cue.Context: + r = (*runtime.Runtime)(x) + case cue.Value: + r, v = ToInternal(x) + default: + panic("unreachable") + } + return eval.NewContext(r, v) } func ToInternal(v cue.Value) (*runtime.Runtime, *adt.Vertex) { @@ -40,9 +69,15 @@ func ToInternal(v cue.Value) (*runtime.Runtime, *adt.Vertex) { return t.R, t.V } +func Vertex(v cue.Value) *adt.Vertex { + var t types.Value + v.Core(&t) + return t.V +} + // Make wraps cue.MakeValue. func Make(ctx *adt.OpContext, v adt.Value) cue.Value { - return (*cue.Context)(ctx.Impl().(*runtime.Runtime)).Encode(v) + return Context(ctx).Encode(v) } // UnifyBuiltin returns the given Value unified with the given builtin template. diff --git a/vendor/cuelang.org/go/mod/modcache/cache.go b/vendor/cuelang.org/go/mod/modcache/cache.go index 1723418da4..a648f546a5 100644 --- a/vendor/cuelang.org/go/mod/modcache/cache.go +++ b/vendor/cuelang.org/go/mod/modcache/cache.go @@ -13,8 +13,8 @@ import ( "path/filepath" "github.com/rogpeppe/go-internal/lockedfile" - "github.com/rogpeppe/go-internal/robustio" + "cuelang.org/go/internal/robustio" "cuelang.org/go/mod/module" ) @@ -24,13 +24,13 @@ var errNotCached = fmt.Errorf("not in cache") // returning the name of the cache file and the result. // If the read fails, the caller can use // writeDiskModFile(file, data) to write a new cache entry. -func (c *cache) readDiskModFile(mv module.Version) (file string, data []byte, err error) { +func (c *Cache) readDiskModFile(mv module.Version) (file string, data []byte, err error) { return c.readDiskCache(mv, "mod") } // writeDiskModFile writes a cue.mod/module.cue cache entry. // The file name must have been returned by a previous call to readDiskModFile. -func (c *cache) writeDiskModFile(ctx context.Context, file string, text []byte) error { +func (c *Cache) writeDiskModFile(ctx context.Context, file string, text []byte) error { return c.writeDiskCache(ctx, file, text) } @@ -39,7 +39,7 @@ func (c *cache) writeDiskModFile(ctx context.Context, file string, text []byte) // It returns the name of the cache file and the content of the file. // If the read fails, the caller can use // writeDiskCache(file, data) to write a new cache entry. -func (c *cache) readDiskCache(mv module.Version, suffix string) (file string, data []byte, err error) { +func (c *Cache) readDiskCache(mv module.Version, suffix string) (file string, data []byte, err error) { file, err = c.cachePath(mv, suffix) if err != nil { return "", nil, errNotCached @@ -53,7 +53,7 @@ func (c *cache) readDiskCache(mv module.Version, suffix string) (file string, da // writeDiskCache is the generic "write to a cache file" implementation. // The file must have been returned by a previous call to readDiskCache. -func (c *cache) writeDiskCache(ctx context.Context, file string, data []byte) error { +func (c *Cache) writeDiskCache(ctx context.Context, file string, data []byte) error { if file == "" { return nil } @@ -95,7 +95,7 @@ func (c *cache) writeDiskCache(ctx context.Context, file string, data []byte) er // An error satisfying [errors.Is](err, [fs.ErrNotExist]) will be returned // along with the directory if the directory does not exist or if the directory // is not completely populated. -func (c *cache) downloadDir(m module.Version) (string, error) { +func (c *Cache) downloadDir(m module.Version) (string, error) { if !m.IsCanonical() { return "", fmt.Errorf("non-semver module version %q", m.Version()) } @@ -132,7 +132,7 @@ func (c *cache) downloadDir(m module.Version) (string, error) { return dir, nil } -func (c *cache) cachePath(m module.Version, suffix string) (string, error) { +func (c *Cache) cachePath(m module.Version, suffix string) (string, error) { if !m.IsValid() || m.Version() == "" { return "", fmt.Errorf("non-semver module version %q", m) } @@ -161,7 +161,7 @@ func (e *downloadDirPartialError) Is(err error) bool { return err == fs.ErrNotEx // lockVersion locks a file within the module cache that guards the downloading // and extraction of module data for the given module version. -func (c *cache) lockVersion(mod module.Version) (unlock func(), err error) { +func (c *Cache) lockVersion(mod module.Version) (unlock func(), err error) { path, err := c.cachePath(mod, "lock") if err != nil { return nil, err diff --git a/vendor/cuelang.org/go/mod/modcache/fetch.go b/vendor/cuelang.org/go/mod/modcache/fetch.go index fa167943b5..43630b8b70 100644 --- a/vendor/cuelang.org/go/mod/modcache/fetch.go +++ b/vendor/cuelang.org/go/mod/modcache/fetch.go @@ -7,16 +7,15 @@ import ( "io" "io/fs" "log" - "math/rand" + "math/rand/v2" "os" "path/filepath" + "slices" "strconv" "strings" - "github.com/rogpeppe/go-internal/robustio" - - "cuelang.org/go/internal/mod/modload" "cuelang.org/go/internal/par" + "cuelang.org/go/internal/robustio" "cuelang.org/go/mod/modfile" "cuelang.org/go/mod/modregistry" "cuelang.org/go/mod/module" @@ -33,25 +32,28 @@ const logging = false // TODO hook this up to CUE_DEBUG // returned by the registry implement the `OSRootFS` interface, // allowing a caller to find the native OS filepath where modules // are stored. -func New(registry *modregistry.Client, dir string) (modload.Registry, error) { +// +// The returned type implements [modconfig.Registry] +// and [modconfig.CachedRegistry]. +func New(registry *modregistry.Client, dir string) (*Cache, error) { info, err := os.Stat(dir) if err == nil && !info.IsDir() { return nil, fmt.Errorf("%q is not a directory", dir) } - return &cache{ + return &Cache{ dir: filepath.Join(dir, "mod"), reg: registry, }, nil } -type cache struct { +type Cache struct { dir string // typically ${CUE_CACHE_DIR}/mod reg *modregistry.Client downloadZipCache par.ErrCache[module.Version, string] modFileCache par.ErrCache[string, []byte] } -func (c *cache) Requirements(ctx context.Context, mv module.Version) ([]module.Version, error) { +func (c *Cache) Requirements(ctx context.Context, mv module.Version) ([]module.Version, error) { data, err := c.downloadModFile(ctx, mv) if err != nil { return nil, err @@ -63,9 +65,21 @@ func (c *cache) Requirements(ctx context.Context, mv module.Version) ([]module.V return mf.DepVersions(), nil } +// FetchFromCache implements [cuelang.org/go/mod/modconfig.CachedRegistry]. +func (c *Cache) FetchFromCache(mv module.Version) (module.SourceLoc, error) { + dir, err := c.downloadDir(mv) + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return module.SourceLoc{}, modregistry.ErrNotFound + } + return module.SourceLoc{}, err + } + return c.dirToLocation(dir), nil +} + // Fetch returns the location of the contents for the given module // version, downloading it if necessary. -func (c *cache) Fetch(ctx context.Context, mv module.Version) (module.SourceLoc, error) { +func (c *Cache) Fetch(ctx context.Context, mv module.Version) (module.SourceLoc, error) { dir, err := c.downloadDir(mv) if err == nil { // The directory has already been completely extracted (no .partial file exists). @@ -150,12 +164,12 @@ func (c *cache) Fetch(ctx context.Context, mv module.Version) (module.SourceLoc, } // ModuleVersions implements [modload.Registry.ModuleVersions]. -func (c *cache) ModuleVersions(ctx context.Context, mpath string) ([]string, error) { +func (c *Cache) ModuleVersions(ctx context.Context, mpath string) ([]string, error) { // TODO should this do any kind of short-term caching? return c.reg.ModuleVersions(ctx, mpath) } -func (c *cache) downloadZip(ctx context.Context, mv module.Version) (zipfile string, err error) { +func (c *Cache) downloadZip(ctx context.Context, mv module.Version) (zipfile string, err error) { return c.downloadZipCache.Do(mv, func() (string, error) { zipfile, err := c.cachePath(mv, "zip") if err != nil { @@ -180,7 +194,7 @@ func (c *cache) downloadZip(ctx context.Context, mv module.Version) (zipfile str }) } -func (c *cache) downloadZip1(ctx context.Context, mod module.Version, zipfile string) (err error) { +func (c *Cache) downloadZip1(ctx context.Context, mod module.Version, zipfile string) (err error) { // Double-check that the zipfile was not created while we were waiting for // the lock in downloadZip. if _, err := os.Stat(zipfile); err == nil { @@ -242,7 +256,7 @@ func (c *cache) downloadZip1(ctx context.Context, mod module.Version, zipfile st return nil } -func (c *cache) downloadModFile(ctx context.Context, mod module.Version) ([]byte, error) { +func (c *Cache) downloadModFile(ctx context.Context, mod module.Version) ([]byte, error) { return c.modFileCache.Do(mod.String(), func() ([]byte, error) { modfile, data, err := c.readDiskModFile(mod) if err == nil { @@ -264,7 +278,7 @@ func (c *cache) downloadModFile(ctx context.Context, mod module.Version) ([]byte }) } -func (c *cache) downloadModFile1(ctx context.Context, mod module.Version, modfile string) ([]byte, error) { +func (c *Cache) downloadModFile1(ctx context.Context, mod module.Version, modfile string) ([]byte, error) { m, err := c.reg.GetModule(ctx, mod) if err != nil { return nil, err @@ -279,7 +293,7 @@ func (c *cache) downloadModFile1(ctx context.Context, mod module.Version, modfil return data, nil } -func (c *cache) dirToLocation(fpath string) module.SourceLoc { +func (c *Cache) dirToLocation(fpath string) module.SourceLoc { return module.SourceLoc{ FS: module.OSDirFS(fpath), Dir: ".", @@ -305,8 +319,8 @@ func makeDirsReadOnly(dir string) { }) // Run over list backward to chmod children before parents. - for i := len(dirs) - 1; i >= 0; i-- { - os.Chmod(dirs[i].path, dirs[i].mode&^0222) + for _, dir := range slices.Backward(dirs) { + os.Chmod(dir.path, dir.mode&^0222) } } @@ -346,8 +360,8 @@ func quoteGlob(s string) string { // tempFile creates a new temporary file with given permission bits. func tempFile(ctx context.Context, dir, prefix string, perm fs.FileMode) (f *os.File, err error) { - for i := 0; i < 10000; i++ { - name := filepath.Join(dir, prefix+strconv.Itoa(rand.Intn(1000000000))+".tmp") + for range 10000 { + name := filepath.Join(dir, prefix+strconv.Itoa(rand.IntN(1000000000))+".tmp") f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm) if os.IsExist(err) { if ctx.Err() != nil { diff --git a/vendor/cuelang.org/go/mod/modconfig/modconfig.go b/vendor/cuelang.org/go/mod/modconfig/modconfig.go index 01102451a2..d707b8f918 100644 --- a/vendor/cuelang.org/go/mod/modconfig/modconfig.go +++ b/vendor/cuelang.org/go/mod/modconfig/modconfig.go @@ -9,6 +9,7 @@ import ( "io/fs" "net/http" "os" + "slices" "strings" "sync" @@ -20,6 +21,7 @@ import ( "cuelang.org/go/internal/cueconfig" "cuelang.org/go/internal/cueversion" "cuelang.org/go/internal/mod/modload" + "cuelang.org/go/internal/mod/modpkgload" "cuelang.org/go/internal/mod/modresolve" "cuelang.org/go/mod/modcache" "cuelang.org/go/mod/modregistry" @@ -41,12 +43,24 @@ type Registry interface { ModuleVersions(ctx context.Context, mpath string) ([]string, error) } +// CachedRegistry is optionally implemented by a registry that +// contains a cache. +type CachedRegistry interface { + // FetchFromCache looks up the given module in the cache. + // It returns an error that satisfies [errors.Is]([modregistry.ErrNotFound]) if the + // module is not present in the cache at this version or if there + // is no cache. + FetchFromCache(mv module.Version) (module.SourceLoc, error) +} + // We don't want to make modload part of the cue/load API, // so we define the above type independently, but we want // it to be interchangeable, so check that statically here. var ( - _ Registry = modload.Registry(nil) - _ modload.Registry = Registry(nil) + _ Registry = modload.Registry(nil) + _ modload.Registry = Registry(nil) + _ CachedRegistry = modpkgload.CachedRegistry(nil) + _ modpkgload.CachedRegistry = CachedRegistry(nil) ) // DefaultRegistry is the default registry host. @@ -74,6 +88,12 @@ type Config struct { // the current process's environment will be used. Env []string + // CUERegistry specifies the registry or registries to use + // to resolve modules. If it is empty, $CUE_REGISTRY + // is used. + // Experimental: this field might go away in a future version. + CUERegistry string + // ClientType is used as part of the User-Agent header // that's added in each outgoing HTTP request. // If it's empty, it defaults to "cuelang.org/go". @@ -94,7 +114,10 @@ func NewResolver(cfg *Config) (*Resolver, error) { getenv := getenvFunc(cfg.Env) var configData []byte var configPath string - cueRegistry := getenv("CUE_REGISTRY") + cueRegistry := cfg.CUERegistry + if cueRegistry == "" { + cueRegistry = getenv("CUE_REGISTRY") + } kind, rest, _ := strings.Cut(cueRegistry, ":") switch kind { case "file": @@ -104,7 +127,7 @@ func NewResolver(cfg *Config) (*Resolver, error) { } configData, configPath = data, rest case "inline": - configData, configPath = []byte(rest), "$CUE_REGISTRY" + configData, configPath = []byte(rest), "inline" case "simple": cueRegistry = rest } @@ -116,7 +139,7 @@ func NewResolver(cfg *Config) (*Resolver, error) { resolver, err = modresolve.ParseCUERegistry(cueRegistry, DefaultRegistry) } if err != nil { - return nil, fmt.Errorf("bad value for $CUE_REGISTRY: %v", err) + return nil, fmt.Errorf("bad value for registry: %v", err) } return &Resolver{ resolver: resolver, @@ -350,8 +373,8 @@ func getenvFunc(env []string) func(string) string { return os.Getenv } return func(key string) string { - for i := len(env) - 1; i >= 0; i-- { - if e := env[i]; len(e) >= len(key)+1 && e[len(key)] == '=' && e[:len(key)] == key { + for _, e := range slices.Backward(env) { + if len(e) >= len(key)+1 && e[len(key)] == '=' && e[:len(key)] == key { return e[len(key)+1:] } } diff --git a/vendor/cuelang.org/go/mod/modfile/modfile.go b/vendor/cuelang.org/go/mod/modfile/modfile.go index 3f1a5dff65..f4e814440c 100644 --- a/vendor/cuelang.org/go/mod/modfile/modfile.go +++ b/vendor/cuelang.org/go/mod/modfile/modfile.go @@ -22,12 +22,9 @@ package modfile import ( _ "embed" "fmt" - "slices" "strings" "sync" - "cuelang.org/go/internal/mod/semver" - "cuelang.org/go/cue" "cuelang.org/go/cue/ast" "cuelang.org/go/cue/build" @@ -38,7 +35,8 @@ import ( "cuelang.org/go/internal/cueversion" "cuelang.org/go/internal/encoding" "cuelang.org/go/internal/filetypes" - "cuelang.org/go/mod/module" + "cuelang.org/go/internal/mod/modfiledata" + "cuelang.org/go/internal/mod/semver" ) //go:embed schema.cue @@ -46,61 +44,17 @@ var moduleSchemaData string const schemaFile = "cuelang.org/go/mod/modfile/schema.cue" -// File represents the contents of a cue.mod/module.cue file. -type File struct { - // Module holds the module path, which may - // not contain a major version suffix. - // Use the [File.QualifiedModule] method to obtain a module - // path that's always qualified. See also the - // [File.ModulePath] and [File.MajorVersion] methods. - Module string `json:"module"` - Language *Language `json:"language,omitempty"` - Source *Source `json:"source,omitempty"` - Deps map[string]*Dep `json:"deps,omitempty"` - Custom map[string]map[string]any `json:"custom,omitempty"` - versions []module.Version - // defaultMajorVersions maps from module base path to the - // major version default for that path. - defaultMajorVersions map[string]string - // actualSchemaVersion holds the actual schema version - // that was used to validate the file. This will be one of the - // entries in the versions field in schema.cue and - // is set by the Parse functions. - actualSchemaVersion string -} - -// Module returns the fully qualified module path -// if is one. It returns the empty string when [ParseLegacy] -// is used and the module field is empty. -// -// Note that when the module field does not contain a major -// version suffix, "@v0" is assumed. -func (f *File) QualifiedModule() string { - if strings.Contains(f.Module, "@") { - return f.Module - } - if f.Module == "" { - return "" - } - return f.Module + "@v0" -} +type ( + // File represents the contents of a cue.mod/module.cue file. + File = modfiledata.File -// ModulePath returns the path part of the module without -// its major version suffix. -func (f *File) ModulePath() string { - path, _, _ := module.SplitPathVersion(f.QualifiedModule()) - return path -} + // Source represents how to transform from a module's + // source to its actual contents. + Source = modfiledata.Source -// MajorVersion returns the major version of the module, -// not including the "@". -// If there is no module (which can happen when [ParseLegacy] -// is used or if Module is explicitly set to an empty string), -// it returns the empty string. -func (f *File) MajorVersion() string { - _, vers, _ := module.SplitPathVersion(f.QualifiedModule()) - return vers -} + Language = modfiledata.Language + Dep = modfiledata.Dep +) // baseFileVersion is used to decode the language version // to decide how to decode the rest of the file. @@ -110,24 +64,9 @@ type baseFileVersion struct { } `json:"language"` } -// Source represents how to transform from a module's -// source to its actual contents. -type Source struct { - Kind string `json:"kind"` -} - -// Validate checks that src is well formed. -func (src *Source) Validate() error { - switch src.Kind { - case "git", "self": - return nil - } - return fmt.Errorf("unrecognized source kind %q", src.Kind) -} - // Format returns a formatted representation of f // in CUE syntax. -func (f *File) Format() ([]byte, error) { +func Format(f *File) ([]byte, error) { if len(f.Deps) == 0 && f.Deps != nil { // There's no way to get the CUE encoder to omit an empty // but non-nil slice (despite the current doc comment on @@ -154,11 +93,11 @@ func (f *File) Format() ([]byte, error) { // Sanity check that it can be parsed. // TODO this could be more efficient by checking all the file fields // before formatting the output. - f1, err := ParseNonStrict(data, "-") + _, actualSchemaVersion, err := parse(data, "-", false) if err != nil { return nil, fmt.Errorf("cannot parse result: %v", strings.TrimSuffix(errors.Details(err, nil), "\n")) } - if f.Language != nil && f1.actualSchemaVersion == "v0.0.0" { + if f.Language != nil && actualSchemaVersion == "v0.0.0" { // It's not a legacy module file (because the language field is present) // but we've used the legacy schema to parse it, which means that // it's almost certainly a bogus version because all versions @@ -169,15 +108,6 @@ func (f *File) Format() ([]byte, error) { return data, err } -type Language struct { - Version string `json:"version,omitempty"` -} - -type Dep struct { - Version string `json:"v"` - Default bool `json:"default,omitempty"` -} - type noDepsFile struct { Module string `json:"module"` } @@ -254,7 +184,8 @@ var earliestClosedSchemaVersion = sync.OnceValue(func() string { // All dependencies must be specified correctly: with major // versions in the module paths and canonical dependency versions. func Parse(modfile []byte, filename string) (*File, error) { - return parse(modfile, filename, true) + f, _, err := parse(modfile, filename, true) + return f, err } // ParseLegacy parses the legacy version of the module file @@ -264,30 +195,30 @@ func ParseLegacy(modfile []byte, filename string) (*File, error) { ctx := cuecontext.New() file, err := parseDataOnlyCUE(ctx, modfile, filename) if err != nil { - return nil, errors.Wrapf(err, token.NoPos, "invalid module.cue file syntax") + return nil, errors.Wrapf(err, token.NoPos, "invalid module file syntax") } // Unfortunately we need a new context. See the note inside [moduleSchemaDo]. v := ctx.BuildFile(file) if err := v.Err(); err != nil { - return nil, errors.Wrapf(err, token.NoPos, "invalid module.cue file") + return nil, errors.Wrapf(err, token.NoPos, "invalid module file") } var f noDepsFile if err := v.Decode(&f); err != nil { return nil, newCUEError(err, filename) } return &File{ - Module: f.Module, - actualSchemaVersion: "v0.0.0", + Module: f.Module, }, nil } -// ParseNonStrict is like Parse but allows some laxity in the parsing: +// ParseNonStrict is like [Parse] but allows some laxity in the parsing: // - if a module path lacks a version, it's taken from the version. // - if a non-canonical version is used, it will be canonicalized. // // The file name is used for error messages. func ParseNonStrict(modfile []byte, filename string) (*File, error) { - return parse(modfile, filename, false) + file, _, err := parse(modfile, filename, false) + return file, err } // FixLegacy converts a legacy module.cue file as parsed by [ParseLegacy] @@ -307,11 +238,11 @@ func FixLegacy(modfile []byte, filename string) (*File, error) { ctx := cuecontext.New() file, err := parseDataOnlyCUE(ctx, modfile, filename) if err != nil { - return nil, errors.Wrapf(err, token.NoPos, "invalid module.cue file syntax") + return nil, errors.Wrapf(err, token.NoPos, "invalid module file syntax") } v := ctx.BuildFile(file) if err := v.Validate(cue.Concrete(true)); err != nil { - return nil, errors.Wrapf(err, token.NoPos, "invalid module.cue file value") + return nil, errors.Wrapf(err, token.NoPos, "invalid module file value") } var allFields map[string]any if err := v.Decode(&allFields); err != nil { @@ -353,7 +284,7 @@ func FixLegacy(modfile []byte, filename string) (*File, error) { // Round-trip through [Parse] so that we get exactly the same // result as a later parse of the same data will. This also // adds a major version to the module path if needed. - data, err := f.Format() + data, err := Format(f) if err != nil { return nil, fmt.Errorf("cannot format fixed file: %v", err) } @@ -364,34 +295,37 @@ func FixLegacy(modfile []byte, filename string) (*File, error) { return f, nil } -func parse(modfile []byte, filename string, strict bool) (*File, error) { +func parse(modfile []byte, filename string, strict bool) (file *File, actualSchemaVersion string, err error) { // Unfortunately we need a new context. See the note inside [moduleSchemaDo]. ctx := cuecontext.New() - file, err := parseDataOnlyCUE(ctx, modfile, filename) + astFile, err := parseDataOnlyCUE(ctx, modfile, filename) if err != nil { - return nil, errors.Wrapf(err, token.NoPos, "invalid module.cue file syntax") + return nil, "", errors.Wrapf(err, token.NoPos, "invalid module file syntax") } - v := ctx.BuildFile(file) + v := ctx.BuildFile(astFile) if err := v.Validate(cue.Concrete(true)); err != nil { - return nil, errors.Wrapf(err, token.NoPos, "invalid module.cue file value") + return nil, "", errors.Wrapf(err, token.NoPos, "invalid module file value") } // First determine the declared version of the module file. var base baseFileVersion if err := v.Decode(&base); err != nil { - return nil, errors.Wrapf(err, token.NoPos, "cannot determine language version") + return nil, "", errors.Wrapf(err, token.NoPos, "cannot determine language version") } if base.Language.Version == "" { - return nil, ErrNoLanguageVersion + return nil, "", ErrNoLanguageVersion } if !semver.IsValid(base.Language.Version) { - return nil, fmt.Errorf("language version %q in module.cue is not valid semantic version", base.Language.Version) + return nil, "", fmt.Errorf("language version %q in module.cue is not valid semantic version", base.Language.Version) } if mv, lv := base.Language.Version, cueversion.LanguageVersion(); semver.Compare(mv, lv) > 0 { - return nil, fmt.Errorf("language version %q declared in module.cue is too new for current language version %q", mv, lv) + return nil, "", fmt.Errorf("language version %q declared in module.cue is too new for current language version %q", mv, lv) } - - mf, err := moduleSchemaDo(func(schemas *schemaInfo) (*File, error) { + type result struct { + file *File + actualSchemaVersion string + } + r, err := moduleSchemaDo(func(schemas *schemaInfo) (result, error) { // Now that we're happy we're within bounds, find the latest // schema that applies to the declared version. latest := "" @@ -408,12 +342,12 @@ func parse(modfile []byte, filename string, strict bool) (*File, error) { if latest == "" { // Should never happen, because there should always // be some applicable schema. - return nil, fmt.Errorf("cannot find schema suitable for reading module file with language version %q", base.Language.Version) + return result{}, fmt.Errorf("cannot find schema suitable for reading module file with language version %q", base.Language.Version) } schema := latestSchema v = v.Unify(lookup(schema, cue.Def("#File"))) if err := v.Validate(); err != nil { - return nil, newCUEError(err, filename) + return result{}, newCUEError(err, filename) } if latest == "v0.0.0" { // The chosen schema is the earliest schema which allowed @@ -423,74 +357,36 @@ func parse(modfile []byte, filename string, strict bool) (*File, error) { // This mirrors the behavior of [ParseLegacy]. var f noDepsFile if err := v.Decode(&f); err != nil { - return nil, newCUEError(err, filename) + return result{}, newCUEError(err, filename) } - return &File{ - Module: f.Module, - actualSchemaVersion: "v0.0.0", + return result{ + file: &File{ + Module: f.Module, + }, + actualSchemaVersion: latest, }, nil } var mf File if err := v.Decode(&mf); err != nil { - return nil, errors.Wrapf(err, token.NoPos, "internal error: cannot decode into modFile struct") + return result{}, errors.Wrapf(err, token.NoPos, "internal error: cannot decode into modFile struct") } - mf.actualSchemaVersion = latest - return &mf, nil + return result{ + file: &mf, + actualSchemaVersion: latest, + }, nil }) if err != nil { - return nil, err - } - mainPath, mainMajor, ok := module.SplitPathVersion(mf.Module) - if ok { - if semver.Major(mainMajor) != mainMajor { - return nil, fmt.Errorf("module path %s in %q should contain the major version only", mf.Module, filename) - } - } else if mainPath = mf.Module; mainPath != "" { - if err := module.CheckPathWithoutVersion(mainPath); err != nil { - return nil, fmt.Errorf("module path %q in %q is not valid: %v", mainPath, filename, err) - } - // There's no main module major version: default to v0. - mainMajor = "v0" - } - if mf.Language != nil { - vers := mf.Language.Version - if !semver.IsValid(vers) { - return nil, fmt.Errorf("language version %q in %s is not well formed", vers, filename) - } - if semver.Canonical(vers) != vers { - return nil, fmt.Errorf("language version %v in %s is not canonical", vers, filename) - } - } - var versions []module.Version - // The main module is always the default for its own major version. - defaultMajorVersions := map[string]string{ - mainPath: mainMajor, + return nil, "", err } - // Check that major versions match dependency versions. - for m, dep := range mf.Deps { - vers, err := module.NewVersion(m, dep.Version) - if err != nil { - return nil, fmt.Errorf("invalid module.cue file %s: cannot make version from module %q, version %q: %v", filename, m, dep.Version, err) - } - versions = append(versions, vers) - if strict && vers.Path() != m { - return nil, fmt.Errorf("invalid module.cue file %s: no major version in %q", filename, m) - } - if dep.Default { - mp := vers.BasePath() - if _, ok := defaultMajorVersions[mp]; ok { - return nil, fmt.Errorf("multiple default major versions found for %v", mp) - } - defaultMajorVersions[mp] = semver.Major(vers.Version()) - } + if strict { + err = r.file.Init() + } else { + err = r.file.InitNonStrict() } - - if len(defaultMajorVersions) > 0 { - mf.defaultMajorVersions = defaultMajorVersions + if err != nil { + return nil, "", fmt.Errorf("invalid module file %s: %v", filename, err) } - mf.versions = versions[:len(versions):len(versions)] - module.Sort(mf.versions) - return mf, nil + return r.file, r.actualSchemaVersion, nil } // ErrNoLanguageVersion is returned by [Parse] and [ParseNonStrict] @@ -518,7 +414,7 @@ func newCUEError(err error, filename string) error { ps := errors.Positions(err) for _, p := range ps { if errStr := findErrorComment(p); errStr != "" { - return fmt.Errorf("invalid module.cue file: %s", errStr) + return fmt.Errorf("invalid module file: %s", errStr) } } // TODO we have more potential to improve error messages here. @@ -563,19 +459,3 @@ func cutLast(s, sep string) (before, after string, found bool) { } return "", s, false } - -// DepVersions returns the versions of all the modules depended on by the -// file. The caller should not modify the returned slice. -// -// This always returns the same value, even if the contents -// of f are changed. If f was not created with [Parse], it returns nil. -func (f *File) DepVersions() []module.Version { - return slices.Clip(f.versions) -} - -// DefaultMajorVersions returns a map from module base path -// to the major version that's specified as the default for that module. -// The caller should not modify the returned map. -func (f *File) DefaultMajorVersions() map[string]string { - return f.defaultMajorVersions -} diff --git a/vendor/cuelang.org/go/mod/modregistry/client.go b/vendor/cuelang.org/go/mod/modregistry/client.go index e34fc03d8e..3eef69fa57 100644 --- a/vendor/cuelang.org/go/mod/modregistry/client.go +++ b/vendor/cuelang.org/go/mod/modregistry/client.go @@ -27,6 +27,7 @@ import ( "errors" "fmt" "io" + "iter" "net/http" "strings" @@ -36,7 +37,9 @@ import ( digest "github.com/opencontainers/go-digest" specs "github.com/opencontainers/image-spec/specs-go" ocispec "github.com/opencontainers/image-spec/specs-go/v1" + "golang.org/x/sync/errgroup" + "cuelang.org/go/cue/ast" "cuelang.org/go/mod/modfile" "cuelang.org/go/mod/module" "cuelang.org/go/mod/modzip" @@ -106,6 +109,130 @@ func NewClientWithResolver(resolver Resolver) *Client { } } +// Mirror ensures that the given module and its component parts +// are present and identical in both src and dst. +func (src *Client) Mirror(ctx context.Context, dst *Client, mv module.Version) error { + m, err := src.GetModule(ctx, mv) + if err != nil { + return err + } + dstLoc, err := dst.resolve(mv) + if err != nil { + return fmt.Errorf("cannot resolve module in destination: %w", err) + } + + // TODO ideally this parallelism would respect parallelism limits + // on whatever is calling the function too rather than just doing + // all uploads in parallel. + var g errgroup.Group + for desc := range manifestRefs(m.manifest) { + g.Go(func() error { + return mirrorBlob(ctx, m.loc, dstLoc, desc) + }) + } + if err := g.Wait(); err != nil { + return err + } + // We've uploaded all the blobs referenced by the manifest; now + // we can upload the manifest itself. + if _, err := dstLoc.Registry.ResolveManifest(ctx, dstLoc.Repository, m.manifestDigest); err == nil { + // Manifest already exists, but we still need to check for referrers + return src.mirrorReferrers(ctx, dst, m.loc, dstLoc, m.manifestDigest) + } + if _, err := dstLoc.Registry.PushManifest(ctx, dstLoc.Repository, dstLoc.Tag, m.manifestContents, ocispec.MediaTypeImageManifest); err != nil { + return nil + } + + // Mirror any referrers that point to this manifest + return src.mirrorReferrers(ctx, dst, m.loc, dstLoc, m.manifestDigest) +} + +func mirrorBlob(ctx context.Context, srcLoc, dstLoc RegistryLocation, desc ocispec.Descriptor) error { + desc1, err := dstLoc.Registry.ResolveBlob(ctx, dstLoc.Repository, desc.Digest) + if err == nil { + // Blob already exists in destination. Check that its size agrees. + if desc1.Size != desc.Size { + return fmt.Errorf("destination size (%d) does not agree with source size (%d) in blob %v", desc1.Size, desc.Size, desc.Digest) + } + return nil + } + r, err := srcLoc.Registry.GetBlob(ctx, srcLoc.Repository, desc.Digest) + if err != nil { + return err + } + defer r.Close() + if _, err := dstLoc.Registry.PushBlob(ctx, dstLoc.Repository, desc, r); err != nil { + return err + } + return nil +} + +// mirrorReferrers mirrors all referrers that point to the given manifest digest. +func (src *Client) mirrorReferrers(ctx context.Context, dst *Client, srcLoc, dstLoc RegistryLocation, manifestDigest ociregistry.Digest) error { + var g errgroup.Group + + // Iterate through all referrers that point to this manifest + for referrerDesc, err := range srcLoc.Registry.Referrers(ctx, srcLoc.Repository, manifestDigest, "") { + if err != nil { + return fmt.Errorf("failed to get referrers: %w", err) + } + + g.Go(func() error { + return src.mirrorReferrer(ctx, dst, srcLoc, dstLoc, referrerDesc) + }) + } + + return g.Wait() +} + +// mirrorReferrer mirrors a single referrer manifest and its associated blobs. +func (src *Client) mirrorReferrer(ctx context.Context, dst *Client, srcLoc, dstLoc RegistryLocation, referrerDesc ocispec.Descriptor) error { + // Check if the referrer manifest already exists in the destination + if _, err := dstLoc.Registry.ResolveManifest(ctx, dstLoc.Repository, referrerDesc.Digest); err == nil { + // Manifest already exists, nothing to do + return nil + } + + // Get the referrer manifest from source + r, err := srcLoc.Registry.GetManifest(ctx, srcLoc.Repository, referrerDesc.Digest) + if err != nil { + return fmt.Errorf("failed to get referrer manifest %s: %w", referrerDesc.Digest, err) + } + defer r.Close() + + manifestData, err := io.ReadAll(r) + if err != nil { + return fmt.Errorf("failed to read referrer manifest %s: %w", referrerDesc.Digest, err) + } + + // Parse the manifest to get the blobs it references + manifest, err := unmarshalManifest(manifestData, r.Descriptor().MediaType) + if err != nil { + return fmt.Errorf("failed to parse referrer manifest %s: %w", referrerDesc.Digest, err) + } + + // Mirror all blobs referenced by this referrer manifest (excluding Subject) + var g errgroup.Group + g.Go(func() error { + return mirrorBlob(ctx, srcLoc, dstLoc, manifest.Config) + }) + for _, desc := range manifest.Layers { + g.Go(func() error { + return mirrorBlob(ctx, srcLoc, dstLoc, desc) + }) + } + if err := g.Wait(); err != nil { + return fmt.Errorf("failed to mirror blobs for referrer %s: %w", referrerDesc.Digest, err) + } + + // Push the referrer manifest itself (without a tag, just by content) + if _, err := dstLoc.Registry.PushManifest(ctx, dstLoc.Repository, "", manifestData, r.Descriptor().MediaType); err != nil { + return fmt.Errorf("failed to push referrer manifest %s: %w", referrerDesc.Digest, err) + } + + return nil +} + // GetModule returns the module instance for the given version. // It returns an error that satisfies [errors.Is]([ErrNotFound]) if the // module is not present in the store at this version. @@ -162,11 +289,12 @@ func (c *Client) GetModuleWithManifest(m module.Version, contents []byte, mediaT } // TODO check that the other blobs are of the expected type (application/zip). return &Module{ - client: c, - loc: loc, - version: m, - manifest: *manifest, - manifestDigest: digest.FromBytes(contents), + client: c, + loc: loc, + version: m, + manifest: *manifest, + manifestContents: contents, + manifestDigest: digest.FromBytes(contents), }, nil } @@ -175,10 +303,7 @@ func (c *Client) GetModuleWithManifest(m module.Version, contents []byte, mediaT // If m has a major version suffix, only versions with that major version will // be returned. func (c *Client) ModuleVersions(ctx context.Context, m string) (_req []string, _err0 error) { - mpath, major, hasMajor := module.SplitPathVersion(m) - if !hasMajor { - mpath = m - } + mpath, major, hasMajor := ast.SplitPackageVersion(m) loc, err := c.resolver.ResolveToRegistry(mpath, "") if err != nil { if errors.Is(err, ErrRegistryNotFound) { @@ -195,25 +320,22 @@ func (c *Client) ModuleVersions(ctx context.Context, m string) (_req []string, _ } // Note: do not use c.repoName because that always expects // a module path with a major version. - iter := loc.Registry.Tags(ctx, loc.Repository, "") - var _err error - iter(func(tag string, err error) bool { + for tag, err := range loc.Registry.Tags(ctx, loc.Repository, "") { if err != nil { - _err = err - return false + if !isNotExist(err) { + return nil, fmt.Errorf("module %v: %w", m, err) + } + continue } vers, ok := strings.CutPrefix(tag, loc.Tag) if !ok || !semver.IsValid(vers) { - return true + continue } if !hasMajor || semver.Major(vers) == major { versions = append(versions, vers) } - return true - }) - if _err != nil && !isNotExist(_err) { - return nil, fmt.Errorf("module %v: %w", m, _err) } + semver.Sort(versions) return versions, nil } @@ -371,11 +493,12 @@ func checkModFile(m module.Version, f *zip.File) ([]byte, *modfile.File, error) // Module represents a CUE module instance. type Module struct { - client *Client - loc RegistryLocation - version module.Version - manifest ocispec.Manifest - manifestDigest ociregistry.Digest + client *Client + loc RegistryLocation + version module.Version + manifest ocispec.Manifest + manifestContents []byte + manifestDigest ociregistry.Digest } func (m *Module) Version() module.Version { @@ -509,3 +632,23 @@ func (r singleResolver) ResolveToRegistry(mpath, vers string) (RegistryLocation, Tag: vers, }, nil } + +// manifestRefs returns an iterator that produces all the references +// contained in m. +func manifestRefs(m ocispec.Manifest) iter.Seq[ociregistry.Descriptor] { + return func(yield func(ociregistry.Descriptor) bool) { + if !yield(m.Config) { + return + } + for _, desc := range m.Layers { + if !yield(desc) { + return + } + } + // For completeness, although we shouldn't actually use this + // logic. + if m.Subject != nil { + yield(*m.Subject) + } + } +} diff --git a/vendor/cuelang.org/go/mod/module/dirfs.go b/vendor/cuelang.org/go/mod/module/dirfs.go index bcc3127e2d..f84469a627 100644 --- a/vendor/cuelang.org/go/mod/module/dirfs.go +++ b/vendor/cuelang.org/go/mod/module/dirfs.go @@ -5,6 +5,7 @@ import ( "os" "cuelang.org/go/cue/ast" + "cuelang.org/go/cue/parser" ) // SourceLoc represents the location of some CUE source code. @@ -15,18 +16,19 @@ type SourceLoc struct { Dir string } -// ReadCUE can be implemented by an [fs.FS] +// ReadCUEFS can be implemented by an [fs.FS] // to provide an optimized (cached) way of // reading and parsing CUE syntax. type ReadCUEFS interface { fs.FS - // ReadCUEFile reads CUE syntax from the given path. + // ReadCUEFile reads CUE syntax from the given path, + // parsing it with the given configuration. // // If this method is implemented, but the implementation // does not support reading CUE files, // it should return [errors.ErrUnsupported]. - ReadCUEFile(path string) (*ast.File, error) + ReadCUEFile(path string, cfg parser.Config) (*ast.File, error) } // OSRootFS can be implemented by an [fs.FS] diff --git a/vendor/cuelang.org/go/mod/module/module.go b/vendor/cuelang.org/go/mod/module/module.go index ed632f343d..4ebf9ff395 100644 --- a/vendor/cuelang.org/go/mod/module/module.go +++ b/vendor/cuelang.org/go/mod/module/module.go @@ -85,6 +85,7 @@ import ( "slices" "strings" + "cuelang.org/go/cue/ast" "cuelang.org/go/internal/mod/semver" ) @@ -113,12 +114,27 @@ func (m Version) Equal(m1 Version) bool { return m.path == m1.path && m.version == m1.version } +func (m Version) Compare(m1 Version) int { + if c := cmp.Compare(m.path, m1.path); c != 0 { + return c + } + // To help go.sum formatting, allow version/file. + // Compare semver prefix by semver rules, + // file by string order. + va, fa, _ := strings.Cut(m.version, "/") + vb, fb, _ := strings.Cut(m1.version, "/") + if c := semver.Compare(va, vb); c != 0 { + return c + } + return cmp.Compare(fa, fb) +} + // BasePath returns the path part of m without its major version suffix. func (m Version) BasePath() string { if m.IsLocal() { return m.path } - basePath, _, ok := SplitPathVersion(m.path) + basePath, _, ok := ast.SplitPackageVersion(m.path) if !ok { panic(fmt.Errorf("broken invariant: failed to split version in %q", m.path)) } @@ -168,7 +184,7 @@ func MustParseVersion(s string) Version { // The version must be canonical (i.e. it can't be // just a major version). func ParseVersion(s string) (Version, error) { - basePath, vers, ok := SplitPathVersion(s) + basePath, vers, ok := ast.SplitPackageVersion(s) if !ok { return Version{}, fmt.Errorf("invalid module path@version %q", s) } @@ -207,19 +223,19 @@ func NewVersion(path string, version string) (Version, error) { return Version{}, fmt.Errorf("version %q (of module %q) is not canonical", version, path) } maj := semver.Major(version) - _, vmaj, ok := SplitPathVersion(path) + _, vmaj, ok := ast.SplitPackageVersion(path) if ok && maj != vmaj { return Version{}, fmt.Errorf("mismatched major version suffix in %q (version %v)", path, version) } if !ok { fullPath := path + "@" + maj - if _, _, ok := SplitPathVersion(fullPath); !ok { + if _, _, ok := ast.SplitPackageVersion(fullPath); !ok { return Version{}, fmt.Errorf("cannot form version path from %q, version %v", path, version) } path = fullPath } default: - base, _, ok := SplitPathVersion(path) + base, _, ok := ast.SplitPackageVersion(path) if !ok { return Version{}, fmt.Errorf("path %q has no major version", path) } @@ -246,26 +262,10 @@ func NewVersion(path string, version string) (Version, error) { // The Version fields are interpreted as semantic versions (using semver.Compare) // optionally followed by a tie-breaking suffix introduced by a slash character, // like in "v0.0.1/module.cue". +// +// Deprecated: use [slices.SortFunc] with [Version.Compare]. +// +//go:fix inline func Sort(list []Version) { - slices.SortFunc(list, func(a, b Version) int { - if c := cmp.Compare(a.path, b.path); c != 0 { - return c - } - // To help go.sum formatting, allow version/file. - // Compare semver prefix by semver rules, - // file by string order. - va := a.version - vb := b.version - var fa, fb string - if k := strings.Index(va, "/"); k >= 0 { - va, fa = va[:k], va[k:] - } - if k := strings.Index(vb, "/"); k >= 0 { - vb, fb = vb[:k], vb[k:] - } - if c := semver.Compare(va, vb); c != 0 { - return c - } - return cmp.Compare(fa, fb) - }) + slices.SortFunc(list, Version.Compare) } diff --git a/vendor/cuelang.org/go/mod/module/path.go b/vendor/cuelang.org/go/mod/module/path.go index 65eae6cf58..38a12f4330 100644 --- a/vendor/cuelang.org/go/mod/module/path.go +++ b/vendor/cuelang.org/go/mod/module/path.go @@ -40,7 +40,7 @@ func Check(path, version string) error { Err: &InvalidVersionError{Version: version, Err: errors.New("not a semantic version")}, } } - _, pathMajor, _ := SplitPathVersion(path) + _, pathMajor, _ := ast.SplitPackageVersion(path) if err := CheckPathMajor(version, pathMajor); err != nil { return &ModuleError{Path: path, Err: err} } @@ -105,29 +105,26 @@ func fileNameOK(r rune) bool { return unicode.IsLetter(r) } -// CheckPathWithoutVersion is like CheckPath except that +// CheckPathWithoutVersion is like [CheckPath] except that // it expects a module path without a major version. func CheckPathWithoutVersion(basePath string) (err error) { - if _, _, ok := SplitPathVersion(basePath); ok { - return fmt.Errorf("module path inappropriately contains major version") + if _, _, ok := ast.SplitPackageVersion(basePath); ok { + return fmt.Errorf("module path inappropriately contains version") } if err := checkPath(basePath, modulePath); err != nil { return err } - i := strings.Index(basePath, "/") - if i < 0 { - i = len(basePath) - } - if i == 0 { + firstPath, _, _ := strings.Cut(basePath, "/") + if firstPath == "" { return fmt.Errorf("leading slash") } - if !strings.Contains(basePath[:i], ".") { + if !strings.Contains(firstPath, ".") { return fmt.Errorf("missing dot in first path element") } if basePath[0] == '-' { return fmt.Errorf("leading dash in first path element") } - for _, r := range basePath[:i] { + for _, r := range firstPath { if !firstPathOK(r) { return fmt.Errorf("invalid char %q in first path element", r) } @@ -165,7 +162,7 @@ func CheckPath(mpath string) (err error) { } }() - basePath, vers, ok := SplitPathVersion(mpath) + basePath, vers, ok := ast.SplitPackageVersion(mpath) if ok { if semver.Major(vers) != vers { return fmt.Errorf("path can contain major version only") @@ -197,7 +194,7 @@ func CheckPath(mpath string) (err error) { // The element prefix up to the first dot must not be a reserved file name // on Windows, regardless of case (CON, com1, NuL, and so on). func CheckImportPath(path string) error { - parts := ParseImportPath(path) + parts := ast.ParseImportPath(path) if semver.Major(parts.Version) != parts.Version { return &InvalidPathError{ Kind: "import", @@ -297,10 +294,7 @@ func checkElem(elem string, kind pathKind) error { } // Windows disallows a bunch of path elements, sadly. // See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file - short := elem - if i := strings.Index(short, "."); i >= 0 { - short = short[:i] - } + short, _, _ := strings.Cut(elem, ".") for _, bad := range badWindowsNames { if strings.EqualFold(bad, short) { return fmt.Errorf("%q disallowed as path element component on Windows", short) @@ -378,124 +372,44 @@ var badWindowsNames = []string{ "LPT9", } -// SplitPathVersion returns a prefix and version suffix such -// that prefix+"@"+version == path. -// SplitPathVersion returns with ok=false when presented -// with a path with an invalid version suffix. +// SplitPathVersion returns a prefix and version suffix such that +// prefix+"@"+version == path. +// +// SplitPathVersion returns (path, "", false) when there is no `@` +// character splitting the path or if the version is empty. +// +// It does not check that the version is valid in any way other than +// checking that it is not empty. +// +// For example: // -// For example, SplitPathVersion("foo.com/bar@v0.1") returns -// ("foo.com/bar", "v0.1", true). +// SplitPathVersion("foo.com/bar@v0.1") returns ("foo.com/bar", "v0.1", true). +// SplitPathVersion("foo.com/bar@badvers") returns ("foo.com/bar", "badvers", true). +// SplitPathVersion("foo.com/bar") returns ("foo.com/bar", "", false). +// SplitPathVersion("foo.com/bar@") returns ("foo.com/bar@", "", false). +// +// Deprecated: use [ast.SplitPackageVersion] instead. +// +//go:fix inline func SplitPathVersion(path string) (prefix, version string, ok bool) { - i := strings.LastIndex(path, "@") - split := i - if i <= 0 || i+2 >= len(path) { - return "", "", false - } - if strings.Contains(path[:i], "@") { - return "", "", false - } - if path[i+1] != 'v' { - return "", "", false - } - if !semver.IsValid(path[i+1:]) { - return "", "", false - } - return path[:split], path[split+1:], true + return ast.SplitPackageVersion(path) } // ImportPath holds the various components of an import path. -type ImportPath struct { - // Path holds the base package/directory path, similar - // to that returned by [Version.BasePath]. - Path string - - // Version holds the version of the import - // or empty if not present. Note: in general this - // will contain a major version only, but there's no - // guarantee of that. - Version string - - // Qualifier holds the package qualifier within the path. - // This will be derived from the last component of Path - // if it wasn't explicitly present in the import path. - // This is not guaranteed to be a valid CUE identifier. - Qualifier string - - // ExplicitQualifier holds whether the qualifier will - // always be added regardless of whether it matches - // the final path element. - ExplicitQualifier bool -} - -// Canonical returns the canonical form of the import path. -// Specifically, it will only include the package qualifier -// if it's different from the last component of parts.Path. -func (parts ImportPath) Canonical() ImportPath { - if i := strings.LastIndex(parts.Path, "/"); i >= 0 && parts.Path[i+1:] == parts.Qualifier { - parts.Qualifier = "" - parts.ExplicitQualifier = false - } - return parts -} - -// Unqualified returns the import path without any package qualifier. -func (parts ImportPath) Unqualified() ImportPath { - parts.Qualifier = "" - parts.ExplicitQualifier = false - return parts -} - -func (parts ImportPath) String() string { - needQualifier := parts.ExplicitQualifier - if !needQualifier && parts.Qualifier != "" { - _, last, _ := cutLast(parts.Path, "/") - if last != "" && last != parts.Qualifier { - needQualifier = true - } - } - if parts.Version == "" && !needQualifier { - // Fast path. - return parts.Path - } - var buf strings.Builder - buf.WriteString(parts.Path) - if parts.Version != "" { - buf.WriteByte('@') - buf.WriteString(parts.Version) - } - if needQualifier { - buf.WriteByte(':') - buf.WriteString(parts.Qualifier) - } - return buf.String() -} +// +// Deprecated: use [ast.ImportPath] instead. +// +//go:fix inline +type ImportPath = ast.ImportPath // ParseImportPath returns the various components of an import path. // It does not check the result for validity. -func ParseImportPath(p string) ImportPath { - var parts ImportPath - pathWithoutQualifier := p - if i := strings.LastIndexAny(p, "/:"); i >= 0 && p[i] == ':' { - pathWithoutQualifier = p[:i] - parts.Qualifier = p[i+1:] - parts.ExplicitQualifier = true - } - parts.Path = pathWithoutQualifier - if path, version, ok := SplitPathVersion(pathWithoutQualifier); ok { - parts.Version = version - parts.Path = path - } - if !parts.ExplicitQualifier { - if i := strings.LastIndex(parts.Path, "/"); i >= 0 { - parts.Qualifier = parts.Path[i+1:] - } else { - parts.Qualifier = parts.Path - } - if !ast.IsValidIdent(parts.Qualifier) || strings.HasPrefix(parts.Qualifier, "#") || parts.Qualifier == "_" { - parts.Qualifier = "" - } - } - return parts +// +// Deprecated: use [ast.ParseImportPath] instead. +// +//go:fix inline +func ParseImportPath(p string) ast.ImportPath { + return ast.ParseImportPath(p) } // CheckPathMajor returns a non-nil error if the semantic version v @@ -509,10 +423,3 @@ func CheckPathMajor(v, pathMajor string) error { } return nil } - -func cutLast(s, sep string) (before, after string, found bool) { - if i := strings.LastIndex(s, sep); i >= 0 { - return s[:i], s[i+len(sep):], true - } - return "", s, false -} diff --git a/vendor/cuelang.org/go/mod/module/versions.go b/vendor/cuelang.org/go/mod/module/versions.go index ef4551a596..5e13bef3b3 100644 --- a/vendor/cuelang.org/go/mod/module/versions.go +++ b/vendor/cuelang.org/go/mod/module/versions.go @@ -7,17 +7,14 @@ import ( // Versions implements mvs.Versions[Version]. type Versions struct{} -// New implements mvs.Versions[Version].Version. func (Versions) Version(v Version) string { return v.Version() } -// New implements mvs.Versions[Version].Path. func (Versions) Path(v Version) string { return v.Path() } -// New implements mvs.Versions[Version].New. func (Versions) New(p, v string) (Version, error) { return NewVersion(p, v) } diff --git a/vendor/cuelang.org/go/mod/modzip/zip.go b/vendor/cuelang.org/go/mod/modzip/zip.go index 0ee2f18be2..9edd722777 100644 --- a/vendor/cuelang.org/go/mod/modzip/zip.go +++ b/vendor/cuelang.org/go/mod/modzip/zip.go @@ -74,7 +74,7 @@ const ( MaxLICENSE = 16 << 20 ) -// File provides an abstraction for a file in a directory, zip, or anything +// FileIO provides an abstraction for a file in a directory, zip, or anything // else that looks like a file - it knows how to open files represented // as a particular type without being a file itself. // diff --git a/vendor/cuelang.org/go/pkg/encoding/json/manual.go b/vendor/cuelang.org/go/pkg/encoding/json/manual.go index b0440831b9..688a83dcba 100644 --- a/vendor/cuelang.org/go/pkg/encoding/json/manual.go +++ b/vendor/cuelang.org/go/pkg/encoding/json/manual.go @@ -27,8 +27,10 @@ import ( "cuelang.org/go/cue/parser" "cuelang.org/go/cue/token" cuejson "cuelang.org/go/encoding/json" + "cuelang.org/go/internal/core/adt" internaljson "cuelang.org/go/internal/encoding/json" "cuelang.org/go/internal/pkg" + "cuelang.org/go/internal/value" ) // Compact generates the JSON-encoded src with insignificant space characters @@ -131,9 +133,29 @@ func Unmarshal(b []byte) (ast.Expr, error) { // Validate validates JSON and confirms it matches the constraints // specified by v. func Validate(b []byte, v pkg.Schema) (bool, error) { - err := cuejson.Validate(b, v) - if err != nil { + c := value.OpContext(v) + return validate(c, b, v) +} + +// validate is the actual implementation of Validate. +func validate(c *adt.OpContext, b []byte, v pkg.Schema) (bool, error) { + if !json.Valid(b) { + return false, fmt.Errorf("json: invalid JSON") + } + v2 := v.Context().CompileBytes(b, cue.Filename("json.Validate")) + if err := v2.Err(); err != nil { + return false, err + } + + vx := adt.Unify(c, value.Vertex(v2), value.Vertex(v)) + v = value.Make(c, vx) + if err := v.Err(); err != nil { + return false, err + } + + if err := v.Validate(cue.Final()); err != nil { return false, err } + return true, nil } diff --git a/vendor/cuelang.org/go/pkg/encoding/json/pkg.go b/vendor/cuelang.org/go/pkg/encoding/json/pkg.go index 189709db18..a8e6d1d3b0 100644 --- a/vendor/cuelang.org/go/pkg/encoding/json/pkg.go +++ b/vendor/cuelang.org/go/pkg/encoding/json/pkg.go @@ -123,7 +123,7 @@ var p = &pkg.Package{ Func: func(c *pkg.CallCtxt) { b, v := c.Bytes(0), c.Schema(1) if c.Do() { - c.Ret, c.Err = Validate(b, v) + c.Ret, c.Err = validate(c.OpContext(), b, v) } }, }}, diff --git a/vendor/cuelang.org/go/pkg/encoding/yaml/manual.go b/vendor/cuelang.org/go/pkg/encoding/yaml/manual.go index b8744c3e4a..bee74e9fae 100644 --- a/vendor/cuelang.org/go/pkg/encoding/yaml/manual.go +++ b/vendor/cuelang.org/go/pkg/encoding/yaml/manual.go @@ -20,9 +20,10 @@ import ( "cuelang.org/go/cue" "cuelang.org/go/cue/ast" - "cuelang.org/go/cue/errors" + "cuelang.org/go/internal/core/adt" cueyaml "cuelang.org/go/internal/encoding/yaml" "cuelang.org/go/internal/pkg" + "cuelang.org/go/internal/value" ) // Marshal returns the YAML encoding of v. @@ -30,7 +31,7 @@ func Marshal(v cue.Value) (string, error) { if err := v.Validate(cue.Concrete(true)); err != nil { return "", err } - n := v.Syntax(cue.Final(), cue.Concrete(true)) + n := v.Syntax(cue.Concrete(true)) b, err := cueyaml.Encode(n) return string(b), err } @@ -51,7 +52,7 @@ func MarshalStream(v cue.Value) (string, error) { if err := v.Validate(cue.Concrete(true)); err != nil { return "", err } - n := v.Syntax(cue.Final(), cue.Concrete(true)) + n := v.Syntax(cue.Concrete(true)) b, err := cueyaml.Encode(n) if err != nil { return "", err @@ -87,45 +88,16 @@ func UnmarshalStream(data []byte) (ast.Expr, error) { // Validate validates YAML and confirms it is an instance of schema. // If the YAML source is a stream, every object must match v. func Validate(b []byte, v pkg.Schema) (bool, error) { - d := cueyaml.NewDecoder("yaml.Validate", b) - r := v.Context() - for { - expr, err := d.Decode() - if err != nil { - if err == io.EOF { - return true, nil - } - return false, err - } - - x := r.BuildExpr(expr) - if err := x.Err(); err != nil { - return false, err - } + // This function is left for Go documentation. The package entry calls + // cueyaml.Validate directly, passing it the call context. - // TODO: consider using subsumption again here. - // Alternatives: - // - allow definition of non-concrete list, - // like list.Of(int), or []int. - // - Introduce ! in addition to ?, allowing: - // list!: [...] - // if err := v.Subsume(inst.Value(), cue.Final()); err != nil { - // return false, err - // } - x = v.Unify(x) - if err := x.Err(); err != nil { - return false, err - } - if err := x.Validate(cue.Concrete(true)); err != nil { - // Strip error codes: incomplete errors are terminal in this case. - var b pkg.Bottomer - if errors.As(err, &b) { - err = b.Bottom().Err - } - return false, err - } + ctx := value.OpContext(v) + return cueyaml.Validate(ctx, b, v) +} - } +// validate is the actual implementation of Validate. +func validate(c *adt.OpContext, b []byte, v pkg.Schema) (bool, error) { + return cueyaml.Validate(c, b, v) } // ValidatePartial validates YAML and confirms it matches the constraints @@ -133,24 +105,14 @@ func Validate(b []byte, v pkg.Schema) (bool, error) { // but does not have to be an instance of v. If the YAML source is a stream, // every object must match v. func ValidatePartial(b []byte, v pkg.Schema) (bool, error) { - d := cueyaml.NewDecoder("yaml.ValidatePartial", b) - r := v.Context() - for { - expr, err := d.Decode() - if err != nil { - if err == io.EOF { - return true, nil - } - return false, err - } + // This function is left for Go documentation. The package entry calls + // cueyaml.ValidatePartial directly, passing it the call context. - x := r.BuildExpr(expr) - if err := x.Err(); err != nil { - return false, err - } + ctx := value.OpContext(v) + return cueyaml.ValidatePartial(ctx, b, v) +} - if x := v.Unify(x); x.Err() != nil { - return false, x.Err() - } - } +// validatePartial is the actual implementation of ValidatePartial. +func validatePartial(c *adt.OpContext, b []byte, v pkg.Schema) (bool, error) { + return cueyaml.ValidatePartial(c, b, v) } diff --git a/vendor/cuelang.org/go/pkg/encoding/yaml/pkg.go b/vendor/cuelang.org/go/pkg/encoding/yaml/pkg.go index d1a31f150f..4c117d447e 100644 --- a/vendor/cuelang.org/go/pkg/encoding/yaml/pkg.go +++ b/vendor/cuelang.org/go/pkg/encoding/yaml/pkg.go @@ -73,7 +73,7 @@ var p = &pkg.Package{ Func: func(c *pkg.CallCtxt) { b, v := c.Bytes(0), c.Schema(1) if c.Do() { - c.Ret, c.Err = Validate(b, v) + c.Ret, c.Err = validate(c.OpContext(), b, v) } }, }, { @@ -87,7 +87,7 @@ var p = &pkg.Package{ Func: func(c *pkg.CallCtxt) { b, v := c.Bytes(0), c.Schema(1) if c.Do() { - c.Ret, c.Err = ValidatePartial(b, v) + c.Ret, c.Err = validatePartial(c.OpContext(), b, v) } }, }}, diff --git a/vendor/cuelang.org/go/pkg/list/list.go b/vendor/cuelang.org/go/pkg/list/list.go index cf59be33c4..08a96fdb01 100644 --- a/vendor/cuelang.org/go/pkg/list/list.go +++ b/vendor/cuelang.org/go/pkg/list/list.go @@ -23,6 +23,8 @@ import ( "cuelang.org/go/cue/errors" "cuelang.org/go/cue/token" "cuelang.org/go/internal/core/adt" + "cuelang.org/go/internal/core/eval" + "cuelang.org/go/internal/iterutil" "cuelang.org/go/internal/pkg" "cuelang.org/go/internal/types" "cuelang.org/go/internal/value" @@ -140,11 +142,7 @@ func Repeat(x []cue.Value, count int) ([]cue.Value, error) { if count < 0 { return nil, fmt.Errorf("negative count") } - var a []cue.Value - for range count { - a = append(a, x...) - } - return a, nil + return slices.Repeat(x, count), nil } // Concat takes a list of lists and concatenates them. @@ -233,7 +231,7 @@ func Reverse(x []cue.Value) []cue.Value { // MinItems reports whether a has at least n items. func MinItems(list pkg.List, n int) (bool, error) { - count := len(list.Elems()) + count := iterutil.Count(list.Elems()) if count >= n { return true, nil } @@ -249,7 +247,7 @@ func MinItems(list pkg.List, n int) (bool, error) { // MaxItems reports whether a has at most n items. func MaxItems(list pkg.List, n int) (bool, error) { - count := len(list.Elems()) + count := iterutil.Count(list.Elems()) if count > n { return false, pkg.ValidationError{B: &adt.Bottom{ Code: adt.EvalError, @@ -275,7 +273,7 @@ func UniqueItems(a []cue.Value) (bool, error) { var tv types.Value a[0].Core(&tv) - ctx := adt.NewContext(tv.R, tv.V) + ctx := eval.NewContext(tv.R, tv.V) posX, posY := 0, 0 code := adt.IncompleteError @@ -318,12 +316,7 @@ outer: // Contains reports whether v is contained in a. The value must be a // comparable value. func Contains(a []cue.Value, v cue.Value) bool { - for _, w := range a { - if v.Equals(w) { - return true - } - } - return false + return slices.ContainsFunc(a, v.Equals) } // MatchN is a validator that checks that the number of elements in the given @@ -331,15 +324,22 @@ func Contains(a []cue.Value, v cue.Value) bool { // "n" may be a number constraint and does not have to be a concrete number. // Likewise, "matchValue" will usually be a non-concrete value. func MatchN(list []cue.Value, n pkg.Schema, matchValue pkg.Schema) (bool, error) { + c := value.OpContext(n) + return matchN(c, list, n, matchValue) +} + +// matchN is the actual implementation of MatchN. +func matchN(c *adt.OpContext, list []cue.Value, n pkg.Schema, matchValue pkg.Schema) (bool, error) { var nmatch int64 for _, w := range list { - if matchValue.Unify(w).Validate(cue.Final()) == nil { + vx := adt.Unify(c, value.Vertex(matchValue), value.Vertex(w)) + x := value.Make(c, vx) + if x.Validate(cue.Final()) == nil { nmatch++ } } - r, _ := value.ToInternal(n) - ctx := (*cue.Context)(r) + ctx := value.Context(c) if err := n.Unify(ctx.Encode(nmatch)).Err(); err != nil { return false, pkg.ValidationError{B: &adt.Bottom{ diff --git a/vendor/cuelang.org/go/pkg/list/pkg.go b/vendor/cuelang.org/go/pkg/list/pkg.go index b58dc3a487..0cc45bf8d4 100644 --- a/vendor/cuelang.org/go/pkg/list/pkg.go +++ b/vendor/cuelang.org/go/pkg/list/pkg.go @@ -167,7 +167,7 @@ var p = &pkg.Package{ Func: func(c *pkg.CallCtxt) { list, n, matchValue := c.List(0), c.Schema(1), c.Schema(2) if c.Do() { - c.Ret, c.Err = MatchN(list, n, matchValue) + c.Ret, c.Err = matchN(c.OpContext(), list, n, matchValue) } }, }, { diff --git a/vendor/cuelang.org/go/pkg/list/sort.go b/vendor/cuelang.org/go/pkg/list/sort.go index 6c5e5310ce..db98a89a34 100644 --- a/vendor/cuelang.org/go/pkg/list/sort.go +++ b/vendor/cuelang.org/go/pkg/list/sort.go @@ -23,8 +23,8 @@ import ( "sort" "cuelang.org/go/cue" - "cuelang.org/go/internal" "cuelang.org/go/internal/core/adt" + "cuelang.org/go/internal/core/eval" "cuelang.org/go/internal/types" ) @@ -55,48 +55,7 @@ func (s *valueSorter) Less(i, j int) bool { return false } - if s.ctx.Version == internal.DevVersion { - return s.lessNew(i, j) - } - - var x, y types.Value - s.a[i].Core(&x) - s.a[j].Core(&y) - - // Save the state of all relevant arcs and restore later for the - // next comparison. - saveCmp := *s.cmp - saveLess := *s.less - saveX := *s.x - saveY := *s.y - - s.x.InsertConjunctsFrom(x.V) - s.y.InsertConjunctsFrom(y.V) - - // TODO(perf): if we can determine that the comparator values for - // x and y are idempotent (no arcs and a basevalue being top or - // a struct or list marker), then we do not need to reevaluate the input. - // In that case, we can use the below code instead of the above two loops - // setting the conjuncts. This may improve performance significantly. - // - // s.x.BaseValue = x.V.BaseValue - // s.x.Arcs = x.V.Arcs - // s.y.BaseValue = y.V.BaseValue - // s.y.Arcs = y.V.Arcs - - s.less.Finalize(s.ctx) - isLess := s.ctx.BoolValue(s.less) - if b := s.less.Err(s.ctx); b != nil && s.err == nil { - s.err = b.Err - return true - } - - *s.less = saveLess - *s.cmp = saveCmp - *s.x = saveX - *s.y = saveY - - return isLess + return s.lessNew(i, j) } func (s *valueSorter) lessNew(i, j int) bool { @@ -152,7 +111,7 @@ func makeValueSorter(list []cue.Value, cmp cue.Value) (s valueSorter) { var v types.Value cmp.Core(&v) - ctx := adt.NewContext(v.R, v.V) + ctx := eval.NewContext(v.R, v.V) n := &adt.Vertex{ Label: v.V.Label, diff --git a/vendor/cuelang.org/go/pkg/net/ip.go b/vendor/cuelang.org/go/pkg/net/ip.go index 89c587be16..9be5ed1a1f 100644 --- a/vendor/cuelang.org/go/pkg/net/ip.go +++ b/vendor/cuelang.org/go/pkg/net/ip.go @@ -16,7 +16,9 @@ package net import ( + "errors" "fmt" + "math/big" "net/netip" "cuelang.org/go/cue" @@ -178,7 +180,7 @@ func InterfaceLocalMulticastIP(ip cue.Value) bool { return netGetIP(ip).IsInterfaceLocalMulticast() } -// LinkLocalMulticast reports whether ip is a link-local multicast address. +// LinkLocalMulticastIP reports whether ip is a link-local multicast address. func LinkLocalMulticastIP(ip cue.Value) bool { return netGetIP(ip).IsLinkLocalMulticast() } @@ -242,3 +244,63 @@ func IPString(ip cue.Value) (string, error) { } return ipdata.String(), nil } + +func netIPAdd(addr netip.Addr, offset *big.Int) (netip.Addr, error) { + i := big.NewInt(0).SetBytes(addr.AsSlice()) + i = i.Add(i, offset) + + if i.Sign() < 0 { + return netip.Addr{}, errors.New("IP address arithmetic resulted in out-of-range address (underflow)") + } + + b := i.Bytes() + size := addr.BitLen() / 8 + + if len(b) > size { + return netip.Addr{}, errors.New("IP address arithmetic resulted in out-of-range address (overflow)") + } + + if len(b) < size { + b = append(make([]byte, size-len(b), size), b...) + } + addr, _ = netip.AddrFromSlice(b) + return addr, nil +} + +// AddIP adds a numerical offset to a given IP address. +// The address can be provided as a string, byte array, or CIDR subnet notation. +// It returns the resulting IP address or CIDR subnet notation as a string. +func AddIP(ip cue.Value, offset *big.Int) (string, error) { + prefix, err := netGetIPCIDR(ip) + if err == nil { + addr, err := netIPAdd(prefix.Addr(), offset) + if err != nil { + return "", err + } + return netip.PrefixFrom(addr, prefix.Bits()).String(), nil + } + ipdata := netGetIP(ip) + if !ipdata.IsValid() { + return "", fmt.Errorf("invalid IP %q", ip) + } + addr, err := netIPAdd(ipdata, offset) + if err != nil { + return "", err + } + return addr.String(), nil +} + +// AddIPCIDR adds a numerical offset to a given CIDR subnet +// string, returning a CIDR string. +func AddIPCIDR(ip cue.Value, offset *big.Int) (string, error) { + prefix, err := netGetIPCIDR(ip) + if err != nil { + return "", err + } + shifted := big.NewInt(0).Lsh(offset, (uint)(prefix.Addr().BitLen()-prefix.Bits())) + addr, err := netIPAdd(prefix.Addr(), shifted) + if err != nil { + return "", err + } + return netip.PrefixFrom(addr, prefix.Bits()).String(), nil +} diff --git a/vendor/cuelang.org/go/pkg/net/pkg.go b/vendor/cuelang.org/go/pkg/net/pkg.go index 568236636b..5599a702d4 100644 --- a/vendor/cuelang.org/go/pkg/net/pkg.go +++ b/vendor/cuelang.org/go/pkg/net/pkg.go @@ -237,6 +237,32 @@ var p = &pkg.Package{ c.Ret, c.Err = IPString(ip) } }, + }, { + Name: "AddIP", + Params: []pkg.Param{ + {Kind: adt.TopKind}, + {Kind: adt.IntKind}, + }, + Result: adt.StringKind, + Func: func(c *pkg.CallCtxt) { + ip, offset := c.Value(0), c.BigInt(1) + if c.Do() { + c.Ret, c.Err = AddIP(ip, offset) + } + }, + }, { + Name: "AddIPCIDR", + Params: []pkg.Param{ + {Kind: adt.TopKind}, + {Kind: adt.IntKind}, + }, + Result: adt.StringKind, + Func: func(c *pkg.CallCtxt) { + ip, offset := c.Value(0), c.BigInt(1) + if c.Do() { + c.Ret, c.Err = AddIPCIDR(ip, offset) + } + }, }, { Name: "PathEscape", Params: []pkg.Param{ diff --git a/vendor/cuelang.org/go/pkg/net/url.go b/vendor/cuelang.org/go/pkg/net/url.go index 5981a54d02..4e1600b92c 100644 --- a/vendor/cuelang.org/go/pkg/net/url.go +++ b/vendor/cuelang.org/go/pkg/net/url.go @@ -57,7 +57,7 @@ func URL(s string) (bool, error) { return err == nil, err } -// URL validates that s is an absolute URL. +// AbsURL validates that s is an absolute URL. // Note: this does also allow non-ASCII characters. func AbsURL(s string) (bool, error) { u, err := url.Parse(s) diff --git a/vendor/cuelang.org/go/pkg/regexp/manual.go b/vendor/cuelang.org/go/pkg/regexp/manual.go index eb3c1d240d..a4e5825f33 100644 --- a/vendor/cuelang.org/go/pkg/regexp/manual.go +++ b/vendor/cuelang.org/go/pkg/regexp/manual.go @@ -92,8 +92,8 @@ func FindAll(pattern, s string, n int) ([]string, error) { return m, nil } -// FindAllNamedSubmatch is like FindAllSubmatch, but returns a list of maps -// with the named used in capturing groups. See FindNamedSubmatch for an +// FindAllNamedSubmatch is like [FindAllSubmatch], but returns a list of maps +// with the named used in capturing groups. See [FindNamedSubmatch] for an // example on how to use named groups. func FindAllNamedSubmatch(pattern, s string, n int) ([]map[string]string, error) { re, err := regexp.Compile(pattern) @@ -123,7 +123,7 @@ func FindAllNamedSubmatch(pattern, s string, n int) ([]map[string]string, error) var errNoNamedGroup = errors.New("no named groups") -// FindAllSubmatch is the 'All' version of FindSubmatch; it returns a list +// FindAllSubmatch is the 'All' version of [FindSubmatch]; it returns a list // of all successive matches of the expression, as defined by the 'All' // description in the package comment. // A return value of bottom indicates no match. @@ -139,7 +139,7 @@ func FindAllSubmatch(pattern, s string, n int) ([][]string, error) { return m, nil } -// FindNamedSubmatch is like FindSubmatch, but returns a map with the names used +// FindNamedSubmatch is like [FindSubmatch], but returns a map with the names used // in capturing groups. // // Example: diff --git a/vendor/cuelang.org/go/pkg/regexp/regexp.go b/vendor/cuelang.org/go/pkg/regexp/regexp.go index 5ee737b90d..8e87dd3197 100644 --- a/vendor/cuelang.org/go/pkg/regexp/regexp.go +++ b/vendor/cuelang.org/go/pkg/regexp/regexp.go @@ -24,7 +24,6 @@ import "regexp" // Match reports whether the string s // contains any match of the regular expression pattern. -// More complicated queries need to use Compile and the full Regexp interface. func Match(pattern string, s string) (matched bool, err error) { return regexp.MatchString(pattern, s) } diff --git a/vendor/cuelang.org/go/pkg/strconv/strconv.go b/vendor/cuelang.org/go/pkg/strconv/strconv.go index 3ebb68e492..5272351b3a 100644 --- a/vendor/cuelang.org/go/pkg/strconv/strconv.go +++ b/vendor/cuelang.org/go/pkg/strconv/strconv.go @@ -68,38 +68,121 @@ func ParseFloat(s string, bitSize int) (float64, error) { // IntSize is the size in bits of an int or uint value. const IntSize = 64 -// ParseUint is like ParseInt but for unsigned numbers. -func ParseUint(s string, base int, bitSize int) (uint64, error) { - return strconv.ParseUint(s, base, bitSize) +// ParseUint is like [ParseInt] but for unsigned numbers. +func ParseUint(s string, base int, bitSize int) (*big.Int, error) { + if bitSize < 0 { + return nil, &strconv.NumError{ + Func: "ParseUint", + Num: s, + Err: strconv.ErrRange, + } + } + + // Parse the number using big.Int to handle arbitrary precision + i := new(big.Int) + i, ok := i.SetString(s, base) + if !ok { + return nil, &strconv.NumError{ + Func: "ParseUint", + Num: s, + Err: strconv.ErrSyntax, + } + } + + // Check if the value is negative (not allowed for unsigned) + if i.Sign() < 0 { + return nil, &strconv.NumError{ + Func: "ParseUint", + Num: s, + Err: strconv.ErrRange, + } + } + + // If bitSize is 0, return unlimited precision result + if bitSize == 0 { + return i, nil + } + + // Check if the value fits in the specified bit size + // For unsigned integers, the range is [0, 2^bitSize-1] + if i.BitLen() <= bitSize { + return i, nil + } + + return nil, &strconv.NumError{ + Func: "ParseUint", + Num: s, + Err: strconv.ErrRange, + } } // ParseInt interprets a string s in the given base (0, 2 to 36) and -// bit size (0 to 64) and returns the corresponding value i. +// bit size and returns the corresponding value i. // // If the base argument is 0, the true base is implied by the string's // prefix: 2 for "0b", 8 for "0" or "0o", 16 for "0x", and 10 otherwise. // Also, for argument base 0 only, underscore characters are permitted // as defined by the Go syntax for integer literals. // -// The bitSize argument specifies the integer type -// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64 -// correspond to int, int8, int16, int32, and int64. -// If bitSize is below 0 or above 64, an error is returned. -// -// The errors that ParseInt returns have concrete type *NumError -// and include err.Num = s. If s is empty or contains invalid -// digits, err.Err = ErrSyntax and the returned value is 0; -// if the value corresponding to s cannot be represented by a -// signed integer of the given size, err.Err = ErrRange and the -// returned value is the maximum magnitude integer of the -// appropriate bitSize and sign. -func ParseInt(s string, base int, bitSize int) (i int64, err error) { - return strconv.ParseInt(s, base, bitSize) +// The bitSize argument specifies the integer type that the result must fit into. +// If bitSize is 0, the result is unconstrained (unlimited precision). +// If bitSize is positive, the result must fit in a signed integer of that many bits. +// If bitSize is negative, an error is returned. +func ParseInt(s string, base int, bitSize int) (*big.Int, error) { + if bitSize < 0 { + return nil, &strconv.NumError{ + Func: "ParseInt", + Num: s, + Err: strconv.ErrRange, + } + } + + // Parse the number using big.Int to handle arbitrary precision + i := new(big.Int) + i, ok := i.SetString(s, base) + if !ok { + return nil, &strconv.NumError{ + Func: "ParseInt", + Num: s, + Err: strconv.ErrSyntax, + } + } + + // If bitSize is 0, return unlimited precision result + if bitSize == 0 { + return i, nil + } + // Check if the value fits in the specified bit size + // For signed integers, the range is [-2^(bitSize-1), 2^(bitSize-1)-1] + bitLen := i.BitLen() + if bitLen <= bitSize-1 { + return i, nil + } + if i.Sign() < 0 && bitLen == bitSize { + // It might be all 1s; add one and see if it fits. + x := big.NewInt(1) + x.Add(i, x) + if x.BitLen() <= bitSize-1 { + return i, nil + } + } + return nil, &strconv.NumError{ + Func: "ParseInt", + Num: s, + Err: strconv.ErrRange, + } } // Atoi is equivalent to ParseInt(s, 10, 0), converted to type int. -func Atoi(s string) (int, error) { - return strconv.Atoi(s) +func Atoi(s string) (*big.Int, error) { + n, err := ParseInt(s, 10, 0) + if err == nil { + return n, nil + } + if nerr, ok := err.(*strconv.NumError); ok { + nerr.Func = "Atoi" + } + return nil, err } // FormatFloat converts the floating-point number f to a string, diff --git a/vendor/cuelang.org/go/pkg/strings/manual.go b/vendor/cuelang.org/go/pkg/strings/manual.go index 56b6f3d9c7..1e475b476c 100644 --- a/vendor/cuelang.org/go/pkg/strings/manual.go +++ b/vendor/cuelang.org/go/pkg/strings/manual.go @@ -29,6 +29,7 @@ import ( "fmt" "strings" "unicode" + "unicode/utf8" ) // ByteAt reports the ith byte of the underlying strings or byte. @@ -60,7 +61,7 @@ func MinRunes(s string, min int) bool { // TODO: CUE strings cannot be invalid UTF-8. In case this changes, we need // to use the following conversion to count properly: // s, _ = unicodeenc.UTF8.NewDecoder().String(s) - return len([]rune(s)) >= min + return utf8.RuneCountInString(s) >= min } // MaxRunes reports whether the number of runes (Unicode codepoints) in a string @@ -68,7 +69,7 @@ func MinRunes(s string, min int) bool { // except all strings for which this property holds func MaxRunes(s string, max int) bool { // See comment in MinRunes implementation. - return len([]rune(s)) <= max + return utf8.RuneCountInString(s) <= max } // ToTitle returns a copy of the string s with all Unicode letters that begin diff --git a/vendor/cuelang.org/go/pkg/strings/strings.go b/vendor/cuelang.org/go/pkg/strings/strings.go index fc10f68d64..3882e6e613 100644 --- a/vendor/cuelang.org/go/pkg/strings/strings.go +++ b/vendor/cuelang.org/go/pkg/strings/strings.go @@ -174,7 +174,7 @@ func Trim(s, cutset string) string { // TrimLeft returns a slice of the string s with all leading // Unicode code points contained in cutset removed. // -// To remove a prefix, use TrimPrefix instead. +// To remove a prefix, use [TrimPrefix] instead. func TrimLeft(s, cutset string) string { return strings.TrimLeft(s, cutset) } @@ -182,7 +182,7 @@ func TrimLeft(s, cutset string) string { // TrimRight returns a slice of the string s, with all trailing // Unicode code points contained in cutset removed. // -// To remove a suffix, use TrimSuffix instead. +// To remove a suffix, use [TrimSuffix] instead. func TrimRight(s, cutset string) string { return strings.TrimRight(s, cutset) } diff --git a/vendor/cuelang.org/go/pkg/tool/cli/cli.cue b/vendor/cuelang.org/go/pkg/tool/cli/cli.cue index 83ce546357..7c15eab5c0 100644 --- a/vendor/cuelang.org/go/pkg/tool/cli/cli.cue +++ b/vendor/cuelang.org/go/pkg/tool/cli/cli.cue @@ -16,7 +16,8 @@ package cli // Print sends text to the stdout of the current process. Print: { - $id: *"tool/cli.Print" | "print" // for backwards compatibility + $id: _id + _id: *"tool/cli.Print" | "print" // for backwards compatibility // text is the text to be printed. text: string @@ -30,7 +31,8 @@ Print: { // response: bool // }) Ask: { - $id: "tool/cli.Ask" + $id: _id + _id: "tool/cli.Ask" // prompt sends this message to the output. prompt: string diff --git a/vendor/cuelang.org/go/pkg/tool/cli/pkg.go b/vendor/cuelang.org/go/pkg/tool/cli/pkg.go index 9ab88573d4..4feb4b0820 100644 --- a/vendor/cuelang.org/go/pkg/tool/cli/pkg.go +++ b/vendor/cuelang.org/go/pkg/tool/cli/pkg.go @@ -6,7 +6,8 @@ // // // Print sends text to the stdout of the current process. // Print: { -// $id: *"tool/cli.Print" | "print" // for backwards compatibility +// $id: _id +// _id: *"tool/cli.Print" | "print" // for backwards compatibility // // // text is the text to be printed. // text: string @@ -20,7 +21,8 @@ // // response: bool // // }) // Ask: { -// $id: "tool/cli.Ask" +// $id: _id +// _id: "tool/cli.Ask" // // // prompt sends this message to the output. // prompt: string @@ -46,11 +48,13 @@ var p = &pkg.Package{ Native: []*pkg.Builtin{}, CUE: `{ Print: { - $id: *"tool/cli.Print" | "print" + $id: _id + _id: *"tool/cli.Print" | "print" text: string } Ask: { - $id: "tool/cli.Ask" + $id: _id + _id: "tool/cli.Ask" prompt: string response: string | bool } diff --git a/vendor/cuelang.org/go/pkg/tool/exec/exec.cue b/vendor/cuelang.org/go/pkg/tool/exec/exec.cue index a4485c8ba2..f8c18dcb09 100644 --- a/vendor/cuelang.org/go/pkg/tool/exec/exec.cue +++ b/vendor/cuelang.org/go/pkg/tool/exec/exec.cue @@ -16,7 +16,8 @@ package exec // Run executes a program with the given arguments. Run: { - $id: *"tool/exec.Run" | "exec" // exec for backwards compatibility + $id: _id + _id: *"tool/exec.Run" | "exec" // exec for backwards compatibility // cmd is a non-empty list holding the program name to run // and the arguments to be passed to it. diff --git a/vendor/cuelang.org/go/pkg/tool/exec/pkg.go b/vendor/cuelang.org/go/pkg/tool/exec/pkg.go index 0eb9fe9e95..68530acf8f 100644 --- a/vendor/cuelang.org/go/pkg/tool/exec/pkg.go +++ b/vendor/cuelang.org/go/pkg/tool/exec/pkg.go @@ -6,7 +6,8 @@ // // // Run executes a program with the given arguments. // Run: { -// $id: *"tool/exec.Run" | "exec" // exec for backwards compatibility +// $id: _id +// _id: *"tool/exec.Run" | "exec" // exec for backwards compatibility // // // cmd is a non-empty list holding the program name to run // // and the arguments to be passed to it. @@ -64,7 +65,8 @@ var p = &pkg.Package{ Native: []*pkg.Builtin{}, CUE: `{ Run: { - $id: *"tool/exec.Run" | "exec" + $id: _id + _id: *"tool/exec.Run" | "exec" cmd: string | [string, ...string] dir?: string env: {[string]: string} | [...=~"="] diff --git a/vendor/cuelang.org/go/pkg/tool/file/file.cue b/vendor/cuelang.org/go/pkg/tool/file/file.cue index 9fe490faeb..7d4d75e0af 100644 --- a/vendor/cuelang.org/go/pkg/tool/file/file.cue +++ b/vendor/cuelang.org/go/pkg/tool/file/file.cue @@ -16,7 +16,8 @@ package file // Read reads the contents of a file. Read: { - $id: "tool/file.Read" + $id: _id + _id: "tool/file.Read" // filename names the file to read. // @@ -32,7 +33,8 @@ Read: { // Append writes contents to the given file. Append: { - $id: "tool/file.Append" + $id: _id + _id: "tool/file.Append" // filename names the file to append. // @@ -49,7 +51,8 @@ Append: { // Create writes contents to the given file. Create: { - $id: "tool/file.Create" + $id: _id + _id: "tool/file.Create" // filename names the file to write. // @@ -66,7 +69,8 @@ Create: { // Glob returns a list of files. Glob: { - $id: "tool/file.Glob" + $id: _id + _id: "tool/file.Glob" // glob specifies the pattern to match files with. // @@ -78,7 +82,8 @@ Glob: { // Mkdir creates a directory at the specified path. Mkdir: { - $id: "tool/file.Mkdir" + $id: _id + _id: "tool/file.Mkdir" // The directory path to create. // If path is already a directory, Mkdir does nothing. @@ -105,7 +110,8 @@ MkdirAll: Mkdir & { // It is the caller's responsibility to remove the directory when it is no // longer needed. MkdirTemp: { - $id: "tool/file.MkdirTemp" + $id: _id + _id: "tool/file.MkdirTemp" // The temporary directory is created in the directory specified by dir. // If dir is the empty string, MkdirTemp uses the default directory for @@ -123,7 +129,8 @@ MkdirTemp: { // RemoveAll removes path and any children it contains. // It removes everything it can but returns the first error it encounters. RemoveAll: { - $id: "tool/file.RemoveAll" + $id: _id + _id: "tool/file.RemoveAll" // The path to remove. // If the path does not exist, RemoveAll does nothing. diff --git a/vendor/cuelang.org/go/pkg/tool/file/pkg.go b/vendor/cuelang.org/go/pkg/tool/file/pkg.go index 2f522c57ff..530706277e 100644 --- a/vendor/cuelang.org/go/pkg/tool/file/pkg.go +++ b/vendor/cuelang.org/go/pkg/tool/file/pkg.go @@ -6,7 +6,8 @@ // // // Read reads the contents of a file. // Read: { -// $id: "tool/file.Read" +// $id: _id +// _id: "tool/file.Read" // // // filename names the file to read. // // @@ -22,7 +23,8 @@ // // // Append writes contents to the given file. // Append: { -// $id: "tool/file.Append" +// $id: _id +// _id: "tool/file.Append" // // // filename names the file to append. // // @@ -39,7 +41,8 @@ // // // Create writes contents to the given file. // Create: { -// $id: "tool/file.Create" +// $id: _id +// _id: "tool/file.Create" // // // filename names the file to write. // // @@ -56,7 +59,8 @@ // // // Glob returns a list of files. // Glob: { -// $id: "tool/file.Glob" +// $id: _id +// _id: "tool/file.Glob" // // // glob specifies the pattern to match files with. // // @@ -68,7 +72,8 @@ // // // Mkdir creates a directory at the specified path. // Mkdir: { -// $id: "tool/file.Mkdir" +// $id: _id +// _id: "tool/file.Mkdir" // // // The directory path to create. // // If path is already a directory, Mkdir does nothing. @@ -95,7 +100,8 @@ // // It is the caller's responsibility to remove the directory when it is no // // longer needed. // MkdirTemp: { -// $id: "tool/file.MkdirTemp" +// $id: _id +// _id: "tool/file.MkdirTemp" // // // The temporary directory is created in the directory specified by dir. // // If dir is the empty string, MkdirTemp uses the default directory for @@ -113,7 +119,8 @@ // // RemoveAll removes path and any children it contains. // // It removes everything it can but returns the first error it encounters. // RemoveAll: { -// $id: "tool/file.RemoveAll" +// $id: _id +// _id: "tool/file.RemoveAll" // // // The path to remove. // // If the path does not exist, RemoveAll does nothing. @@ -141,29 +148,34 @@ var p = &pkg.Package{ Native: []*pkg.Builtin{}, CUE: `{ Read: { - $id: "tool/file.Read" + $id: _id + _id: "tool/file.Read" filename: !="" contents: *bytes | string } Append: { - $id: "tool/file.Append" + $id: _id + _id: "tool/file.Append" filename: !="" permissions: int | *0o666 contents: bytes | string } Create: { - $id: "tool/file.Create" + $id: _id + _id: "tool/file.Create" filename: !="" permissions: int | *0o666 contents: bytes | string } Glob: { - $id: "tool/file.Glob" + $id: _id + _id: "tool/file.Glob" glob: !="" files: [...string] } Mkdir: { - $id: "tool/file.Mkdir" + $id: _id + _id: "tool/file.Mkdir" path: string createParents: bool | *false permissions: int | *0o777 @@ -172,13 +184,15 @@ var p = &pkg.Package{ createParents: true } MkdirTemp: { - $id: "tool/file.MkdirTemp" + $id: _id + _id: "tool/file.MkdirTemp" dir: string | *"" pattern: string | *"" path: string } RemoveAll: { - $id: "tool/file.RemoveAll" + $id: _id + _id: "tool/file.RemoveAll" path: string success: bool } diff --git a/vendor/cuelang.org/go/pkg/tool/http/http.cue b/vendor/cuelang.org/go/pkg/tool/http/http.cue index 04816de7d3..49eb02cb37 100644 --- a/vendor/cuelang.org/go/pkg/tool/http/http.cue +++ b/vendor/cuelang.org/go/pkg/tool/http/http.cue @@ -1,11 +1,11 @@ // Copyright 2018 The CUE Authors -// +// // 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. @@ -20,11 +20,16 @@ Put: Do & {method: "PUT"} Delete: Do & {method: "DELETE"} Do: { - $id: *"tool/http.Do" | "http" // http for backwards compatibility + $id: _id + _id: *"tool/http.Do" | "http" // http for backwards compatibility method: string url: string // TODO: make url.URL type + // followRedirects controls whether the http client follows redirects + // or not. Defaults to true, like the default net/http client in Go. + followRedirects: *true | bool + tls: { // Whether the server certificate must be validated. verify: *true | bool diff --git a/vendor/cuelang.org/go/pkg/tool/http/http.go b/vendor/cuelang.org/go/pkg/tool/http/http.go index 192db32ae6..303c32bc6d 100644 --- a/vendor/cuelang.org/go/pkg/tool/http/http.go +++ b/vendor/cuelang.org/go/pkg/tool/http/http.go @@ -116,6 +116,29 @@ func (c *httpCmd) Run(ctx *task.Context) (res interface{}, err error) { // TODO: timeout } + // Rather clumsily, we need to also default followRedirects here because + // it's still valid for tasks to be specified via the special $id field, in + // which case we cannot be clear that the documented CUE-based defaults have + // been applied. + // + // This is noted as something to fix, more precisely a mistake not to make + // again, in https://cuelang.org/issue/1325 + followRedirects := true + followRedirectsValue := ctx.Obj.LookupPath(cue.MakePath(cue.Str("followRedirects"))) + if followRedirectsValue.Exists() { + var err error + followRedirects, err = followRedirectsValue.Bool() + if err != nil { + return nil, err + } + } + + if !followRedirects { + client.CheckRedirect = func(req *http.Request, via []*http.Request) error { + return http.ErrUseLastResponse + } + } + req, err := http.NewRequest(method, u, r) if err != nil { return nil, err diff --git a/vendor/cuelang.org/go/pkg/tool/http/pkg.go b/vendor/cuelang.org/go/pkg/tool/http/pkg.go index 071b2e8917..097e79e081 100644 --- a/vendor/cuelang.org/go/pkg/tool/http/pkg.go +++ b/vendor/cuelang.org/go/pkg/tool/http/pkg.go @@ -10,11 +10,16 @@ // Delete: Do & {method: "DELETE"} // // Do: { -// $id: *"tool/http.Do" | "http" // http for backwards compatibility +// $id: _id +// _id: *"tool/http.Do" | "http" // http for backwards compatibility // // method: string // url: string // TODO: make url.URL type // +// // followRedirects controls whether the http client follows redirects +// // or not. Defaults to true, like the default net/http client in Go. +// followRedirects: *true | bool +// // tls: { // // Whether the server certificate must be validated. // verify: *true | bool @@ -70,9 +75,11 @@ var p = &pkg.Package{ Put: Do & {method: "PUT"} Delete: Do & {method: "DELETE"} Do: { - $id: *"tool/http.Do" | "http" - method: string - url: string + $id: _id + _id: *"tool/http.Do" | "http" + method: string + url: string + followRedirects: *true | bool tls: { verify: *true | bool caCert?: bytes | string diff --git a/vendor/cuelang.org/go/pkg/tool/os/os.cue b/vendor/cuelang.org/go/pkg/tool/os/os.cue index 56e1724309..ac4d16a26f 100644 --- a/vendor/cuelang.org/go/pkg/tool/os/os.cue +++ b/vendor/cuelang.org/go/pkg/tool/os/os.cue @@ -27,21 +27,24 @@ Name: !="" & !~"^[$]" // To define a shorthand, define the shorthand as a new flag referring to // the flag of which it is a shorthand. Setenv: { - $id: "tool/os.Setenv" + $id: _id + _id: "tool/os.Setenv" {[Name]: Value} } // Getenv gets and parses the specific command line variables. Getenv: { - $id: "tool/os.Getenv" + $id: _id + _id: "tool/os.Getenv" {[Name]: Value} } // Environ populates a struct with all environment variables. Environ: { - $id: "tool/os.Environ" + $id: _id + _id: "tool/os.Environ" // A map of all populated values. // Individual entries may be specified ahead of time to enable @@ -52,5 +55,6 @@ Environ: { // Clearenv clears all environment variables. Clearenv: { - $id: "tool/os.Clearenv" + $id: _id + _id: "tool/os.Clearenv" } diff --git a/vendor/cuelang.org/go/pkg/tool/os/pkg.go b/vendor/cuelang.org/go/pkg/tool/os/pkg.go index c38daadace..07163422c4 100644 --- a/vendor/cuelang.org/go/pkg/tool/os/pkg.go +++ b/vendor/cuelang.org/go/pkg/tool/os/pkg.go @@ -17,21 +17,24 @@ // // To define a shorthand, define the shorthand as a new flag referring to // // the flag of which it is a shorthand. // Setenv: { -// $id: "tool/os.Setenv" +// $id: _id +// _id: "tool/os.Setenv" // // {[Name]: Value} // } // // // Getenv gets and parses the specific command line variables. // Getenv: { -// $id: "tool/os.Getenv" +// $id: _id +// _id: "tool/os.Getenv" // // {[Name]: Value} // } // // // Environ populates a struct with all environment variables. // Environ: { -// $id: "tool/os.Environ" +// $id: _id +// _id: "tool/os.Environ" // // // A map of all populated values. // // Individual entries may be specified ahead of time to enable @@ -42,7 +45,8 @@ // // // Clearenv clears all environment variables. // Clearenv: { -// $id: "tool/os.Clearenv" +// $id: _id +// _id: "tool/os.Clearenv" // } package os @@ -63,19 +67,23 @@ var p = &pkg.Package{ Value: bool | number | *string | null Name: !="" & !~"^[$]" Setenv: { - $id: "tool/os.Setenv" + $id: _id + _id: "tool/os.Setenv" {[Name]: Value} } Getenv: { - $id: "tool/os.Getenv" + $id: _id + _id: "tool/os.Getenv" {[Name]: Value} } Environ: { - $id: "tool/os.Environ" + $id: _id + _id: "tool/os.Environ" {[Name]: Value} } Clearenv: { - $id: "tool/os.Clearenv" + $id: _id + _id: "tool/os.Clearenv" } }`, } diff --git a/vendor/cuelang.org/go/pkg/tool/pkg.go b/vendor/cuelang.org/go/pkg/tool/pkg.go index 50d6c86559..64c96155d5 100644 --- a/vendor/cuelang.org/go/pkg/tool/pkg.go +++ b/vendor/cuelang.org/go/pkg/tool/pkg.go @@ -69,14 +69,12 @@ // // // A Task defines a step in the execution of a command. // Task: { -// $type: "tool.Task" // legacy field 'kind' still supported for now. -// -// // $id indicates the operation to run. It must be of the form -// // packagePath.Operation. +// // $id indicates the operation to run. Do not use this field directly; +// // instead unify with a task imported from one of the tool packages. // $id: =~#"\."# // -// // $after can be used to specify a task is run after another one, when -// // it does not otherwise refer to an output of that task. +// // $after can be used to specify a task is run after another one, +// // when it does not otherwise refer to an output of that task. // $after?: Task | [...Task] // } // diff --git a/vendor/cuelang.org/go/pkg/tool/tool.cue b/vendor/cuelang.org/go/pkg/tool/tool.cue index cbf7125a5d..2c5bf884c0 100644 --- a/vendor/cuelang.org/go/pkg/tool/tool.cue +++ b/vendor/cuelang.org/go/pkg/tool/tool.cue @@ -64,14 +64,12 @@ Name: =~#"^\PL([-](\PL|\PN))*$"# // A Task defines a step in the execution of a command. Task: { - $type: "tool.Task" // legacy field 'kind' still supported for now. - - // $id indicates the operation to run. It must be of the form - // packagePath.Operation. + // $id indicates the operation to run. Do not use this field directly; + // instead unify with a task imported from one of the tool packages. $id: =~#"\."# - // $after can be used to specify a task is run after another one, when - // it does not otherwise refer to an output of that task. + // $after can be used to specify a task is run after another one, + // when it does not otherwise refer to an output of that task. $after?: Task | [...Task] } diff --git a/vendor/cuelang.org/go/pkg/uuid/pkg.go b/vendor/cuelang.org/go/pkg/uuid/pkg.go index 70d1b23039..bc1f1e3fd3 100644 --- a/vendor/cuelang.org/go/pkg/uuid/pkg.go +++ b/vendor/cuelang.org/go/pkg/uuid/pkg.go @@ -38,18 +38,6 @@ var p = &pkg.Package{ c.Ret, c.Err = Parse(s) } }, - }, { - Name: "ToString", - Params: []pkg.Param{ - {Kind: adt.StringKind}, - }, - Result: adt.StringKind, - Func: func(c *pkg.CallCtxt) { - x := c.String(0) - if c.Do() { - c.Ret = ToString(x) - } - }, }, { Name: "URN", Params: []pkg.Param{ diff --git a/vendor/cuelang.org/go/pkg/uuid/uuid.go b/vendor/cuelang.org/go/pkg/uuid/uuid.go index d164a5259c..8f57e6f242 100644 --- a/vendor/cuelang.org/go/pkg/uuid/uuid.go +++ b/vendor/cuelang.org/go/pkg/uuid/uuid.go @@ -35,19 +35,12 @@ func Valid(s string) error { // encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. func Parse(s string) (string, error) { x, err := uuid.Parse(s) - return string(x.String()), err -} - -// TODO(mvdan): what is ToString meant to do? it appears like a no-op? - -// String represents a 128-bit UUID value as a string. -func ToString(x string) string { - return string(x) + return x.String(), err } // URN reports the canonical URN of a UUID. func URN(x string) (string, error) { - u, err := uuid.Parse(string(x)) + u, err := uuid.Parse(x) if err != nil { return "", err } @@ -66,7 +59,7 @@ func FromInt(i *big.Int) (string, error) { b = buf[:] } u, err := uuid.FromBytes(b) - return string(u.String()), err + return u.String(), err } // ToInt represents a UUID string as a 128-bit value. @@ -78,7 +71,7 @@ func ToInt(x string) *big.Int { // Variant reports the UUID variant. func Variant(x string) (int, error) { - u, err := uuid.Parse(string(x)) + u, err := uuid.Parse(x) if err != nil { return 0, err } @@ -87,7 +80,7 @@ func Variant(x string) (int, error) { // Version reports the UUID version. func Version(x string) (int, error) { - u, err := uuid.Parse(string(x)) + u, err := uuid.Parse(x) if err != nil { return 0, err } @@ -96,19 +89,19 @@ func Version(x string) (int, error) { // SHA1 generates a version 5 UUID based on the supplied name space and data. func SHA1(space string, data []byte) (string, error) { - u, err := uuid.Parse(string(space)) + u, err := uuid.Parse(space) if err != nil { return "", err } - return string(uuid.NewSHA1(u, data).String()), nil + return uuid.NewSHA1(u, data).String(), nil } // MD5 generates a version 3 UUID based on the supplied name space and data. // Use SHA1 instead if you can. func MD5(space string, data []byte) (string, error) { - u, err := uuid.Parse(string(space)) + u, err := uuid.Parse(space) if err != nil { return "", err } - return string(uuid.NewMD5(u, data).String()), nil + return uuid.NewMD5(u, data).String(), nil } diff --git a/vendor/cuelang.org/go/tools/flow/cycle.go b/vendor/cuelang.org/go/tools/flow/cycle.go new file mode 100644 index 0000000000..5b50e0ebc3 --- /dev/null +++ b/vendor/cuelang.org/go/tools/flow/cycle.go @@ -0,0 +1,107 @@ +// Copyright 2020 CUE Authors +// +// 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. + +package flow + +import ( + "fmt" + "slices" + "strings" + + "cuelang.org/go/cue" + "cuelang.org/go/cue/errors" + "cuelang.org/go/cue/token" +) + +// checkCycle checks for cyclic dependencies between tasks. +func checkCycle(a []*Task) errors.Error { + cc := cycleChecker{ + visited: make([]bool, len(a)), + stack: make([]*Task, 0, len(a)), + } + if slices.ContainsFunc(a, cc.isCyclic) { + + } + return cc.err +} + +type cycleChecker struct { + visited []bool + stack []*Task + err errors.Error +} + +func (cc *cycleChecker) isCyclic(t *Task) bool { + i := t.index + if !cc.visited[i] { + cc.visited[i] = true + cc.stack = append(cc.stack, t) + + for _, d := range t.depTasks { + if !cc.visited[d.index] && cc.isCyclic(d) { + return true + } else if cc.visited[d.index] { + cc.addCycleError(t) + return true + } + } + } + cc.stack = cc.stack[:len(cc.stack)-1] + cc.visited[i] = false + return false +} + +func (cc *cycleChecker) addCycleError(start *Task) { + err := &cycleError{} + + for _, t := range cc.stack { + err.path = append(err.path, t.v.Path()) + err.positions = append(err.positions, t.v.Pos()) + } + + cc.err = errors.Append(cc.err, err) +} + +type cycleError struct { + path []cue.Path + positions []token.Pos +} + +func (e *cycleError) Error() string { + msg, args := e.Msg() + return fmt.Sprintf(msg, args...) +} + +func (e *cycleError) Path() []string { return nil } + +func (e *cycleError) Msg() (format string, args []interface{}) { + w := &strings.Builder{} + for _, p := range e.path { + fmt.Fprintf(w, "\n\ttask %s refers to", p) + } + fmt.Fprintf(w, "\n\ttask %s", e.path[0]) + + return "cyclic task dependency:%v", []interface{}{w.String()} +} + +func (e *cycleError) Position() token.Pos { + if len(e.positions) == 0 { + return token.NoPos + } + return e.positions[0] +} + +func (e *cycleError) InputPositions() []token.Pos { + return e.positions +} diff --git a/vendor/cuelang.org/go/tools/flow/flow.go b/vendor/cuelang.org/go/tools/flow/flow.go new file mode 100644 index 0000000000..ff1ba39784 --- /dev/null +++ b/vendor/cuelang.org/go/tools/flow/flow.go @@ -0,0 +1,494 @@ +// Copyright 2020 CUE Authors +// +// 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. + +// Package flow provides a low-level workflow manager based on a CUE Instance. +// +// A Task defines an operational unit in a Workflow and corresponds to a struct +// in a CUE instance. This package does not define what a Task looks like in a +// CUE Instance. Instead, the user of this package must supply a TaskFunc that +// creates a Runner for cue.Values that are deemed to be a Task. +// +// Tasks may depend on other tasks. Cyclic dependencies are thereby not allowed. +// A Task A depends on another Task B if A, directly or indirectly, has a +// reference to any field of Task B, including its root. +package flow + +// TODO: Add hooks. This would allow UIs, for instance, to report on progress. +// +// - New(inst *cue.Instance, options ...Option) +// - AddTask(v cue.Value, r Runner) *Task +// - AddDependency(a, b *Task) +// - AddTaskGraph(root cue.Value, fn taskFunc) +// - AddSequence(list cue.Value, fn taskFunc) +// - Err() + +// TODO: +// Should we allow lists as a shorthand for a sequence of tasks? +// If so, how do we specify termination behavior? + +// TODO: +// Should we allow tasks to be a child of another task? Currently, the search +// for tasks end once a task root is found. +// +// Semantically it is somewhat unclear to do so: for instance, if an $after +// is used to refer to an explicit task dependency, it is logically +// indistinguishable whether this should be a subtask or is a dependency. +// Using higher-order constructs for analysis is generally undesirable. +// +// A possible solution would be to define specific "grouping tasks" whose sole +// purpose is to define sub tasks. The user of this package would then need +// to explicitly distinguish between tasks that are dependencies and tasks that +// are subtasks. + +// TODO: streaming tasks/ server applications +// +// Workflows are currently implemented for batch processing, for instance to +// implement shell scripting or other kinds of batch processing. +// +// This API has been designed, however, to also allow for streaming +// applications. For instance, a streaming Task could listen for Etcd changes +// or incoming HTTP requests and send updates each time an input changes. +// Downstream tasks could then alternate between a Waiting and Running state. +// +// Note that such streaming applications would also cause configurations to +// potentially not become increasingly more specific. Instead, a Task would +// replace its old result each time it is updated. This would require tracking +// of which conjunct was previously created by a task. + +import ( + "context" + "fmt" + "slices" + "strings" + "sync/atomic" + + "cuelang.org/go/cue" + "cuelang.org/go/cue/errors" + "cuelang.org/go/cue/stats" + "cuelang.org/go/internal/core/adt" + "cuelang.org/go/internal/core/convert" + "cuelang.org/go/internal/core/eval" + "cuelang.org/go/internal/value" +) + +var ( + // ErrAbort may be returned by a task to avoid processing downstream tasks. + // This can be used by control nodes to influence execution. + ErrAbort = errors.New("abort dependant tasks without failure") + + // TODO: ErrUpdate: update and run a dependency, but don't complete a + // dependency as more results may come. This is useful in server mode. +) + +// A TaskFunc creates a Runner for v if v defines a task or reports nil +// otherwise. It reports an error for illformed tasks. +// +// If TaskFunc returns a non-nil Runner the search for task within v stops. +// That is, subtasks are not supported. +type TaskFunc func(v cue.Value) (Runner, error) + +// A Runner executes a Task. +type Runner interface { + // Run runs a Task. If any of the tasks it depends on returned an error it + // is passed to this task. It reports an error upon failure. + // + // Any results to be returned can be set by calling Fill on the passed task. + // + // TODO: what is a good contract for receiving and passing errors and abort. + // + // If for a returned error x errors.Is(x, ErrAbort), all dependant tasks + // will not be run, without this being an error. + Run(t *Task, err error) error +} + +// A RunnerFunc runs a Task. +type RunnerFunc func(t *Task) error + +func (f RunnerFunc) Run(t *Task, err error) error { + return f(t) +} + +// A Config defines options for interpreting an Instance as a Workflow. +type Config struct { + // Root limits the search for tasks to be within the path indicated to root. + // For the cue command, this is set to ["command"]. The default value is + // for all tasks to be root. + Root cue.Path + + // InferTasks allows tasks to be defined outside of the Root. Such tasks + // will only be included in the workflow if any of its fields is referenced + // by any of the tasks defined within Root. + // + // CAVEAT EMPTOR: this features is mostly provided for backwards + // compatibility with v0.2. A problem with this approach is that it will + // look for task structs within arbitrary data. So if not careful, there may + // be spurious matches. + InferTasks bool + + // IgnoreConcrete ignores references for which the values are already + // concrete and cannot change. + IgnoreConcrete bool + + // FindHiddenTasks allows tasks to be defined in hidden fields. + FindHiddenTasks bool + + // UpdateFunc is called whenever the information in the controller is + // updated. This includes directly after initialization. The task may be + // nil if this call is not the result of a task completing. + UpdateFunc func(c *Controller, t *Task) error +} + +// A Controller defines a set of Tasks to be executed. +type Controller struct { + cfg Config + isTask TaskFunc + + inst cue.Value + valueSeqNum int64 + + env *adt.Environment + + conjuncts []adt.Conjunct + conjunctSeq int64 + + taskCh chan *Task + + opCtx *adt.OpContext + context context.Context + cancelFunc context.CancelFunc + + // taskStats tracks counters for auxiliary operations done by tasks. It does + // not include the CUE operations done by the Controller on behalf of tasks, + // which is likely going to tbe the bulk of the operations. + taskStats stats.Counts + + done atomic.Bool + + // keys maps task keys to their index. This allows a recreation of the + // Instance while retaining the original task indices. + // + // TODO: do instance updating in place to allow for more efficient + // processing. + keys map[string]*Task + tasks []*Task + + // Only used during task initialization. + nodes map[*adt.Vertex]*Task + + errs errors.Error +} + +// Stats reports statistics on the total number of CUE operations used. +// +// This is an experimental method and the API is likely to change. The +// Counts.String method will likely stay and is the safest way to use this API. +// +// This currently should only be called after completion or within a call to +// UpdateFunc. +func (c *Controller) Stats() (counts stats.Counts) { + counts = *c.opCtx.Stats() + counts.Add(c.taskStats) + return counts +} + +// Tasks reports the tasks that are currently registered with the controller. +// +// This may currently only be called before Run is called or from within +// a call to UpdateFunc. Task pointers returned by this call are not guaranteed +// to be the same between successive calls to this method. +func (c *Controller) Tasks() []*Task { + return c.tasks +} + +func (c *Controller) cancel() { + if c.cancelFunc != nil { + c.cancelFunc() + } +} + +func (c *Controller) addErr(err error, msg string) { + c.errs = errors.Append(c.errs, errors.Promote(err, msg)) +} + +// New creates a Controller for a given Instance and TaskFunc. +// +// The instance value can either be a *cue.Instance or a cue.Value. +func New(cfg *Config, inst cue.InstanceOrValue, f TaskFunc) *Controller { + v := inst.Value() + ctx := eval.NewContext(value.ToInternal(v)) + + c := &Controller{ + isTask: f, + inst: v, + opCtx: ctx, + + taskCh: make(chan *Task), + keys: map[string]*Task{}, + } + + if cfg != nil { + c.cfg = *cfg + } + c.initTasks(true) + return c + +} + +// Run runs the tasks of a workflow until completion. +func (c *Controller) Run(ctx context.Context) error { + c.context, c.cancelFunc = context.WithCancel(ctx) + defer c.cancelFunc() + + c.runLoop() + + // NOTE: track state here as runLoop might add more tasks to the flow + // during the execution so checking current tasks state may not be + // accurate enough to determine that the flow is terminated. + // This is used to determine if the controller value can be retrieved. + // When the controller value is safe to be read concurrently this tracking + // can be removed. + c.done.Store(true) + + return c.errs +} + +// Value returns the value managed by the controller. +// +// It is safe to use the value only after [Controller.Run] has returned. +// It panics if the flow is running. +func (c *Controller) Value() cue.Value { + if !c.done.Load() { + panic("can't retrieve value before flow has terminated") + } + return c.inst +} + +// We need to escape quotes in the path, per +// https://mermaid-js.github.io/mermaid/#/flowchart?id=entity-codes-to-escape-characters +// This also requires that we escape the quoting character #. +var mermaidQuote = strings.NewReplacer("#", "#35;", `"`, "#quot;") + +// mermaidGraph generates a mermaid graph of the current state. This can be +// pasted into https://mermaid-js.github.io/mermaid-live-editor/ for +// visualization. +func mermaidGraph(c *Controller) string { + w := &strings.Builder{} + fmt.Fprintln(w, "graph TD") + for i, t := range c.Tasks() { + path := mermaidQuote.Replace(t.Path().String()) + fmt.Fprintf(w, " t%d(\"%s [%s]\")\n", i, path, t.State()) + for _, t := range t.Dependencies() { + fmt.Fprintf(w, " t%d-->t%d\n", i, t.Index()) + } + } + return w.String() +} + +// A State indicates the state of a Task. +// +// The following state diagram indicates the possible state transitions: +// +// Ready +// ↗︎ ↘︎ +// Waiting ← Running +// ↘︎ ↙︎ +// Terminated +// +// A Task may move from Waiting to Terminating if one of +// the tasks on which it depends fails. +// +// NOTE: transitions from Running to Waiting are currently not supported. In +// the future this may be possible if a task depends on continuously running +// tasks that send updates. +type State int + +//go:generate go tool stringer -type=State + +const ( + // Waiting indicates a task is blocked on input from another task. + // + // NOTE: although this is currently not implemented, a task could + // theoretically move from the Running to Waiting state. + Waiting State = iota + + // Ready means a tasks is ready to run, but currently not running. + Ready + + // Running indicates a goroutine is currently active for a task and that + // it is not Waiting. + Running + + // Terminated means a task has stopped running either because it terminated + // while Running or was aborted by task on which it depends. The error + // value of a Task indicates the reason for the termination. + Terminated +) + +// A Task contains the context for a single task execution. +// Tasks may be run concurrently. +type Task struct { + // Static + c *Controller + ctxt *adt.OpContext + r Runner + + index int + path cue.Path + key string + labels []adt.Feature + + // Dynamic + update adt.Expr + deps map[*Task]bool + pathDeps map[string][]*Task + + conjunctSeq int64 + valueSeq int64 + v cue.Value + err errors.Error + state State + depTasks []*Task + + stats stats.Counts +} + +// Stats reports statistics on the number of CUE operations used to complete +// this task. +// +// This is an experimental method and the API is likely to change. +// +// It only shows numbers upon completion. This may change in the future. +func (t *Task) Stats() stats.Counts { + return t.stats +} + +// Context reports the Controller's Context. +func (t *Task) Context() context.Context { + return t.c.context +} + +// Path reports the path of Task within the Instance in which it is defined. +// The Path is always valid. +func (t *Task) Path() cue.Path { + return t.path +} + +// Index reports the sequence number of the Task. This will not change over +// time. +func (t *Task) Index() int { + return t.index +} + +func (t *Task) done() bool { + return t.state > Running +} + +func (t *Task) isReady() bool { + for _, d := range t.depTasks { + if !d.done() { + return false + } + } + return true +} + +func (t *Task) vertex() *adt.Vertex { + _, x := value.ToInternal(t.v) + return x +} + +func (t *Task) addDep(path string, dep *Task) { + if dep == nil || dep == t { + return + } + if t.deps == nil { + t.deps = map[*Task]bool{} + t.pathDeps = map[string][]*Task{} + } + + // Add the dependencies for a given path to the controller. We could compute + // this again later, but this ensures there will be no discrepancies. + a := t.pathDeps[path] + found := slices.Contains(a, dep) + if !found { + t.pathDeps[path] = append(a, dep) + + } + + if !t.deps[dep] { + t.deps[dep] = true + t.depTasks = append(t.depTasks, dep) + } +} + +// Fill fills in values of the Controller's configuration for the current task. +// The changes take effect after the task completes. +// +// This method may currently only be called by the runner. +func (t *Task) Fill(x interface{}) error { + expr := convert.GoValueToExpr(t.ctxt, true, x) + if t.update == nil { + t.update = expr + return nil + } + t.update = &adt.BinaryExpr{ + Op: adt.AndOp, + X: t.update, + Y: expr, + } + return nil +} + +// Value reports the latest value of this task. +// +// This method may currently only be called before Run is called or after a +// Task completed, or from within a call to UpdateFunc. +func (t *Task) Value() cue.Value { + // TODO: synchronize + return t.v +} + +// Dependencies reports the Tasks t depends on. +// +// This method may currently only be called before Run is called or after a +// Task completed, or from within a call to UpdateFunc. +func (t *Task) Dependencies() []*Task { + // TODO: add synchronization. + return t.depTasks +} + +// PathDependencies reports the dependencies found for a value at the given +// path. +// +// This may currently only be called before Run is called or from within +// a call to UpdateFunc. +func (t *Task) PathDependencies(p cue.Path) []*Task { + return t.pathDeps[p.String()] +} + +// Err returns the error of a completed Task. +// +// This method may currently only be called before Run is called, after a +// Task completed, or from within a call to UpdateFunc. +func (t *Task) Err() error { + return t.err +} + +// State is the current state of the Task. +// +// This method may currently only be called before Run is called or after a +// Task completed, or from within a call to UpdateFunc. +func (t *Task) State() State { + return t.state +} diff --git a/vendor/cuelang.org/go/tools/flow/run.go b/vendor/cuelang.org/go/tools/flow/run.go new file mode 100644 index 0000000000..036ea15f28 --- /dev/null +++ b/vendor/cuelang.org/go/tools/flow/run.go @@ -0,0 +1,251 @@ +// Copyright 2020 CUE Authors +// +// 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. + +package flow + +// This file contains logic for running tasks. +// +// This implementation anticipates that workflows can also be used for defining +// servers, not just batch scripts. In the future, tasks may be long running and +// provide streams of results. +// +// The implementation starts a goroutine for each user-defined task, instead of +// having a fixed pool of workers. The main reason for this is that tasks are +// inherently heterogeneous and may be blocking on top of that. Also, in the +// future tasks may be long running, as discussed above. + +import ( + "fmt" + "os" + "slices" + + "cuelang.org/go/cue/errors" + "cuelang.org/go/internal/core/adt" + "cuelang.org/go/internal/core/eval" + "cuelang.org/go/internal/cuedebug" + "cuelang.org/go/internal/value" +) + +func (c *Controller) runLoop() { + _, root := value.ToInternal(c.inst) + + // Copy the initial conjuncts. + rootConjuncts := slices.Collect(root.LeafConjuncts()) + n := len(rootConjuncts) + c.conjuncts = make([]adt.Conjunct, n, n+len(c.tasks)) + copy(c.conjuncts, rootConjuncts) + + c.markReady(nil) + + for c.errs == nil { + // Dispatch all unblocked tasks to workers. Only update + // the configuration when all have been dispatched. + + waiting := false + running := false + + // Mark tasks as Ready. + for _, t := range c.tasks { + // Avoid clobbering t: since we are running a goroutine below that + // refers to this t, we need to ensure t is captured before the next + // loop starts. + t := t + switch t.state { + case Waiting: + waiting = true + + case Ready: + running = true + + t.state = Running + c.updateTaskValue(t) + + t.ctxt = eval.NewContext(value.ToInternal(t.v)) + + go func(t *Task) { + if err := t.r.Run(t, nil); err != nil { + t.err = errors.Promote(err, "task failed") + } + + t.c.taskCh <- t + }(t) + + case Running: + running = true + + case Terminated: + } + } + + if !running { + if waiting { + // Should not happen ever, as cycle detection should have caught + // this. But keep this around as a defensive measure. + c.addErr(errors.New("deadlock"), "run loop") + } + break + } + + select { + case <-c.context.Done(): + return + + case t := <-c.taskCh: + t.state = Terminated + + taskStats := *t.ctxt.Stats() + t.stats.Add(taskStats) + c.taskStats.Add(taskStats) + + start := *c.opCtx.Stats() + + switch t.err { + case nil: + c.updateTaskResults(t) + + case ErrAbort: + // TODO: do something cleverer. + fallthrough + + default: + c.addErr(t.err, "task failure") + return + } + + // Recompute the configuration, if necessary. + if c.updateValue() { + // initTasks was already called in New to catch initialization + // errors earlier and add stats. + c.initTasks(false) + } + + c.updateTaskValue(t) + + t.stats.Add(c.opCtx.Stats().Since(start)) + + c.markReady(t) + } + } +} + +func (c *Controller) markReady(t *Task) { + for _, x := range c.tasks { + if x.state == Waiting && x.isReady() { + x.state = Ready + } + } + + cuedebug.Init() + if cuedebug.Flags.ToolsFlow { + fmt.Fprintln(os.Stderr, "tools/flow task dependency graph:") + fmt.Fprintln(os.Stderr, "```mermaid") + fmt.Fprint(os.Stderr, mermaidGraph(c)) + fmt.Fprintln(os.Stderr, "```") + } + + if c.cfg.UpdateFunc != nil { + if err := c.cfg.UpdateFunc(c, t); err != nil { + c.addErr(err, "task completed") + c.cancel() + return + } + } +} + +// updateValue recomputes the workflow configuration if it is out of date. It +// reports whether the values were updated. +func (c *Controller) updateValue() bool { + + if c.valueSeqNum == c.conjunctSeq { + return false + } + + // TODO: incrementally update results. Currently, the entire tree is + // recomputed on every update. This should not be necessary with the right + // notification structure in place. + + v := &adt.Vertex{Conjuncts: c.conjuncts} + v.Finalize(c.opCtx) + + c.inst = value.Make(c.opCtx, v) + c.valueSeqNum = c.conjunctSeq + return true +} + +// updateTaskValue updates the value of the task in the configuration if it is +// out of date. +func (c *Controller) updateTaskValue(t *Task) { + required := t.conjunctSeq + for _, dep := range t.depTasks { + if dep.conjunctSeq > required { + required = dep.conjunctSeq + } + } + + if t.valueSeq == required { + return + } + + if c.valueSeqNum < required { + c.updateValue() + } + + t.v = c.inst.LookupPath(t.path) + t.valueSeq = required +} + +// updateTaskResults updates the result status of the task and adds any result +// values to the overall configuration. +func (c *Controller) updateTaskResults(t *Task) bool { + if t.update == nil { + return false + } + + expr := t.update + for _, label := range slices.Backward(t.labels) { + switch label.Typ() { + case adt.StringLabel, adt.HiddenLabel: + expr = &adt.StructLit{ + Decls: []adt.Decl{ + &adt.Field{ + Label: label, + Value: expr, + }, + }, + } + case adt.IntLabel: + i := label.Index() + list := &adt.ListLit{} + any := &adt.Top{} + // TODO(perf): make this a constant thing. This will be possible with the query extension. + for range i { + list.Elems = append(list.Elems, any) + } + list.Elems = append(list.Elems, expr, &adt.Ellipsis{}) + expr = list + default: + panic(fmt.Errorf("unexpected label type %v", label.Typ())) + } + } + + t.update = nil + + // TODO: replace rather than add conjunct if this task already added a + // conjunct before. This will allow for serving applications. + c.conjuncts = append(c.conjuncts, adt.MakeRootConjunct(c.env, expr)) + c.conjunctSeq++ + t.conjunctSeq = c.conjunctSeq + + return true +} diff --git a/vendor/cuelang.org/go/tools/flow/state_string.go b/vendor/cuelang.org/go/tools/flow/state_string.go new file mode 100644 index 0000000000..3f85735cb7 --- /dev/null +++ b/vendor/cuelang.org/go/tools/flow/state_string.go @@ -0,0 +1,27 @@ +// Code generated by "stringer -type=State"; DO NOT EDIT. + +package flow + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[Waiting-0] + _ = x[Ready-1] + _ = x[Running-2] + _ = x[Terminated-3] +} + +const _State_name = "WaitingReadyRunningTerminated" + +var _State_index = [...]uint8{0, 7, 12, 19, 29} + +func (i State) String() string { + idx := int(i) - 0 + if i < 0 || idx >= len(_State_index)-1 { + return "State(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _State_name[_State_index[idx]:_State_index[idx+1]] +} diff --git a/vendor/cuelang.org/go/tools/flow/tasks.go b/vendor/cuelang.org/go/tools/flow/tasks.go new file mode 100644 index 0000000000..e724076c9d --- /dev/null +++ b/vendor/cuelang.org/go/tools/flow/tasks.go @@ -0,0 +1,285 @@ +// Copyright 2020 CUE Authors +// +// 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. + +package flow + +// This file contains functionality for identifying tasks in the configuration +// and annotating the dependencies between them. + +import ( + "cuelang.org/go/cue" + "cuelang.org/go/cue/errors" + "cuelang.org/go/internal/core/adt" + "cuelang.org/go/internal/core/dep" + "cuelang.org/go/internal/value" +) + +// initTasks takes the current configuration and adds tasks to the list of +// tasks. It can be run multiple times on increasingly more concrete +// configurations to add more tasks, whereby the task pointers of previously +// found tasks are preserved. +func (c *Controller) initTasks(addStats bool) { + // Clear previous cache. + c.nodes = map[*adt.Vertex]*Task{} + + v := c.inst.LookupPath(c.cfg.Root) + if err := v.Err(); err != nil { + c.addErr(err, "invalid root") + c.cancel() + return + } + + // Mark any task that is located under the root. + c.findRootTasks(v) + + // Mark any tasks that are implied by dependencies. + // Note that the list of tasks may grow as this loop progresses. + for i := 0; i < len(c.tasks); i++ { + t := c.tasks[i] + start := *c.opCtx.Stats() + c.markTaskDependencies(t, t.vertex()) + if addStats { + t.stats.Add(c.opCtx.Stats().Since(start)) + } + } + + // Check if there are cycles in the task dependencies. + if err := checkCycle(c.tasks); err != nil { + c.addErr(err, "cyclic task") + } + + if c.errs != nil { + c.cancel() + } +} + +// findRootTasks finds tasks under the root. +func (c *Controller) findRootTasks(v cue.Value) { + t := c.getTask(nil, v) + + if t != nil { + return + } + + opts := []cue.Option{} + + if c.cfg.FindHiddenTasks { + opts = append(opts, cue.Hidden(true), cue.Definitions(false)) + } + + for iter, _ := v.Fields(opts...); iter.Next(); { + c.findRootTasks(iter.Value()) + } + for iter, _ := v.List(); iter.Next(); { + c.findRootTasks(iter.Value()) + } + +} + +// This file contains the functionality to locate and record the tasks of +// a configuration. It: +// - create Task struct for each node that is a task +// - associate nodes in a configuration with a Task, if applicable. +// The node-to-task map is used to determine task dependencies. + +// getTask finds and marks tasks that are descendents of v. +func (c *Controller) getTask(scope *Task, v cue.Value) *Task { + // Look up cached node. + _, w := value.ToInternal(v) + if t, ok := c.nodes[w]; ok { + return t + } + + if err := w.Err(c.opCtx); err != nil && err.Permanent { + c.addErr(err.Err, "invalid task") + return nil + } + + // Look up cached task from previous evaluation. + p := v.Path() + key := p.String() + + t := c.keys[key] + + if t == nil { + r, err := c.isTask(v) + + var errs errors.Error + if err != nil { + if !c.inRoot(w) { + // Must be in InferTask mode. In this case we ignore the error. + r = nil + } else { + c.addErr(err, "invalid task") + errs = errors.Promote(err, "create task") + } + } + + if r != nil { + index := len(c.tasks) + t = &Task{ + v: v, + c: c, + r: r, + path: p, + labels: w.Path(), + key: key, + index: index, + err: errs, + } + c.tasks = append(c.tasks, t) + c.keys[key] = t + } + } + + // Process nodes of task for this evaluation. + if t != nil { + scope = t + if t.state <= Ready { + // Don't set the value if the task is currently running as this may + // result in all kinds of inconsistency issues. + t.v = v + } + + c.tagChildren(w, t) + } + + c.nodes[w] = scope + + return t +} + +func (c *Controller) tagChildren(n *adt.Vertex, t *Task) { + for _, a := range n.Arcs { + c.nodes[a] = t + c.tagChildren(a, t) + } +} + +// findImpliedTask determines the task of corresponding to node n, if any. If n +// is not already associated with a task, it tries to determine whether n is +// part of a task by checking if any of the parent nodes is a task. +// +// TODO: it is actually more accurate to check for tasks from top down. TODO: +// What should be done if a subtasks is referenced that is embedded in another +// task. Should the surrounding tasks be added as well? +func (c *Controller) findImpliedTask(d dep.Dependency) *Task { + // Ignore references into packages. Fill will fundamentally not work for + // packages, and packages cannot point back to the main package as cycles + // are not allowed. + if d.Import() != nil { + return nil + } + + n := d.Node + + // This Finalize should not be necessary, as the input to dep is already + // finalized. However, cue cmd uses some legacy instance stitching code + // where some of the backlink Environments are not properly initialized. + // Finalizing should patch those up at the expense of doing some duplicate + // work. The plan is to replace `cue cmd` with a much more clean + // implementation (probably a separate tool called `cuerun`) where this + // issue is fixed. For now we leave this patch. + // + // Note that this issue predates package flow, but that it just surfaced in + // flow and having a different evaluation order. + // + // Note: this call is cheap if n is already Finalized. + n.Finalize(c.opCtx) + + for ; n != nil; n = n.Parent { + if c.cfg.IgnoreConcrete && n.IsConcrete() { + if k := n.BaseValue.Kind(); k != adt.StructKind && k != adt.ListKind { + return nil + } + } + + t, ok := c.nodes[n] + if ok || !c.cfg.InferTasks { + return t + } + + if !d.IsRoot() { + v := value.Make(c.opCtx, n) + + if t := c.getTask(nil, v); t != nil { + return t + } + } + } + + return nil +} + +// markTaskDependencies traces through all conjuncts of a Task and marks +// any dependencies on other tasks. +// +// The dependencies for a node by traversing the nodes of a task and then +// traversing the dependencies of the conjuncts. +// +// This terminates because: +// +// - traversing all nodes of all tasks is guaranteed finite (CUE does not +// evaluate to infinite structure). +// +// - traversing conjuncts of all nodes is finite, as the input syntax is +// inherently finite. +// +// - as regular nodes are traversed recursively they are marked with a cycle +// marker to detect cycles, ensuring a finite traversal as well. +func (c *Controller) markTaskDependencies(t *Task, n *adt.Vertex) { + cfg := &dep.Config{ + Dynamic: true, + } + dep.Visit(cfg, c.opCtx, n, func(d dep.Dependency) error { + depTask := c.findImpliedTask(d) + if depTask != nil { + if depTask != cycleMarker { + v := value.Make(c.opCtx, d.Node) + t.addDep(v.Path().String(), depTask) + } + return nil + } + + // If this points to a non-task node, it may itself point to a task. + // Handling this allows for dynamic references. For instance, such a + // value may reference the result value of a task, or even create + // new tasks based on the result of another task. + if d.Import() == nil { + if c.nodes[d.Node] == cycleMarker { + return nil + } + c.nodes[d.Node] = cycleMarker + d.Recurse() + c.nodes[d.Node] = nil + } + return nil + }) +} + +func (c *Controller) inRoot(n *adt.Vertex) bool { + path := value.Make(c.opCtx, n).Path().Selectors() + root := c.cfg.Root.Selectors() + if len(path) < len(root) { + return false + } + for i, sel := range root { + if path[i] != sel { + return false + } + } + return true +} + +var cycleMarker = &Task{} diff --git a/vendor/github.com/mitchellh/mapstructure/LICENSE b/vendor/github.com/Azure/go-ansiterm/LICENSE similarity index 96% rename from vendor/github.com/mitchellh/mapstructure/LICENSE rename to vendor/github.com/Azure/go-ansiterm/LICENSE index f9c841a51e..e3d9a64d1d 100644 --- a/vendor/github.com/mitchellh/mapstructure/LICENSE +++ b/vendor/github.com/Azure/go-ansiterm/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013 Mitchell Hashimoto +Copyright (c) 2015 Microsoft Corporation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/Azure/go-ansiterm/README.md b/vendor/github.com/Azure/go-ansiterm/README.md new file mode 100644 index 0000000000..261c041e7a --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/README.md @@ -0,0 +1,12 @@ +# go-ansiterm + +This is a cross platform Ansi Terminal Emulation library. It reads a stream of Ansi characters and produces the appropriate function calls. The results of the function calls are platform dependent. + +For example the parser might receive "ESC, [, A" as a stream of three characters. This is the code for Cursor Up (http://www.vt100.net/docs/vt510-rm/CUU). The parser then calls the cursor up function (CUU()) on an event handler. The event handler determines what platform specific work must be done to cause the cursor to move up one position. + +The parser (parser.go) is a partial implementation of this state machine (http://vt100.net/emu/vt500_parser.png). There are also two event handler implementations, one for tests (test_event_handler.go) to validate that the expected events are being produced and called, the other is a Windows implementation (winterm/win_event_handler.go). + +See parser_test.go for examples exercising the state machine and generating appropriate function calls. + +----- +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. diff --git a/vendor/github.com/Azure/go-ansiterm/SECURITY.md b/vendor/github.com/Azure/go-ansiterm/SECURITY.md new file mode 100644 index 0000000000..e138ec5d6a --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/SECURITY.md @@ -0,0 +1,41 @@ + + +## Security + +Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). + +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). + +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). + + diff --git a/vendor/github.com/Azure/go-ansiterm/constants.go b/vendor/github.com/Azure/go-ansiterm/constants.go new file mode 100644 index 0000000000..96504a33bc --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/constants.go @@ -0,0 +1,188 @@ +package ansiterm + +const LogEnv = "DEBUG_TERMINAL" + +// ANSI constants +// References: +// -- http://www.ecma-international.org/publications/standards/Ecma-048.htm +// -- http://man7.org/linux/man-pages/man4/console_codes.4.html +// -- http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html +// -- http://en.wikipedia.org/wiki/ANSI_escape_code +// -- http://vt100.net/emu/dec_ansi_parser +// -- http://vt100.net/emu/vt500_parser.svg +// -- http://invisible-island.net/xterm/ctlseqs/ctlseqs.html +// -- http://www.inwap.com/pdp10/ansicode.txt +const ( + // ECMA-48 Set Graphics Rendition + // Note: + // -- Constants leading with an underscore (e.g., _ANSI_xxx) are unsupported or reserved + // -- Fonts could possibly be supported via SetCurrentConsoleFontEx + // -- Windows does not expose the per-window cursor (i.e., caret) blink times + ANSI_SGR_RESET = 0 + ANSI_SGR_BOLD = 1 + ANSI_SGR_DIM = 2 + _ANSI_SGR_ITALIC = 3 + ANSI_SGR_UNDERLINE = 4 + _ANSI_SGR_BLINKSLOW = 5 + _ANSI_SGR_BLINKFAST = 6 + ANSI_SGR_REVERSE = 7 + _ANSI_SGR_INVISIBLE = 8 + _ANSI_SGR_LINETHROUGH = 9 + _ANSI_SGR_FONT_00 = 10 + _ANSI_SGR_FONT_01 = 11 + _ANSI_SGR_FONT_02 = 12 + _ANSI_SGR_FONT_03 = 13 + _ANSI_SGR_FONT_04 = 14 + _ANSI_SGR_FONT_05 = 15 + _ANSI_SGR_FONT_06 = 16 + _ANSI_SGR_FONT_07 = 17 + _ANSI_SGR_FONT_08 = 18 + _ANSI_SGR_FONT_09 = 19 + _ANSI_SGR_FONT_10 = 20 + _ANSI_SGR_DOUBLEUNDERLINE = 21 + ANSI_SGR_BOLD_DIM_OFF = 22 + _ANSI_SGR_ITALIC_OFF = 23 + ANSI_SGR_UNDERLINE_OFF = 24 + _ANSI_SGR_BLINK_OFF = 25 + _ANSI_SGR_RESERVED_00 = 26 + ANSI_SGR_REVERSE_OFF = 27 + _ANSI_SGR_INVISIBLE_OFF = 28 + _ANSI_SGR_LINETHROUGH_OFF = 29 + ANSI_SGR_FOREGROUND_BLACK = 30 + ANSI_SGR_FOREGROUND_RED = 31 + ANSI_SGR_FOREGROUND_GREEN = 32 + ANSI_SGR_FOREGROUND_YELLOW = 33 + ANSI_SGR_FOREGROUND_BLUE = 34 + ANSI_SGR_FOREGROUND_MAGENTA = 35 + ANSI_SGR_FOREGROUND_CYAN = 36 + ANSI_SGR_FOREGROUND_WHITE = 37 + _ANSI_SGR_RESERVED_01 = 38 + ANSI_SGR_FOREGROUND_DEFAULT = 39 + ANSI_SGR_BACKGROUND_BLACK = 40 + ANSI_SGR_BACKGROUND_RED = 41 + ANSI_SGR_BACKGROUND_GREEN = 42 + ANSI_SGR_BACKGROUND_YELLOW = 43 + ANSI_SGR_BACKGROUND_BLUE = 44 + ANSI_SGR_BACKGROUND_MAGENTA = 45 + ANSI_SGR_BACKGROUND_CYAN = 46 + ANSI_SGR_BACKGROUND_WHITE = 47 + _ANSI_SGR_RESERVED_02 = 48 + ANSI_SGR_BACKGROUND_DEFAULT = 49 + // 50 - 65: Unsupported + + ANSI_MAX_CMD_LENGTH = 4096 + + MAX_INPUT_EVENTS = 128 + DEFAULT_WIDTH = 80 + DEFAULT_HEIGHT = 24 + + ANSI_BEL = 0x07 + ANSI_BACKSPACE = 0x08 + ANSI_TAB = 0x09 + ANSI_LINE_FEED = 0x0A + ANSI_VERTICAL_TAB = 0x0B + ANSI_FORM_FEED = 0x0C + ANSI_CARRIAGE_RETURN = 0x0D + ANSI_ESCAPE_PRIMARY = 0x1B + ANSI_ESCAPE_SECONDARY = 0x5B + ANSI_OSC_STRING_ENTRY = 0x5D + ANSI_COMMAND_FIRST = 0x40 + ANSI_COMMAND_LAST = 0x7E + DCS_ENTRY = 0x90 + CSI_ENTRY = 0x9B + OSC_STRING = 0x9D + ANSI_PARAMETER_SEP = ";" + ANSI_CMD_G0 = '(' + ANSI_CMD_G1 = ')' + ANSI_CMD_G2 = '*' + ANSI_CMD_G3 = '+' + ANSI_CMD_DECPNM = '>' + ANSI_CMD_DECPAM = '=' + ANSI_CMD_OSC = ']' + ANSI_CMD_STR_TERM = '\\' + + KEY_CONTROL_PARAM_2 = ";2" + KEY_CONTROL_PARAM_3 = ";3" + KEY_CONTROL_PARAM_4 = ";4" + KEY_CONTROL_PARAM_5 = ";5" + KEY_CONTROL_PARAM_6 = ";6" + KEY_CONTROL_PARAM_7 = ";7" + KEY_CONTROL_PARAM_8 = ";8" + KEY_ESC_CSI = "\x1B[" + KEY_ESC_N = "\x1BN" + KEY_ESC_O = "\x1BO" + + FILL_CHARACTER = ' ' +) + +func getByteRange(start byte, end byte) []byte { + bytes := make([]byte, 0, 32) + for i := start; i <= end; i++ { + bytes = append(bytes, byte(i)) + } + + return bytes +} + +var toGroundBytes = getToGroundBytes() +var executors = getExecuteBytes() + +// SPACE 20+A0 hex Always and everywhere a blank space +// Intermediate 20-2F hex !"#$%&'()*+,-./ +var intermeds = getByteRange(0x20, 0x2F) + +// Parameters 30-3F hex 0123456789:;<=>? +// CSI Parameters 30-39, 3B hex 0123456789; +var csiParams = getByteRange(0x30, 0x3F) + +var csiCollectables = append(getByteRange(0x30, 0x39), getByteRange(0x3B, 0x3F)...) + +// Uppercase 40-5F hex @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ +var upperCase = getByteRange(0x40, 0x5F) + +// Lowercase 60-7E hex `abcdefghijlkmnopqrstuvwxyz{|}~ +var lowerCase = getByteRange(0x60, 0x7E) + +// Alphabetics 40-7E hex (all of upper and lower case) +var alphabetics = append(upperCase, lowerCase...) + +var printables = getByteRange(0x20, 0x7F) + +var escapeIntermediateToGroundBytes = getByteRange(0x30, 0x7E) +var escapeToGroundBytes = getEscapeToGroundBytes() + +// See http://www.vt100.net/emu/vt500_parser.png for description of the complex +// byte ranges below + +func getEscapeToGroundBytes() []byte { + escapeToGroundBytes := getByteRange(0x30, 0x4F) + escapeToGroundBytes = append(escapeToGroundBytes, getByteRange(0x51, 0x57)...) + escapeToGroundBytes = append(escapeToGroundBytes, 0x59) + escapeToGroundBytes = append(escapeToGroundBytes, 0x5A) + escapeToGroundBytes = append(escapeToGroundBytes, 0x5C) + escapeToGroundBytes = append(escapeToGroundBytes, getByteRange(0x60, 0x7E)...) + return escapeToGroundBytes +} + +func getExecuteBytes() []byte { + executeBytes := getByteRange(0x00, 0x17) + executeBytes = append(executeBytes, 0x19) + executeBytes = append(executeBytes, getByteRange(0x1C, 0x1F)...) + return executeBytes +} + +func getToGroundBytes() []byte { + groundBytes := []byte{0x18} + groundBytes = append(groundBytes, 0x1A) + groundBytes = append(groundBytes, getByteRange(0x80, 0x8F)...) + groundBytes = append(groundBytes, getByteRange(0x91, 0x97)...) + groundBytes = append(groundBytes, 0x99) + groundBytes = append(groundBytes, 0x9A) + groundBytes = append(groundBytes, 0x9C) + return groundBytes +} + +// Delete 7F hex Always and everywhere ignored +// C1 Control 80-9F hex 32 additional control characters +// G1 Displayable A1-FE hex 94 additional displayable characters +// Special A0+FF hex Same as SPACE and DELETE diff --git a/vendor/github.com/Azure/go-ansiterm/context.go b/vendor/github.com/Azure/go-ansiterm/context.go new file mode 100644 index 0000000000..8d66e777c0 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/context.go @@ -0,0 +1,7 @@ +package ansiterm + +type ansiContext struct { + currentChar byte + paramBuffer []byte + interBuffer []byte +} diff --git a/vendor/github.com/Azure/go-ansiterm/csi_entry_state.go b/vendor/github.com/Azure/go-ansiterm/csi_entry_state.go new file mode 100644 index 0000000000..bcbe00d0c5 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/csi_entry_state.go @@ -0,0 +1,49 @@ +package ansiterm + +type csiEntryState struct { + baseState +} + +func (csiState csiEntryState) Handle(b byte) (s state, e error) { + csiState.parser.logf("CsiEntry::Handle %#x", b) + + nextState, err := csiState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case sliceContains(alphabetics, b): + return csiState.parser.ground, nil + case sliceContains(csiCollectables, b): + return csiState.parser.csiParam, nil + case sliceContains(executors, b): + return csiState, csiState.parser.execute() + } + + return csiState, nil +} + +func (csiState csiEntryState) Transition(s state) error { + csiState.parser.logf("CsiEntry::Transition %s --> %s", csiState.Name(), s.Name()) + csiState.baseState.Transition(s) + + switch s { + case csiState.parser.ground: + return csiState.parser.csiDispatch() + case csiState.parser.csiParam: + switch { + case sliceContains(csiParams, csiState.parser.context.currentChar): + csiState.parser.collectParam() + case sliceContains(intermeds, csiState.parser.context.currentChar): + csiState.parser.collectInter() + } + } + + return nil +} + +func (csiState csiEntryState) Enter() error { + csiState.parser.clear() + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/csi_param_state.go b/vendor/github.com/Azure/go-ansiterm/csi_param_state.go new file mode 100644 index 0000000000..7ed5e01c34 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/csi_param_state.go @@ -0,0 +1,38 @@ +package ansiterm + +type csiParamState struct { + baseState +} + +func (csiState csiParamState) Handle(b byte) (s state, e error) { + csiState.parser.logf("CsiParam::Handle %#x", b) + + nextState, err := csiState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case sliceContains(alphabetics, b): + return csiState.parser.ground, nil + case sliceContains(csiCollectables, b): + csiState.parser.collectParam() + return csiState, nil + case sliceContains(executors, b): + return csiState, csiState.parser.execute() + } + + return csiState, nil +} + +func (csiState csiParamState) Transition(s state) error { + csiState.parser.logf("CsiParam::Transition %s --> %s", csiState.Name(), s.Name()) + csiState.baseState.Transition(s) + + switch s { + case csiState.parser.ground: + return csiState.parser.csiDispatch() + } + + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go b/vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go new file mode 100644 index 0000000000..1c719db9e4 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go @@ -0,0 +1,36 @@ +package ansiterm + +type escapeIntermediateState struct { + baseState +} + +func (escState escapeIntermediateState) Handle(b byte) (s state, e error) { + escState.parser.logf("escapeIntermediateState::Handle %#x", b) + nextState, err := escState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case sliceContains(intermeds, b): + return escState, escState.parser.collectInter() + case sliceContains(executors, b): + return escState, escState.parser.execute() + case sliceContains(escapeIntermediateToGroundBytes, b): + return escState.parser.ground, nil + } + + return escState, nil +} + +func (escState escapeIntermediateState) Transition(s state) error { + escState.parser.logf("escapeIntermediateState::Transition %s --> %s", escState.Name(), s.Name()) + escState.baseState.Transition(s) + + switch s { + case escState.parser.ground: + return escState.parser.escDispatch() + } + + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/escape_state.go b/vendor/github.com/Azure/go-ansiterm/escape_state.go new file mode 100644 index 0000000000..6390abd231 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/escape_state.go @@ -0,0 +1,47 @@ +package ansiterm + +type escapeState struct { + baseState +} + +func (escState escapeState) Handle(b byte) (s state, e error) { + escState.parser.logf("escapeState::Handle %#x", b) + nextState, err := escState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case b == ANSI_ESCAPE_SECONDARY: + return escState.parser.csiEntry, nil + case b == ANSI_OSC_STRING_ENTRY: + return escState.parser.oscString, nil + case sliceContains(executors, b): + return escState, escState.parser.execute() + case sliceContains(escapeToGroundBytes, b): + return escState.parser.ground, nil + case sliceContains(intermeds, b): + return escState.parser.escapeIntermediate, nil + } + + return escState, nil +} + +func (escState escapeState) Transition(s state) error { + escState.parser.logf("Escape::Transition %s --> %s", escState.Name(), s.Name()) + escState.baseState.Transition(s) + + switch s { + case escState.parser.ground: + return escState.parser.escDispatch() + case escState.parser.escapeIntermediate: + return escState.parser.collectInter() + } + + return nil +} + +func (escState escapeState) Enter() error { + escState.parser.clear() + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/event_handler.go b/vendor/github.com/Azure/go-ansiterm/event_handler.go new file mode 100644 index 0000000000..98087b38c2 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/event_handler.go @@ -0,0 +1,90 @@ +package ansiterm + +type AnsiEventHandler interface { + // Print + Print(b byte) error + + // Execute C0 commands + Execute(b byte) error + + // CUrsor Up + CUU(int) error + + // CUrsor Down + CUD(int) error + + // CUrsor Forward + CUF(int) error + + // CUrsor Backward + CUB(int) error + + // Cursor to Next Line + CNL(int) error + + // Cursor to Previous Line + CPL(int) error + + // Cursor Horizontal position Absolute + CHA(int) error + + // Vertical line Position Absolute + VPA(int) error + + // CUrsor Position + CUP(int, int) error + + // Horizontal and Vertical Position (depends on PUM) + HVP(int, int) error + + // Text Cursor Enable Mode + DECTCEM(bool) error + + // Origin Mode + DECOM(bool) error + + // 132 Column Mode + DECCOLM(bool) error + + // Erase in Display + ED(int) error + + // Erase in Line + EL(int) error + + // Insert Line + IL(int) error + + // Delete Line + DL(int) error + + // Insert Character + ICH(int) error + + // Delete Character + DCH(int) error + + // Set Graphics Rendition + SGR([]int) error + + // Pan Down + SU(int) error + + // Pan Up + SD(int) error + + // Device Attributes + DA([]string) error + + // Set Top and Bottom Margins + DECSTBM(int, int) error + + // Index + IND() error + + // Reverse Index + RI() error + + // Flush updates from previous commands + Flush() error +} diff --git a/vendor/github.com/Azure/go-ansiterm/ground_state.go b/vendor/github.com/Azure/go-ansiterm/ground_state.go new file mode 100644 index 0000000000..52451e9469 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/ground_state.go @@ -0,0 +1,24 @@ +package ansiterm + +type groundState struct { + baseState +} + +func (gs groundState) Handle(b byte) (s state, e error) { + gs.parser.context.currentChar = b + + nextState, err := gs.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + switch { + case sliceContains(printables, b): + return gs, gs.parser.print() + + case sliceContains(executors, b): + return gs, gs.parser.execute() + } + + return gs, nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/osc_string_state.go b/vendor/github.com/Azure/go-ansiterm/osc_string_state.go new file mode 100644 index 0000000000..194d5e9c94 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/osc_string_state.go @@ -0,0 +1,23 @@ +package ansiterm + +type oscStringState struct { + baseState +} + +func (oscState oscStringState) Handle(b byte) (s state, e error) { + oscState.parser.logf("OscString::Handle %#x", b) + nextState, err := oscState.baseState.Handle(b) + if nextState != nil || err != nil { + return nextState, err + } + + // There are several control characters and sequences which can + // terminate an OSC string. Most of them are handled by the baseState + // handler. The ANSI_BEL character is a special case which behaves as a + // terminator only for an OSC string. + if b == ANSI_BEL { + return oscState.parser.ground, nil + } + + return oscState, nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/parser.go b/vendor/github.com/Azure/go-ansiterm/parser.go new file mode 100644 index 0000000000..03cec7ada6 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/parser.go @@ -0,0 +1,151 @@ +package ansiterm + +import ( + "errors" + "log" + "os" +) + +type AnsiParser struct { + currState state + eventHandler AnsiEventHandler + context *ansiContext + csiEntry state + csiParam state + dcsEntry state + escape state + escapeIntermediate state + error state + ground state + oscString state + stateMap []state + + logf func(string, ...interface{}) +} + +type Option func(*AnsiParser) + +func WithLogf(f func(string, ...interface{})) Option { + return func(ap *AnsiParser) { + ap.logf = f + } +} + +func CreateParser(initialState string, evtHandler AnsiEventHandler, opts ...Option) *AnsiParser { + ap := &AnsiParser{ + eventHandler: evtHandler, + context: &ansiContext{}, + } + for _, o := range opts { + o(ap) + } + + if isDebugEnv := os.Getenv(LogEnv); isDebugEnv == "1" { + logFile, _ := os.Create("ansiParser.log") + logger := log.New(logFile, "", log.LstdFlags) + if ap.logf != nil { + l := ap.logf + ap.logf = func(s string, v ...interface{}) { + l(s, v...) + logger.Printf(s, v...) + } + } else { + ap.logf = logger.Printf + } + } + + if ap.logf == nil { + ap.logf = func(string, ...interface{}) {} + } + + ap.csiEntry = csiEntryState{baseState{name: "CsiEntry", parser: ap}} + ap.csiParam = csiParamState{baseState{name: "CsiParam", parser: ap}} + ap.dcsEntry = dcsEntryState{baseState{name: "DcsEntry", parser: ap}} + ap.escape = escapeState{baseState{name: "Escape", parser: ap}} + ap.escapeIntermediate = escapeIntermediateState{baseState{name: "EscapeIntermediate", parser: ap}} + ap.error = errorState{baseState{name: "Error", parser: ap}} + ap.ground = groundState{baseState{name: "Ground", parser: ap}} + ap.oscString = oscStringState{baseState{name: "OscString", parser: ap}} + + ap.stateMap = []state{ + ap.csiEntry, + ap.csiParam, + ap.dcsEntry, + ap.escape, + ap.escapeIntermediate, + ap.error, + ap.ground, + ap.oscString, + } + + ap.currState = getState(initialState, ap.stateMap) + + ap.logf("CreateParser: parser %p", ap) + return ap +} + +func getState(name string, states []state) state { + for _, el := range states { + if el.Name() == name { + return el + } + } + + return nil +} + +func (ap *AnsiParser) Parse(bytes []byte) (int, error) { + for i, b := range bytes { + if err := ap.handle(b); err != nil { + return i, err + } + } + + return len(bytes), ap.eventHandler.Flush() +} + +func (ap *AnsiParser) handle(b byte) error { + ap.context.currentChar = b + newState, err := ap.currState.Handle(b) + if err != nil { + return err + } + + if newState == nil { + ap.logf("WARNING: newState is nil") + return errors.New("New state of 'nil' is invalid.") + } + + if newState != ap.currState { + if err := ap.changeState(newState); err != nil { + return err + } + } + + return nil +} + +func (ap *AnsiParser) changeState(newState state) error { + ap.logf("ChangeState %s --> %s", ap.currState.Name(), newState.Name()) + + // Exit old state + if err := ap.currState.Exit(); err != nil { + ap.logf("Exit state '%s' failed with : '%v'", ap.currState.Name(), err) + return err + } + + // Perform transition action + if err := ap.currState.Transition(newState); err != nil { + ap.logf("Transition from '%s' to '%s' failed with: '%v'", ap.currState.Name(), newState.Name, err) + return err + } + + // Enter new state + if err := newState.Enter(); err != nil { + ap.logf("Enter state '%s' failed with: '%v'", newState.Name(), err) + return err + } + + ap.currState = newState + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go b/vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go new file mode 100644 index 0000000000..de0a1f9cde --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go @@ -0,0 +1,99 @@ +package ansiterm + +import ( + "strconv" +) + +func parseParams(bytes []byte) ([]string, error) { + paramBuff := make([]byte, 0, 0) + params := []string{} + + for _, v := range bytes { + if v == ';' { + if len(paramBuff) > 0 { + // Completed parameter, append it to the list + s := string(paramBuff) + params = append(params, s) + paramBuff = make([]byte, 0, 0) + } + } else { + paramBuff = append(paramBuff, v) + } + } + + // Last parameter may not be terminated with ';' + if len(paramBuff) > 0 { + s := string(paramBuff) + params = append(params, s) + } + + return params, nil +} + +func parseCmd(context ansiContext) (string, error) { + return string(context.currentChar), nil +} + +func getInt(params []string, dflt int) int { + i := getInts(params, 1, dflt)[0] + return i +} + +func getInts(params []string, minCount int, dflt int) []int { + ints := []int{} + + for _, v := range params { + i, _ := strconv.Atoi(v) + // Zero is mapped to the default value in VT100. + if i == 0 { + i = dflt + } + ints = append(ints, i) + } + + if len(ints) < minCount { + remaining := minCount - len(ints) + for i := 0; i < remaining; i++ { + ints = append(ints, dflt) + } + } + + return ints +} + +func (ap *AnsiParser) modeDispatch(param string, set bool) error { + switch param { + case "?3": + return ap.eventHandler.DECCOLM(set) + case "?6": + return ap.eventHandler.DECOM(set) + case "?25": + return ap.eventHandler.DECTCEM(set) + } + return nil +} + +func (ap *AnsiParser) hDispatch(params []string) error { + if len(params) == 1 { + return ap.modeDispatch(params[0], true) + } + + return nil +} + +func (ap *AnsiParser) lDispatch(params []string) error { + if len(params) == 1 { + return ap.modeDispatch(params[0], false) + } + + return nil +} + +func getEraseParam(params []string) int { + param := getInt(params, 0) + if param < 0 || 3 < param { + param = 0 + } + + return param +} diff --git a/vendor/github.com/Azure/go-ansiterm/parser_actions.go b/vendor/github.com/Azure/go-ansiterm/parser_actions.go new file mode 100644 index 0000000000..0bb5e51e9a --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/parser_actions.go @@ -0,0 +1,119 @@ +package ansiterm + +func (ap *AnsiParser) collectParam() error { + currChar := ap.context.currentChar + ap.logf("collectParam %#x", currChar) + ap.context.paramBuffer = append(ap.context.paramBuffer, currChar) + return nil +} + +func (ap *AnsiParser) collectInter() error { + currChar := ap.context.currentChar + ap.logf("collectInter %#x", currChar) + ap.context.paramBuffer = append(ap.context.interBuffer, currChar) + return nil +} + +func (ap *AnsiParser) escDispatch() error { + cmd, _ := parseCmd(*ap.context) + intermeds := ap.context.interBuffer + ap.logf("escDispatch currentChar: %#x", ap.context.currentChar) + ap.logf("escDispatch: %v(%v)", cmd, intermeds) + + switch cmd { + case "D": // IND + return ap.eventHandler.IND() + case "E": // NEL, equivalent to CRLF + err := ap.eventHandler.Execute(ANSI_CARRIAGE_RETURN) + if err == nil { + err = ap.eventHandler.Execute(ANSI_LINE_FEED) + } + return err + case "M": // RI + return ap.eventHandler.RI() + } + + return nil +} + +func (ap *AnsiParser) csiDispatch() error { + cmd, _ := parseCmd(*ap.context) + params, _ := parseParams(ap.context.paramBuffer) + ap.logf("Parsed params: %v with length: %d", params, len(params)) + + ap.logf("csiDispatch: %v(%v)", cmd, params) + + switch cmd { + case "@": + return ap.eventHandler.ICH(getInt(params, 1)) + case "A": + return ap.eventHandler.CUU(getInt(params, 1)) + case "B": + return ap.eventHandler.CUD(getInt(params, 1)) + case "C": + return ap.eventHandler.CUF(getInt(params, 1)) + case "D": + return ap.eventHandler.CUB(getInt(params, 1)) + case "E": + return ap.eventHandler.CNL(getInt(params, 1)) + case "F": + return ap.eventHandler.CPL(getInt(params, 1)) + case "G": + return ap.eventHandler.CHA(getInt(params, 1)) + case "H": + ints := getInts(params, 2, 1) + x, y := ints[0], ints[1] + return ap.eventHandler.CUP(x, y) + case "J": + param := getEraseParam(params) + return ap.eventHandler.ED(param) + case "K": + param := getEraseParam(params) + return ap.eventHandler.EL(param) + case "L": + return ap.eventHandler.IL(getInt(params, 1)) + case "M": + return ap.eventHandler.DL(getInt(params, 1)) + case "P": + return ap.eventHandler.DCH(getInt(params, 1)) + case "S": + return ap.eventHandler.SU(getInt(params, 1)) + case "T": + return ap.eventHandler.SD(getInt(params, 1)) + case "c": + return ap.eventHandler.DA(params) + case "d": + return ap.eventHandler.VPA(getInt(params, 1)) + case "f": + ints := getInts(params, 2, 1) + x, y := ints[0], ints[1] + return ap.eventHandler.HVP(x, y) + case "h": + return ap.hDispatch(params) + case "l": + return ap.lDispatch(params) + case "m": + return ap.eventHandler.SGR(getInts(params, 1, 0)) + case "r": + ints := getInts(params, 2, 1) + top, bottom := ints[0], ints[1] + return ap.eventHandler.DECSTBM(top, bottom) + default: + ap.logf("ERROR: Unsupported CSI command: '%s', with full context: %v", cmd, ap.context) + return nil + } + +} + +func (ap *AnsiParser) print() error { + return ap.eventHandler.Print(ap.context.currentChar) +} + +func (ap *AnsiParser) clear() error { + ap.context = &ansiContext{} + return nil +} + +func (ap *AnsiParser) execute() error { + return ap.eventHandler.Execute(ap.context.currentChar) +} diff --git a/vendor/github.com/Azure/go-ansiterm/states.go b/vendor/github.com/Azure/go-ansiterm/states.go new file mode 100644 index 0000000000..f2ea1fcd12 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/states.go @@ -0,0 +1,71 @@ +package ansiterm + +type stateID int + +type state interface { + Enter() error + Exit() error + Handle(byte) (state, error) + Name() string + Transition(state) error +} + +type baseState struct { + name string + parser *AnsiParser +} + +func (base baseState) Enter() error { + return nil +} + +func (base baseState) Exit() error { + return nil +} + +func (base baseState) Handle(b byte) (s state, e error) { + + switch { + case b == CSI_ENTRY: + return base.parser.csiEntry, nil + case b == DCS_ENTRY: + return base.parser.dcsEntry, nil + case b == ANSI_ESCAPE_PRIMARY: + return base.parser.escape, nil + case b == OSC_STRING: + return base.parser.oscString, nil + case sliceContains(toGroundBytes, b): + return base.parser.ground, nil + } + + return nil, nil +} + +func (base baseState) Name() string { + return base.name +} + +func (base baseState) Transition(s state) error { + if s == base.parser.ground { + execBytes := []byte{0x18} + execBytes = append(execBytes, 0x1A) + execBytes = append(execBytes, getByteRange(0x80, 0x8F)...) + execBytes = append(execBytes, getByteRange(0x91, 0x97)...) + execBytes = append(execBytes, 0x99) + execBytes = append(execBytes, 0x9A) + + if sliceContains(execBytes, base.parser.context.currentChar) { + return base.parser.execute() + } + } + + return nil +} + +type dcsEntryState struct { + baseState +} + +type errorState struct { + baseState +} diff --git a/vendor/github.com/Azure/go-ansiterm/utilities.go b/vendor/github.com/Azure/go-ansiterm/utilities.go new file mode 100644 index 0000000000..392114493a --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/utilities.go @@ -0,0 +1,21 @@ +package ansiterm + +import ( + "strconv" +) + +func sliceContains(bytes []byte, b byte) bool { + for _, v := range bytes { + if v == b { + return true + } + } + + return false +} + +func convertBytesToInteger(bytes []byte) int { + s := string(bytes) + i, _ := strconv.Atoi(s) + return i +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/ansi.go b/vendor/github.com/Azure/go-ansiterm/winterm/ansi.go new file mode 100644 index 0000000000..5599082ae9 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/ansi.go @@ -0,0 +1,196 @@ +// +build windows + +package winterm + +import ( + "fmt" + "os" + "strconv" + "strings" + "syscall" + + "github.com/Azure/go-ansiterm" + windows "golang.org/x/sys/windows" +) + +// Windows keyboard constants +// See https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx. +const ( + VK_PRIOR = 0x21 // PAGE UP key + VK_NEXT = 0x22 // PAGE DOWN key + VK_END = 0x23 // END key + VK_HOME = 0x24 // HOME key + VK_LEFT = 0x25 // LEFT ARROW key + VK_UP = 0x26 // UP ARROW key + VK_RIGHT = 0x27 // RIGHT ARROW key + VK_DOWN = 0x28 // DOWN ARROW key + VK_SELECT = 0x29 // SELECT key + VK_PRINT = 0x2A // PRINT key + VK_EXECUTE = 0x2B // EXECUTE key + VK_SNAPSHOT = 0x2C // PRINT SCREEN key + VK_INSERT = 0x2D // INS key + VK_DELETE = 0x2E // DEL key + VK_HELP = 0x2F // HELP key + VK_F1 = 0x70 // F1 key + VK_F2 = 0x71 // F2 key + VK_F3 = 0x72 // F3 key + VK_F4 = 0x73 // F4 key + VK_F5 = 0x74 // F5 key + VK_F6 = 0x75 // F6 key + VK_F7 = 0x76 // F7 key + VK_F8 = 0x77 // F8 key + VK_F9 = 0x78 // F9 key + VK_F10 = 0x79 // F10 key + VK_F11 = 0x7A // F11 key + VK_F12 = 0x7B // F12 key + + RIGHT_ALT_PRESSED = 0x0001 + LEFT_ALT_PRESSED = 0x0002 + RIGHT_CTRL_PRESSED = 0x0004 + LEFT_CTRL_PRESSED = 0x0008 + SHIFT_PRESSED = 0x0010 + NUMLOCK_ON = 0x0020 + SCROLLLOCK_ON = 0x0040 + CAPSLOCK_ON = 0x0080 + ENHANCED_KEY = 0x0100 +) + +type ansiCommand struct { + CommandBytes []byte + Command string + Parameters []string + IsSpecial bool +} + +func newAnsiCommand(command []byte) *ansiCommand { + + if isCharacterSelectionCmdChar(command[1]) { + // Is Character Set Selection commands + return &ansiCommand{ + CommandBytes: command, + Command: string(command), + IsSpecial: true, + } + } + + // last char is command character + lastCharIndex := len(command) - 1 + + ac := &ansiCommand{ + CommandBytes: command, + Command: string(command[lastCharIndex]), + IsSpecial: false, + } + + // more than a single escape + if lastCharIndex != 0 { + start := 1 + // skip if double char escape sequence + if command[0] == ansiterm.ANSI_ESCAPE_PRIMARY && command[1] == ansiterm.ANSI_ESCAPE_SECONDARY { + start++ + } + // convert this to GetNextParam method + ac.Parameters = strings.Split(string(command[start:lastCharIndex]), ansiterm.ANSI_PARAMETER_SEP) + } + + return ac +} + +func (ac *ansiCommand) paramAsSHORT(index int, defaultValue int16) int16 { + if index < 0 || index >= len(ac.Parameters) { + return defaultValue + } + + param, err := strconv.ParseInt(ac.Parameters[index], 10, 16) + if err != nil { + return defaultValue + } + + return int16(param) +} + +func (ac *ansiCommand) String() string { + return fmt.Sprintf("0x%v \"%v\" (\"%v\")", + bytesToHex(ac.CommandBytes), + ac.Command, + strings.Join(ac.Parameters, "\",\"")) +} + +// isAnsiCommandChar returns true if the passed byte falls within the range of ANSI commands. +// See http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html. +func isAnsiCommandChar(b byte) bool { + switch { + case ansiterm.ANSI_COMMAND_FIRST <= b && b <= ansiterm.ANSI_COMMAND_LAST && b != ansiterm.ANSI_ESCAPE_SECONDARY: + return true + case b == ansiterm.ANSI_CMD_G1 || b == ansiterm.ANSI_CMD_OSC || b == ansiterm.ANSI_CMD_DECPAM || b == ansiterm.ANSI_CMD_DECPNM: + // non-CSI escape sequence terminator + return true + case b == ansiterm.ANSI_CMD_STR_TERM || b == ansiterm.ANSI_BEL: + // String escape sequence terminator + return true + } + return false +} + +func isXtermOscSequence(command []byte, current byte) bool { + return (len(command) >= 2 && command[0] == ansiterm.ANSI_ESCAPE_PRIMARY && command[1] == ansiterm.ANSI_CMD_OSC && current != ansiterm.ANSI_BEL) +} + +func isCharacterSelectionCmdChar(b byte) bool { + return (b == ansiterm.ANSI_CMD_G0 || b == ansiterm.ANSI_CMD_G1 || b == ansiterm.ANSI_CMD_G2 || b == ansiterm.ANSI_CMD_G3) +} + +// bytesToHex converts a slice of bytes to a human-readable string. +func bytesToHex(b []byte) string { + hex := make([]string, len(b)) + for i, ch := range b { + hex[i] = fmt.Sprintf("%X", ch) + } + return strings.Join(hex, "") +} + +// ensureInRange adjusts the passed value, if necessary, to ensure it is within +// the passed min / max range. +func ensureInRange(n int16, min int16, max int16) int16 { + if n < min { + return min + } else if n > max { + return max + } else { + return n + } +} + +func GetStdFile(nFile int) (*os.File, uintptr) { + var file *os.File + + // syscall uses negative numbers + // windows package uses very big uint32 + // Keep these switches split so we don't have to convert ints too much. + switch uint32(nFile) { + case windows.STD_INPUT_HANDLE: + file = os.Stdin + case windows.STD_OUTPUT_HANDLE: + file = os.Stdout + case windows.STD_ERROR_HANDLE: + file = os.Stderr + default: + switch nFile { + case syscall.STD_INPUT_HANDLE: + file = os.Stdin + case syscall.STD_OUTPUT_HANDLE: + file = os.Stdout + case syscall.STD_ERROR_HANDLE: + file = os.Stderr + default: + panic(fmt.Errorf("Invalid standard handle identifier: %v", nFile)) + } + } + + fd, err := syscall.GetStdHandle(nFile) + if err != nil { + panic(fmt.Errorf("Invalid standard handle identifier: %v -- %v", nFile, err)) + } + + return file, uintptr(fd) +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/api.go b/vendor/github.com/Azure/go-ansiterm/winterm/api.go new file mode 100644 index 0000000000..6055e33b91 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/api.go @@ -0,0 +1,327 @@ +// +build windows + +package winterm + +import ( + "fmt" + "syscall" + "unsafe" +) + +//=========================================================================================================== +// IMPORTANT NOTE: +// +// The methods below make extensive use of the "unsafe" package to obtain the required pointers. +// Beginning in Go 1.3, the garbage collector may release local variables (e.g., incoming arguments, stack +// variables) the pointers reference *before* the API completes. +// +// As a result, in those cases, the code must hint that the variables remain in active by invoking the +// dummy method "use" (see below). Newer versions of Go are planned to change the mechanism to no longer +// require unsafe pointers. +// +// If you add or modify methods, ENSURE protection of local variables through the "use" builtin to inform +// the garbage collector the variables remain in use if: +// +// -- The value is not a pointer (e.g., int32, struct) +// -- The value is not referenced by the method after passing the pointer to Windows +// +// See http://golang.org/doc/go1.3. +//=========================================================================================================== + +var ( + kernel32DLL = syscall.NewLazyDLL("kernel32.dll") + + getConsoleCursorInfoProc = kernel32DLL.NewProc("GetConsoleCursorInfo") + setConsoleCursorInfoProc = kernel32DLL.NewProc("SetConsoleCursorInfo") + setConsoleCursorPositionProc = kernel32DLL.NewProc("SetConsoleCursorPosition") + setConsoleModeProc = kernel32DLL.NewProc("SetConsoleMode") + getConsoleScreenBufferInfoProc = kernel32DLL.NewProc("GetConsoleScreenBufferInfo") + setConsoleScreenBufferSizeProc = kernel32DLL.NewProc("SetConsoleScreenBufferSize") + scrollConsoleScreenBufferProc = kernel32DLL.NewProc("ScrollConsoleScreenBufferA") + setConsoleTextAttributeProc = kernel32DLL.NewProc("SetConsoleTextAttribute") + setConsoleWindowInfoProc = kernel32DLL.NewProc("SetConsoleWindowInfo") + writeConsoleOutputProc = kernel32DLL.NewProc("WriteConsoleOutputW") + readConsoleInputProc = kernel32DLL.NewProc("ReadConsoleInputW") + waitForSingleObjectProc = kernel32DLL.NewProc("WaitForSingleObject") +) + +// Windows Console constants +const ( + // Console modes + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx. + ENABLE_PROCESSED_INPUT = 0x0001 + ENABLE_LINE_INPUT = 0x0002 + ENABLE_ECHO_INPUT = 0x0004 + ENABLE_WINDOW_INPUT = 0x0008 + ENABLE_MOUSE_INPUT = 0x0010 + ENABLE_INSERT_MODE = 0x0020 + ENABLE_QUICK_EDIT_MODE = 0x0040 + ENABLE_EXTENDED_FLAGS = 0x0080 + ENABLE_AUTO_POSITION = 0x0100 + ENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200 + + ENABLE_PROCESSED_OUTPUT = 0x0001 + ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002 + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 + DISABLE_NEWLINE_AUTO_RETURN = 0x0008 + ENABLE_LVB_GRID_WORLDWIDE = 0x0010 + + // Character attributes + // Note: + // -- The attributes are combined to produce various colors (e.g., Blue + Green will create Cyan). + // Clearing all foreground or background colors results in black; setting all creates white. + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes. + FOREGROUND_BLUE uint16 = 0x0001 + FOREGROUND_GREEN uint16 = 0x0002 + FOREGROUND_RED uint16 = 0x0004 + FOREGROUND_INTENSITY uint16 = 0x0008 + FOREGROUND_MASK uint16 = 0x000F + + BACKGROUND_BLUE uint16 = 0x0010 + BACKGROUND_GREEN uint16 = 0x0020 + BACKGROUND_RED uint16 = 0x0040 + BACKGROUND_INTENSITY uint16 = 0x0080 + BACKGROUND_MASK uint16 = 0x00F0 + + COMMON_LVB_MASK uint16 = 0xFF00 + COMMON_LVB_REVERSE_VIDEO uint16 = 0x4000 + COMMON_LVB_UNDERSCORE uint16 = 0x8000 + + // Input event types + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx. + KEY_EVENT = 0x0001 + MOUSE_EVENT = 0x0002 + WINDOW_BUFFER_SIZE_EVENT = 0x0004 + MENU_EVENT = 0x0008 + FOCUS_EVENT = 0x0010 + + // WaitForSingleObject return codes + WAIT_ABANDONED = 0x00000080 + WAIT_FAILED = 0xFFFFFFFF + WAIT_SIGNALED = 0x0000000 + WAIT_TIMEOUT = 0x00000102 + + // WaitForSingleObject wait duration + WAIT_INFINITE = 0xFFFFFFFF + WAIT_ONE_SECOND = 1000 + WAIT_HALF_SECOND = 500 + WAIT_QUARTER_SECOND = 250 +) + +// Windows API Console types +// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682101(v=vs.85).aspx for Console specific types (e.g., COORD) +// -- See https://msdn.microsoft.com/en-us/library/aa296569(v=vs.60).aspx for comments on alignment +type ( + CHAR_INFO struct { + UnicodeChar uint16 + Attributes uint16 + } + + CONSOLE_CURSOR_INFO struct { + Size uint32 + Visible int32 + } + + CONSOLE_SCREEN_BUFFER_INFO struct { + Size COORD + CursorPosition COORD + Attributes uint16 + Window SMALL_RECT + MaximumWindowSize COORD + } + + COORD struct { + X int16 + Y int16 + } + + SMALL_RECT struct { + Left int16 + Top int16 + Right int16 + Bottom int16 + } + + // INPUT_RECORD is a C/C++ union of which KEY_EVENT_RECORD is one case, it is also the largest + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx. + INPUT_RECORD struct { + EventType uint16 + KeyEvent KEY_EVENT_RECORD + } + + KEY_EVENT_RECORD struct { + KeyDown int32 + RepeatCount uint16 + VirtualKeyCode uint16 + VirtualScanCode uint16 + UnicodeChar uint16 + ControlKeyState uint32 + } + + WINDOW_BUFFER_SIZE struct { + Size COORD + } +) + +// boolToBOOL converts a Go bool into a Windows int32. +func boolToBOOL(f bool) int32 { + if f { + return int32(1) + } else { + return int32(0) + } +} + +// GetConsoleCursorInfo retrieves information about the size and visiblity of the console cursor. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683163(v=vs.85).aspx. +func GetConsoleCursorInfo(handle uintptr, cursorInfo *CONSOLE_CURSOR_INFO) error { + r1, r2, err := getConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0) + return checkError(r1, r2, err) +} + +// SetConsoleCursorInfo sets the size and visiblity of the console cursor. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686019(v=vs.85).aspx. +func SetConsoleCursorInfo(handle uintptr, cursorInfo *CONSOLE_CURSOR_INFO) error { + r1, r2, err := setConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0) + return checkError(r1, r2, err) +} + +// SetConsoleCursorPosition location of the console cursor. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx. +func SetConsoleCursorPosition(handle uintptr, coord COORD) error { + r1, r2, err := setConsoleCursorPositionProc.Call(handle, coordToPointer(coord)) + use(coord) + return checkError(r1, r2, err) +} + +// GetConsoleMode gets the console mode for given file descriptor +// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx. +func GetConsoleMode(handle uintptr) (mode uint32, err error) { + err = syscall.GetConsoleMode(syscall.Handle(handle), &mode) + return mode, err +} + +// SetConsoleMode sets the console mode for given file descriptor +// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx. +func SetConsoleMode(handle uintptr, mode uint32) error { + r1, r2, err := setConsoleModeProc.Call(handle, uintptr(mode), 0) + use(mode) + return checkError(r1, r2, err) +} + +// GetConsoleScreenBufferInfo retrieves information about the specified console screen buffer. +// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx. +func GetConsoleScreenBufferInfo(handle uintptr) (*CONSOLE_SCREEN_BUFFER_INFO, error) { + info := CONSOLE_SCREEN_BUFFER_INFO{} + err := checkError(getConsoleScreenBufferInfoProc.Call(handle, uintptr(unsafe.Pointer(&info)), 0)) + if err != nil { + return nil, err + } + return &info, nil +} + +func ScrollConsoleScreenBuffer(handle uintptr, scrollRect SMALL_RECT, clipRect SMALL_RECT, destOrigin COORD, char CHAR_INFO) error { + r1, r2, err := scrollConsoleScreenBufferProc.Call(handle, uintptr(unsafe.Pointer(&scrollRect)), uintptr(unsafe.Pointer(&clipRect)), coordToPointer(destOrigin), uintptr(unsafe.Pointer(&char))) + use(scrollRect) + use(clipRect) + use(destOrigin) + use(char) + return checkError(r1, r2, err) +} + +// SetConsoleScreenBufferSize sets the size of the console screen buffer. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686044(v=vs.85).aspx. +func SetConsoleScreenBufferSize(handle uintptr, coord COORD) error { + r1, r2, err := setConsoleScreenBufferSizeProc.Call(handle, coordToPointer(coord)) + use(coord) + return checkError(r1, r2, err) +} + +// SetConsoleTextAttribute sets the attributes of characters written to the +// console screen buffer by the WriteFile or WriteConsole function. +// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047(v=vs.85).aspx. +func SetConsoleTextAttribute(handle uintptr, attribute uint16) error { + r1, r2, err := setConsoleTextAttributeProc.Call(handle, uintptr(attribute), 0) + use(attribute) + return checkError(r1, r2, err) +} + +// SetConsoleWindowInfo sets the size and position of the console screen buffer's window. +// Note that the size and location must be within and no larger than the backing console screen buffer. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686125(v=vs.85).aspx. +func SetConsoleWindowInfo(handle uintptr, isAbsolute bool, rect SMALL_RECT) error { + r1, r2, err := setConsoleWindowInfoProc.Call(handle, uintptr(boolToBOOL(isAbsolute)), uintptr(unsafe.Pointer(&rect))) + use(isAbsolute) + use(rect) + return checkError(r1, r2, err) +} + +// WriteConsoleOutput writes the CHAR_INFOs from the provided buffer to the active console buffer. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687404(v=vs.85).aspx. +func WriteConsoleOutput(handle uintptr, buffer []CHAR_INFO, bufferSize COORD, bufferCoord COORD, writeRegion *SMALL_RECT) error { + r1, r2, err := writeConsoleOutputProc.Call(handle, uintptr(unsafe.Pointer(&buffer[0])), coordToPointer(bufferSize), coordToPointer(bufferCoord), uintptr(unsafe.Pointer(writeRegion))) + use(buffer) + use(bufferSize) + use(bufferCoord) + return checkError(r1, r2, err) +} + +// ReadConsoleInput reads (and removes) data from the console input buffer. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684961(v=vs.85).aspx. +func ReadConsoleInput(handle uintptr, buffer []INPUT_RECORD, count *uint32) error { + r1, r2, err := readConsoleInputProc.Call(handle, uintptr(unsafe.Pointer(&buffer[0])), uintptr(len(buffer)), uintptr(unsafe.Pointer(count))) + use(buffer) + return checkError(r1, r2, err) +} + +// WaitForSingleObject waits for the passed handle to be signaled. +// It returns true if the handle was signaled; false otherwise. +// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx. +func WaitForSingleObject(handle uintptr, msWait uint32) (bool, error) { + r1, _, err := waitForSingleObjectProc.Call(handle, uintptr(uint32(msWait))) + switch r1 { + case WAIT_ABANDONED, WAIT_TIMEOUT: + return false, nil + case WAIT_SIGNALED: + return true, nil + } + use(msWait) + return false, err +} + +// String helpers +func (info CONSOLE_SCREEN_BUFFER_INFO) String() string { + return fmt.Sprintf("Size(%v) Cursor(%v) Window(%v) Max(%v)", info.Size, info.CursorPosition, info.Window, info.MaximumWindowSize) +} + +func (coord COORD) String() string { + return fmt.Sprintf("%v,%v", coord.X, coord.Y) +} + +func (rect SMALL_RECT) String() string { + return fmt.Sprintf("(%v,%v),(%v,%v)", rect.Left, rect.Top, rect.Right, rect.Bottom) +} + +// checkError evaluates the results of a Windows API call and returns the error if it failed. +func checkError(r1, r2 uintptr, err error) error { + // Windows APIs return non-zero to indicate success + if r1 != 0 { + return nil + } + + // Return the error if provided, otherwise default to EINVAL + if err != nil { + return err + } + return syscall.EINVAL +} + +// coordToPointer converts a COORD into a uintptr (by fooling the type system). +func coordToPointer(c COORD) uintptr { + // Note: This code assumes the two SHORTs are correctly laid out; the "cast" to uint32 is just to get a pointer to pass. + return uintptr(*((*uint32)(unsafe.Pointer(&c)))) +} + +// use is a no-op, but the compiler cannot see that it is. +// Calling use(p) ensures that p is kept live until that point. +func use(p interface{}) {} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go b/vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go new file mode 100644 index 0000000000..cbec8f728f --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go @@ -0,0 +1,100 @@ +// +build windows + +package winterm + +import "github.com/Azure/go-ansiterm" + +const ( + FOREGROUND_COLOR_MASK = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE + BACKGROUND_COLOR_MASK = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE +) + +// collectAnsiIntoWindowsAttributes modifies the passed Windows text mode flags to reflect the +// request represented by the passed ANSI mode. +func collectAnsiIntoWindowsAttributes(windowsMode uint16, inverted bool, baseMode uint16, ansiMode int16) (uint16, bool) { + switch ansiMode { + + // Mode styles + case ansiterm.ANSI_SGR_BOLD: + windowsMode = windowsMode | FOREGROUND_INTENSITY + + case ansiterm.ANSI_SGR_DIM, ansiterm.ANSI_SGR_BOLD_DIM_OFF: + windowsMode &^= FOREGROUND_INTENSITY + + case ansiterm.ANSI_SGR_UNDERLINE: + windowsMode = windowsMode | COMMON_LVB_UNDERSCORE + + case ansiterm.ANSI_SGR_REVERSE: + inverted = true + + case ansiterm.ANSI_SGR_REVERSE_OFF: + inverted = false + + case ansiterm.ANSI_SGR_UNDERLINE_OFF: + windowsMode &^= COMMON_LVB_UNDERSCORE + + // Foreground colors + case ansiterm.ANSI_SGR_FOREGROUND_DEFAULT: + windowsMode = (windowsMode &^ FOREGROUND_MASK) | (baseMode & FOREGROUND_MASK) + + case ansiterm.ANSI_SGR_FOREGROUND_BLACK: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) + + case ansiterm.ANSI_SGR_FOREGROUND_RED: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED + + case ansiterm.ANSI_SGR_FOREGROUND_GREEN: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN + + case ansiterm.ANSI_SGR_FOREGROUND_YELLOW: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN + + case ansiterm.ANSI_SGR_FOREGROUND_BLUE: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_BLUE + + case ansiterm.ANSI_SGR_FOREGROUND_MAGENTA: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_BLUE + + case ansiterm.ANSI_SGR_FOREGROUND_CYAN: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN | FOREGROUND_BLUE + + case ansiterm.ANSI_SGR_FOREGROUND_WHITE: + windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE + + // Background colors + case ansiterm.ANSI_SGR_BACKGROUND_DEFAULT: + // Black with no intensity + windowsMode = (windowsMode &^ BACKGROUND_MASK) | (baseMode & BACKGROUND_MASK) + + case ansiterm.ANSI_SGR_BACKGROUND_BLACK: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) + + case ansiterm.ANSI_SGR_BACKGROUND_RED: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED + + case ansiterm.ANSI_SGR_BACKGROUND_GREEN: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN + + case ansiterm.ANSI_SGR_BACKGROUND_YELLOW: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN + + case ansiterm.ANSI_SGR_BACKGROUND_BLUE: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_BLUE + + case ansiterm.ANSI_SGR_BACKGROUND_MAGENTA: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_BLUE + + case ansiterm.ANSI_SGR_BACKGROUND_CYAN: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN | BACKGROUND_BLUE + + case ansiterm.ANSI_SGR_BACKGROUND_WHITE: + windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE + } + + return windowsMode, inverted +} + +// invertAttributes inverts the foreground and background colors of a Windows attributes value +func invertAttributes(windowsMode uint16) uint16 { + return (COMMON_LVB_MASK & windowsMode) | ((FOREGROUND_MASK & windowsMode) << 4) | ((BACKGROUND_MASK & windowsMode) >> 4) +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go b/vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go new file mode 100644 index 0000000000..3ee06ea728 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go @@ -0,0 +1,101 @@ +// +build windows + +package winterm + +const ( + horizontal = iota + vertical +) + +func (h *windowsAnsiEventHandler) getCursorWindow(info *CONSOLE_SCREEN_BUFFER_INFO) SMALL_RECT { + if h.originMode { + sr := h.effectiveSr(info.Window) + return SMALL_RECT{ + Top: sr.top, + Bottom: sr.bottom, + Left: 0, + Right: info.Size.X - 1, + } + } else { + return SMALL_RECT{ + Top: info.Window.Top, + Bottom: info.Window.Bottom, + Left: 0, + Right: info.Size.X - 1, + } + } +} + +// setCursorPosition sets the cursor to the specified position, bounded to the screen size +func (h *windowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL_RECT) error { + position.X = ensureInRange(position.X, window.Left, window.Right) + position.Y = ensureInRange(position.Y, window.Top, window.Bottom) + err := SetConsoleCursorPosition(h.fd, position) + if err != nil { + return err + } + h.logf("Cursor position set: (%d, %d)", position.X, position.Y) + return err +} + +func (h *windowsAnsiEventHandler) moveCursorVertical(param int) error { + return h.moveCursor(vertical, param) +} + +func (h *windowsAnsiEventHandler) moveCursorHorizontal(param int) error { + return h.moveCursor(horizontal, param) +} + +func (h *windowsAnsiEventHandler) moveCursor(moveMode int, param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + position := info.CursorPosition + switch moveMode { + case horizontal: + position.X += int16(param) + case vertical: + position.Y += int16(param) + } + + if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) moveCursorLine(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + position := info.CursorPosition + position.X = 0 + position.Y += int16(param) + + if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) moveCursorColumn(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + position := info.CursorPosition + position.X = int16(param) - 1 + + if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go b/vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go new file mode 100644 index 0000000000..244b5fa25e --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go @@ -0,0 +1,84 @@ +// +build windows + +package winterm + +import "github.com/Azure/go-ansiterm" + +func (h *windowsAnsiEventHandler) clearRange(attributes uint16, fromCoord COORD, toCoord COORD) error { + // Ignore an invalid (negative area) request + if toCoord.Y < fromCoord.Y { + return nil + } + + var err error + + var coordStart = COORD{} + var coordEnd = COORD{} + + xCurrent, yCurrent := fromCoord.X, fromCoord.Y + xEnd, yEnd := toCoord.X, toCoord.Y + + // Clear any partial initial line + if xCurrent > 0 { + coordStart.X, coordStart.Y = xCurrent, yCurrent + coordEnd.X, coordEnd.Y = xEnd, yCurrent + + err = h.clearRect(attributes, coordStart, coordEnd) + if err != nil { + return err + } + + xCurrent = 0 + yCurrent += 1 + } + + // Clear intervening rectangular section + if yCurrent < yEnd { + coordStart.X, coordStart.Y = xCurrent, yCurrent + coordEnd.X, coordEnd.Y = xEnd, yEnd-1 + + err = h.clearRect(attributes, coordStart, coordEnd) + if err != nil { + return err + } + + xCurrent = 0 + yCurrent = yEnd + } + + // Clear remaining partial ending line + coordStart.X, coordStart.Y = xCurrent, yCurrent + coordEnd.X, coordEnd.Y = xEnd, yEnd + + err = h.clearRect(attributes, coordStart, coordEnd) + if err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) clearRect(attributes uint16, fromCoord COORD, toCoord COORD) error { + region := SMALL_RECT{Top: fromCoord.Y, Left: fromCoord.X, Bottom: toCoord.Y, Right: toCoord.X} + width := toCoord.X - fromCoord.X + 1 + height := toCoord.Y - fromCoord.Y + 1 + size := uint32(width) * uint32(height) + + if size <= 0 { + return nil + } + + buffer := make([]CHAR_INFO, size) + + char := CHAR_INFO{ansiterm.FILL_CHARACTER, attributes} + for i := 0; i < int(size); i++ { + buffer[i] = char + } + + err := WriteConsoleOutput(h.fd, buffer, COORD{X: width, Y: height}, COORD{X: 0, Y: 0}, ®ion) + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go b/vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go new file mode 100644 index 0000000000..2d27fa1d02 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go @@ -0,0 +1,118 @@ +// +build windows + +package winterm + +// effectiveSr gets the current effective scroll region in buffer coordinates +func (h *windowsAnsiEventHandler) effectiveSr(window SMALL_RECT) scrollRegion { + top := addInRange(window.Top, h.sr.top, window.Top, window.Bottom) + bottom := addInRange(window.Top, h.sr.bottom, window.Top, window.Bottom) + if top >= bottom { + top = window.Top + bottom = window.Bottom + } + return scrollRegion{top: top, bottom: bottom} +} + +func (h *windowsAnsiEventHandler) scrollUp(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + sr := h.effectiveSr(info.Window) + return h.scroll(param, sr, info) +} + +func (h *windowsAnsiEventHandler) scrollDown(param int) error { + return h.scrollUp(-param) +} + +func (h *windowsAnsiEventHandler) deleteLines(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + start := info.CursorPosition.Y + sr := h.effectiveSr(info.Window) + // Lines cannot be inserted or deleted outside the scrolling region. + if start >= sr.top && start <= sr.bottom { + sr.top = start + return h.scroll(param, sr, info) + } else { + return nil + } +} + +func (h *windowsAnsiEventHandler) insertLines(param int) error { + return h.deleteLines(-param) +} + +// scroll scrolls the provided scroll region by param lines. The scroll region is in buffer coordinates. +func (h *windowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSOLE_SCREEN_BUFFER_INFO) error { + h.logf("scroll: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom) + h.logf("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom) + + // Copy from and clip to the scroll region (full buffer width) + scrollRect := SMALL_RECT{ + Top: sr.top, + Bottom: sr.bottom, + Left: 0, + Right: info.Size.X - 1, + } + + // Origin to which area should be copied + destOrigin := COORD{ + X: 0, + Y: sr.top - int16(param), + } + + char := CHAR_INFO{ + UnicodeChar: ' ', + Attributes: h.attributes, + } + + if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil { + return err + } + return nil +} + +func (h *windowsAnsiEventHandler) deleteCharacters(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + return h.scrollLine(param, info.CursorPosition, info) +} + +func (h *windowsAnsiEventHandler) insertCharacters(param int) error { + return h.deleteCharacters(-param) +} + +// scrollLine scrolls a line horizontally starting at the provided position by a number of columns. +func (h *windowsAnsiEventHandler) scrollLine(columns int, position COORD, info *CONSOLE_SCREEN_BUFFER_INFO) error { + // Copy from and clip to the scroll region (full buffer width) + scrollRect := SMALL_RECT{ + Top: position.Y, + Bottom: position.Y, + Left: position.X, + Right: info.Size.X - 1, + } + + // Origin to which area should be copied + destOrigin := COORD{ + X: position.X - int16(columns), + Y: position.Y, + } + + char := CHAR_INFO{ + UnicodeChar: ' ', + Attributes: h.attributes, + } + + if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/utilities.go b/vendor/github.com/Azure/go-ansiterm/winterm/utilities.go new file mode 100644 index 0000000000..afa7635d77 --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/utilities.go @@ -0,0 +1,9 @@ +// +build windows + +package winterm + +// AddInRange increments a value by the passed quantity while ensuring the values +// always remain within the supplied min / max range. +func addInRange(n int16, increment int16, min int16, max int16) int16 { + return ensureInRange(n+increment, min, max) +} diff --git a/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go b/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go new file mode 100644 index 0000000000..2d40fb75ad --- /dev/null +++ b/vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go @@ -0,0 +1,743 @@ +// +build windows + +package winterm + +import ( + "bytes" + "log" + "os" + "strconv" + + "github.com/Azure/go-ansiterm" +) + +type windowsAnsiEventHandler struct { + fd uintptr + file *os.File + infoReset *CONSOLE_SCREEN_BUFFER_INFO + sr scrollRegion + buffer bytes.Buffer + attributes uint16 + inverted bool + wrapNext bool + drewMarginByte bool + originMode bool + marginByte byte + curInfo *CONSOLE_SCREEN_BUFFER_INFO + curPos COORD + logf func(string, ...interface{}) +} + +type Option func(*windowsAnsiEventHandler) + +func WithLogf(f func(string, ...interface{})) Option { + return func(w *windowsAnsiEventHandler) { + w.logf = f + } +} + +func CreateWinEventHandler(fd uintptr, file *os.File, opts ...Option) ansiterm.AnsiEventHandler { + infoReset, err := GetConsoleScreenBufferInfo(fd) + if err != nil { + return nil + } + + h := &windowsAnsiEventHandler{ + fd: fd, + file: file, + infoReset: infoReset, + attributes: infoReset.Attributes, + } + for _, o := range opts { + o(h) + } + + if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" { + logFile, _ := os.Create("winEventHandler.log") + logger := log.New(logFile, "", log.LstdFlags) + if h.logf != nil { + l := h.logf + h.logf = func(s string, v ...interface{}) { + l(s, v...) + logger.Printf(s, v...) + } + } else { + h.logf = logger.Printf + } + } + + if h.logf == nil { + h.logf = func(string, ...interface{}) {} + } + + return h +} + +type scrollRegion struct { + top int16 + bottom int16 +} + +// simulateLF simulates a LF or CR+LF by scrolling if necessary to handle the +// current cursor position and scroll region settings, in which case it returns +// true. If no special handling is necessary, then it does nothing and returns +// false. +// +// In the false case, the caller should ensure that a carriage return +// and line feed are inserted or that the text is otherwise wrapped. +func (h *windowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) { + if h.wrapNext { + if err := h.Flush(); err != nil { + return false, err + } + h.clearWrap() + } + pos, info, err := h.getCurrentInfo() + if err != nil { + return false, err + } + sr := h.effectiveSr(info.Window) + if pos.Y == sr.bottom { + // Scrolling is necessary. Let Windows automatically scroll if the scrolling region + // is the full window. + if sr.top == info.Window.Top && sr.bottom == info.Window.Bottom { + if includeCR { + pos.X = 0 + h.updatePos(pos) + } + return false, nil + } + + // A custom scroll region is active. Scroll the window manually to simulate + // the LF. + if err := h.Flush(); err != nil { + return false, err + } + h.logf("Simulating LF inside scroll region") + if err := h.scrollUp(1); err != nil { + return false, err + } + if includeCR { + pos.X = 0 + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return false, err + } + } + return true, nil + + } else if pos.Y < info.Window.Bottom { + // Let Windows handle the LF. + pos.Y++ + if includeCR { + pos.X = 0 + } + h.updatePos(pos) + return false, nil + } else { + // The cursor is at the bottom of the screen but outside the scroll + // region. Skip the LF. + h.logf("Simulating LF outside scroll region") + if includeCR { + if err := h.Flush(); err != nil { + return false, err + } + pos.X = 0 + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return false, err + } + } + return true, nil + } +} + +// executeLF executes a LF without a CR. +func (h *windowsAnsiEventHandler) executeLF() error { + handled, err := h.simulateLF(false) + if err != nil { + return err + } + if !handled { + // Windows LF will reset the cursor column position. Write the LF + // and restore the cursor position. + pos, _, err := h.getCurrentInfo() + if err != nil { + return err + } + h.buffer.WriteByte(ansiterm.ANSI_LINE_FEED) + if pos.X != 0 { + if err := h.Flush(); err != nil { + return err + } + h.logf("Resetting cursor position for LF without CR") + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return err + } + } + } + return nil +} + +func (h *windowsAnsiEventHandler) Print(b byte) error { + if h.wrapNext { + h.buffer.WriteByte(h.marginByte) + h.clearWrap() + if _, err := h.simulateLF(true); err != nil { + return err + } + } + pos, info, err := h.getCurrentInfo() + if err != nil { + return err + } + if pos.X == info.Size.X-1 { + h.wrapNext = true + h.marginByte = b + } else { + pos.X++ + h.updatePos(pos) + h.buffer.WriteByte(b) + } + return nil +} + +func (h *windowsAnsiEventHandler) Execute(b byte) error { + switch b { + case ansiterm.ANSI_TAB: + h.logf("Execute(TAB)") + // Move to the next tab stop, but preserve auto-wrap if already set. + if !h.wrapNext { + pos, info, err := h.getCurrentInfo() + if err != nil { + return err + } + pos.X = (pos.X + 8) - pos.X%8 + if pos.X >= info.Size.X { + pos.X = info.Size.X - 1 + } + if err := h.Flush(); err != nil { + return err + } + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return err + } + } + return nil + + case ansiterm.ANSI_BEL: + h.buffer.WriteByte(ansiterm.ANSI_BEL) + return nil + + case ansiterm.ANSI_BACKSPACE: + if h.wrapNext { + if err := h.Flush(); err != nil { + return err + } + h.clearWrap() + } + pos, _, err := h.getCurrentInfo() + if err != nil { + return err + } + if pos.X > 0 { + pos.X-- + h.updatePos(pos) + h.buffer.WriteByte(ansiterm.ANSI_BACKSPACE) + } + return nil + + case ansiterm.ANSI_VERTICAL_TAB, ansiterm.ANSI_FORM_FEED: + // Treat as true LF. + return h.executeLF() + + case ansiterm.ANSI_LINE_FEED: + // Simulate a CR and LF for now since there is no way in go-ansiterm + // to tell if the LF should include CR (and more things break when it's + // missing than when it's incorrectly added). + handled, err := h.simulateLF(true) + if handled || err != nil { + return err + } + return h.buffer.WriteByte(ansiterm.ANSI_LINE_FEED) + + case ansiterm.ANSI_CARRIAGE_RETURN: + if h.wrapNext { + if err := h.Flush(); err != nil { + return err + } + h.clearWrap() + } + pos, _, err := h.getCurrentInfo() + if err != nil { + return err + } + if pos.X != 0 { + pos.X = 0 + h.updatePos(pos) + h.buffer.WriteByte(ansiterm.ANSI_CARRIAGE_RETURN) + } + return nil + + default: + return nil + } +} + +func (h *windowsAnsiEventHandler) CUU(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUU: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorVertical(-param) +} + +func (h *windowsAnsiEventHandler) CUD(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUD: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorVertical(param) +} + +func (h *windowsAnsiEventHandler) CUF(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUF: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorHorizontal(param) +} + +func (h *windowsAnsiEventHandler) CUB(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUB: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorHorizontal(-param) +} + +func (h *windowsAnsiEventHandler) CNL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CNL: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorLine(param) +} + +func (h *windowsAnsiEventHandler) CPL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CPL: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorLine(-param) +} + +func (h *windowsAnsiEventHandler) CHA(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CHA: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.moveCursorColumn(param) +} + +func (h *windowsAnsiEventHandler) VPA(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("VPA: [[%d]]", param) + h.clearWrap() + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + window := h.getCursorWindow(info) + position := info.CursorPosition + position.Y = window.Top + int16(param) - 1 + return h.setCursorPosition(position, window) +} + +func (h *windowsAnsiEventHandler) CUP(row int, col int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("CUP: [[%d %d]]", row, col) + h.clearWrap() + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + window := h.getCursorWindow(info) + position := COORD{window.Left + int16(col) - 1, window.Top + int16(row) - 1} + return h.setCursorPosition(position, window) +} + +func (h *windowsAnsiEventHandler) HVP(row int, col int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("HVP: [[%d %d]]", row, col) + h.clearWrap() + return h.CUP(row, col) +} + +func (h *windowsAnsiEventHandler) DECTCEM(visible bool) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DECTCEM: [%v]", []string{strconv.FormatBool(visible)}) + h.clearWrap() + return nil +} + +func (h *windowsAnsiEventHandler) DECOM(enable bool) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DECOM: [%v]", []string{strconv.FormatBool(enable)}) + h.clearWrap() + h.originMode = enable + return h.CUP(1, 1) +} + +func (h *windowsAnsiEventHandler) DECCOLM(use132 bool) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DECCOLM: [%v]", []string{strconv.FormatBool(use132)}) + h.clearWrap() + if err := h.ED(2); err != nil { + return err + } + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + targetWidth := int16(80) + if use132 { + targetWidth = 132 + } + if info.Size.X < targetWidth { + if err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil { + h.logf("set buffer failed: %v", err) + return err + } + } + window := info.Window + window.Left = 0 + window.Right = targetWidth - 1 + if err := SetConsoleWindowInfo(h.fd, true, window); err != nil { + h.logf("set window failed: %v", err) + return err + } + if info.Size.X > targetWidth { + if err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil { + h.logf("set buffer failed: %v", err) + return err + } + } + return SetConsoleCursorPosition(h.fd, COORD{0, 0}) +} + +func (h *windowsAnsiEventHandler) ED(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("ED: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + + // [J -- Erases from the cursor to the end of the screen, including the cursor position. + // [1J -- Erases from the beginning of the screen to the cursor, including the cursor position. + // [2J -- Erases the complete display. The cursor does not move. + // Notes: + // -- Clearing the entire buffer, versus just the Window, works best for Windows Consoles + + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + var start COORD + var end COORD + + switch param { + case 0: + start = info.CursorPosition + end = COORD{info.Size.X - 1, info.Size.Y - 1} + + case 1: + start = COORD{0, 0} + end = info.CursorPosition + + case 2: + start = COORD{0, 0} + end = COORD{info.Size.X - 1, info.Size.Y - 1} + } + + err = h.clearRange(h.attributes, start, end) + if err != nil { + return err + } + + // If the whole buffer was cleared, move the window to the top while preserving + // the window-relative cursor position. + if param == 2 { + pos := info.CursorPosition + window := info.Window + pos.Y -= window.Top + window.Bottom -= window.Top + window.Top = 0 + if err := SetConsoleCursorPosition(h.fd, pos); err != nil { + return err + } + if err := SetConsoleWindowInfo(h.fd, true, window); err != nil { + return err + } + } + + return nil +} + +func (h *windowsAnsiEventHandler) EL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("EL: [%v]", strconv.Itoa(param)) + h.clearWrap() + + // [K -- Erases from the cursor to the end of the line, including the cursor position. + // [1K -- Erases from the beginning of the line to the cursor, including the cursor position. + // [2K -- Erases the complete line. + + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + var start COORD + var end COORD + + switch param { + case 0: + start = info.CursorPosition + end = COORD{info.Size.X, info.CursorPosition.Y} + + case 1: + start = COORD{0, info.CursorPosition.Y} + end = info.CursorPosition + + case 2: + start = COORD{0, info.CursorPosition.Y} + end = COORD{info.Size.X, info.CursorPosition.Y} + } + + err = h.clearRange(h.attributes, start, end) + if err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) IL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("IL: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.insertLines(param) +} + +func (h *windowsAnsiEventHandler) DL(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DL: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.deleteLines(param) +} + +func (h *windowsAnsiEventHandler) ICH(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("ICH: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.insertCharacters(param) +} + +func (h *windowsAnsiEventHandler) DCH(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DCH: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.deleteCharacters(param) +} + +func (h *windowsAnsiEventHandler) SGR(params []int) error { + if err := h.Flush(); err != nil { + return err + } + strings := []string{} + for _, v := range params { + strings = append(strings, strconv.Itoa(v)) + } + + h.logf("SGR: [%v]", strings) + + if len(params) <= 0 { + h.attributes = h.infoReset.Attributes + h.inverted = false + } else { + for _, attr := range params { + + if attr == ansiterm.ANSI_SGR_RESET { + h.attributes = h.infoReset.Attributes + h.inverted = false + continue + } + + h.attributes, h.inverted = collectAnsiIntoWindowsAttributes(h.attributes, h.inverted, h.infoReset.Attributes, int16(attr)) + } + } + + attributes := h.attributes + if h.inverted { + attributes = invertAttributes(attributes) + } + err := SetConsoleTextAttribute(h.fd, attributes) + if err != nil { + return err + } + + return nil +} + +func (h *windowsAnsiEventHandler) SU(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("SU: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.scrollUp(param) +} + +func (h *windowsAnsiEventHandler) SD(param int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("SD: [%v]", []string{strconv.Itoa(param)}) + h.clearWrap() + return h.scrollDown(param) +} + +func (h *windowsAnsiEventHandler) DA(params []string) error { + h.logf("DA: [%v]", params) + // DA cannot be implemented because it must send data on the VT100 input stream, + // which is not available to go-ansiterm. + return nil +} + +func (h *windowsAnsiEventHandler) DECSTBM(top int, bottom int) error { + if err := h.Flush(); err != nil { + return err + } + h.logf("DECSTBM: [%d, %d]", top, bottom) + + // Windows is 0 indexed, Linux is 1 indexed + h.sr.top = int16(top - 1) + h.sr.bottom = int16(bottom - 1) + + // This command also moves the cursor to the origin. + h.clearWrap() + return h.CUP(1, 1) +} + +func (h *windowsAnsiEventHandler) RI() error { + if err := h.Flush(); err != nil { + return err + } + h.logf("RI: []") + h.clearWrap() + + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + sr := h.effectiveSr(info.Window) + if info.CursorPosition.Y == sr.top { + return h.scrollDown(1) + } + + return h.moveCursorVertical(-1) +} + +func (h *windowsAnsiEventHandler) IND() error { + h.logf("IND: []") + return h.executeLF() +} + +func (h *windowsAnsiEventHandler) Flush() error { + h.curInfo = nil + if h.buffer.Len() > 0 { + h.logf("Flush: [%s]", h.buffer.Bytes()) + if _, err := h.buffer.WriteTo(h.file); err != nil { + return err + } + } + + if h.wrapNext && !h.drewMarginByte { + h.logf("Flush: drawing margin byte '%c'", h.marginByte) + + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + + charInfo := []CHAR_INFO{{UnicodeChar: uint16(h.marginByte), Attributes: info.Attributes}} + size := COORD{1, 1} + position := COORD{0, 0} + region := SMALL_RECT{Left: info.CursorPosition.X, Top: info.CursorPosition.Y, Right: info.CursorPosition.X, Bottom: info.CursorPosition.Y} + if err := WriteConsoleOutput(h.fd, charInfo, size, position, ®ion); err != nil { + return err + } + h.drewMarginByte = true + } + return nil +} + +// cacheConsoleInfo ensures that the current console screen information has been queried +// since the last call to Flush(). It must be called before accessing h.curInfo or h.curPos. +func (h *windowsAnsiEventHandler) getCurrentInfo() (COORD, *CONSOLE_SCREEN_BUFFER_INFO, error) { + if h.curInfo == nil { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return COORD{}, nil, err + } + h.curInfo = info + h.curPos = info.CursorPosition + } + return h.curPos, h.curInfo, nil +} + +func (h *windowsAnsiEventHandler) updatePos(pos COORD) { + if h.curInfo == nil { + panic("failed to call getCurrentInfo before calling updatePos") + } + h.curPos = pos +} + +// clearWrap clears the state where the cursor is in the margin +// waiting for the next character before wrapping the line. This must +// be done before most operations that act on the cursor. +func (h *windowsAnsiEventHandler) clearWrap() { + h.wrapNext = false + h.drewMarginByte = false +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go index a015cc5b20..3219517dab 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/config.go @@ -6,6 +6,7 @@ import ( smithybearer "github.com/aws/smithy-go/auth/bearer" "github.com/aws/smithy-go/logging" "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" ) // HTTPClient provides the interface to provide custom HTTPClients. Generally @@ -192,6 +193,17 @@ type Config struct { // This variable is sourced from environment variable AWS_RESPONSE_CHECKSUM_VALIDATION or // the shared config profile attribute "response_checksum_validation". ResponseChecksumValidation ResponseChecksumValidation + + // Registry of HTTP interceptors. + Interceptors smithyhttp.InterceptorRegistry + + // Priority list of preferred auth scheme IDs. + AuthSchemePreference []string + + // ServiceOptions provides service specific configuration options that will be applied + // when constructing clients for specific services. Each callback function receives the service ID + // and the service's Options struct, allowing for dynamic configuration based on the service. + ServiceOptions []func(string, any) } // NewConfig returns a new Config pointer that can be chained with builder diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go index 4ad2ee4405..9f94cfe004 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go @@ -118,6 +118,10 @@ const ( CredentialSourceHTTP // CredentialSourceIMDS credentials resolved from the instance metadata service (IMDS) CredentialSourceIMDS + // CredentialSourceProfileLogin credentials resolved from an `aws login` session sourced from a profile + CredentialSourceProfileLogin + // CredentialSourceLogin credentials resolved from an `aws login` session + CredentialSourceLogin ) // A Credentials is the AWS credentials value for individual credential fields. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go index fc102ab7e1..97bc17f4f1 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go @@ -3,4 +3,4 @@ package aws // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.36.4" +const goModuleVersion = "1.40.0" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/user_agent.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/user_agent.go index 6ee3391be2..157a71505c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/user_agent.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/user_agent.go @@ -135,6 +135,11 @@ const ( UserAgentFeatureCredentialsAwsSdkStore = "y" // n/a (this is used by .NET based sdk) UserAgentFeatureCredentialsHTTP = "z" UserAgentFeatureCredentialsIMDS = "0" + + UserAgentFeatureBearerServiceEnvVars = "3" + + UserAgentFeatureCredentialsProfileLogin = "AC" + UserAgentFeatureCredentialsLogin = "AD" ) var credentialSourceToFeature = map[aws.CredentialSource]UserAgentFeature{ @@ -158,6 +163,8 @@ var credentialSourceToFeature = map[aws.CredentialSource]UserAgentFeature{ aws.CredentialSourceProcess: UserAgentFeatureCredentialsProcess, aws.CredentialSourceHTTP: UserAgentFeatureCredentialsHTTP, aws.CredentialSourceIMDS: UserAgentFeatureCredentialsIMDS, + aws.CredentialSourceProfileLogin: UserAgentFeatureCredentialsProfileLogin, + aws.CredentialSourceLogin: UserAgentFeatureCredentialsLogin, } // RequestUserAgent is a build middleware that set the User-Agent for the request. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go index 52d59b04bf..5549922ab8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go @@ -260,7 +260,7 @@ func (r *Attempt) handleAttempt( // Get a retry token that will be released after the releaseRetryToken, retryTokenErr := r.retryer.GetRetryToken(ctx, err) if retryTokenErr != nil { - return out, attemptResult, nopRelease, retryTokenErr + return out, attemptResult, nopRelease, errors.Join(err, retryTokenErr) } //------------------------------ diff --git a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeout_read_closer.go b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeout_read_closer.go index 993929bd9b..4881ae1445 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeout_read_closer.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeout_read_closer.go @@ -64,6 +64,11 @@ func (r *timeoutReadCloser) Close() error { // AddResponseReadTimeoutMiddleware adds a middleware to the stack that wraps the // response body so that a read that takes too long will return an error. +// +// Deprecated: This API was previously exposed to customize behavior of the +// Kinesis service. That customization has been removed and this middleware's +// implementation can cause panics within the standard library networking loop. +// See #2752. func AddResponseReadTimeoutMiddleware(stack *middleware.Stack, duration time.Duration) error { return stack.Deserialize.Add(&readTimeout{duration: duration}, middleware.After) } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md index 0416b30a4d..37b9f3f7ed 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md @@ -1,3 +1,134 @@ +# v1.32.2 (2025-11-25) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.1 (2025-11-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.0 (2025-11-19.2) + +* **Feature**: Add support for AWS Login credentials (package credentials/logincreds) to the default credential chain. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.21 (2025-11-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.20 (2025-11-12) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.19 (2025-11-11) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.18 (2025-11-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.17 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.31.16 (2025-10-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.15 (2025-10-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.14 (2025-10-22) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.13 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.12 (2025-09-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.11 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.10 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.9 (2025-09-22) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.8 (2025-09-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.7 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.6 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.5 (2025-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.4 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.3 (2025-08-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.2 (2025-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.1 (2025-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.0 (2025-08-11) + +* **Feature**: Add support for configuring per-service Options via callback on global config. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.30.3 (2025-08-04) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.30.2 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.30.1 (2025-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.30.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.29.18 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.29.17 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + # v1.29.16 (2025-06-10) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/auth_scheme_preference.go b/vendor/github.com/aws/aws-sdk-go-v2/config/auth_scheme_preference.go new file mode 100644 index 0000000000..99e1236614 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/auth_scheme_preference.go @@ -0,0 +1,19 @@ +package config + +import "strings" + +func toAuthSchemePreferenceList(cfg string) []string { + if len(cfg) == 0 { + return nil + } + parts := strings.Split(cfg, ",") + ids := make([]string, 0, len(parts)) + + for _, p := range parts { + if id := strings.TrimSpace(p); len(id) > 0 { + ids = append(ids, id) + } + } + + return ids +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/config.go b/vendor/github.com/aws/aws-sdk-go-v2/config/config.go index 09d9b63116..caa20a158a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/config.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/config.go @@ -89,6 +89,13 @@ var defaultAWSConfigResolvers = []awsConfigResolver{ // Sets the ResponseChecksumValidation if present in env var or shared config profile resolveResponseChecksumValidation, + + resolveInterceptors, + + resolveAuthSchemePreference, + + // Sets the ServiceOptions if present in LoadOptions + resolveServiceOptions, } // A Config represents a generic configuration value or set of values. This type diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/env_config.go b/vendor/github.com/aws/aws-sdk-go-v2/config/env_config.go index 9db507e38e..e932c63dfb 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/env_config.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/env_config.go @@ -85,6 +85,8 @@ const ( awsRequestChecksumCalculation = "AWS_REQUEST_CHECKSUM_CALCULATION" awsResponseChecksumValidation = "AWS_RESPONSE_CHECKSUM_VALIDATION" + + awsAuthSchemePreferenceEnv = "AWS_AUTH_SCHEME_PREFERENCE" ) var ( @@ -304,6 +306,9 @@ type EnvConfig struct { // Indicates whether response checksum should be validated ResponseChecksumValidation aws.ResponseChecksumValidation + + // Priority list of preferred auth scheme names (e.g. sigv4a). + AuthSchemePreference []string } // loadEnvConfig reads configuration values from the OS's environment variables. @@ -415,6 +420,8 @@ func NewEnvConfig() (EnvConfig, error) { return cfg, err } + cfg.AuthSchemePreference = toAuthSchemePreferenceList(os.Getenv(awsAuthSchemePreferenceEnv)) + return cfg, nil } @@ -916,3 +923,10 @@ func (c EnvConfig) GetS3DisableExpressAuth() (value, ok bool) { return *c.S3DisableExpressAuth, true } + +func (c EnvConfig) getAuthSchemePreference() ([]string, bool) { + if len(c.AuthSchemePreference) > 0 { + return c.AuthSchemePreference, true + } + return nil, false +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/config/go_module_metadata.go index 8c30900142..d59007fa72 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/go_module_metadata.go @@ -3,4 +3,4 @@ package config // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.29.16" +const goModuleVersion = "1.32.2" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/load_options.go b/vendor/github.com/aws/aws-sdk-go-v2/config/load_options.go index 0810ecf16a..7cb5a13658 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/load_options.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/load_options.go @@ -14,6 +14,7 @@ import ( smithybearer "github.com/aws/smithy-go/auth/bearer" "github.com/aws/smithy-go/logging" "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" ) // LoadOptionsFunc is a type alias for LoadOptions functional option @@ -228,6 +229,17 @@ type LoadOptions struct { // Service endpoint override. This value is not necessarily final and is // passed to the service's EndpointResolverV2 for further delegation. BaseEndpoint string + + // Registry of operation interceptors. + Interceptors smithyhttp.InterceptorRegistry + + // Priority list of preferred auth scheme names (e.g. sigv4a). + AuthSchemePreference []string + + // ServiceOptions provides service specific configuration options that will be applied + // when constructing clients for specific services. Each callback function receives the service ID + // and the service's Options struct, allowing for dynamic configuration based on the service. + ServiceOptions []func(string, any) } func (o LoadOptions) getDefaultsMode(ctx context.Context) (aws.DefaultsMode, bool, error) { @@ -307,6 +319,10 @@ func (o LoadOptions) getBaseEndpoint(context.Context) (string, bool, error) { return o.BaseEndpoint, o.BaseEndpoint != "", nil } +func (o LoadOptions) getServiceOptions(context.Context) ([]func(string, any), bool, error) { + return o.ServiceOptions, len(o.ServiceOptions) > 0, nil +} + // GetServiceBaseEndpoint satisfies (internal/configsources).ServiceBaseEndpointProvider. // // The sdkID value is unused because LoadOptions only supports setting a GLOBAL @@ -1207,3 +1223,133 @@ func WithBaseEndpoint(v string) LoadOptionsFunc { return nil } } + +// WithServiceOptions is a helper function to construct functional options +// that sets ServiceOptions on config's LoadOptions. +func WithServiceOptions(callbacks ...func(string, any)) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.ServiceOptions = append(o.ServiceOptions, callbacks...) + return nil + } +} + +// WithBeforeExecution adds the BeforeExecutionInterceptor to config. +func WithBeforeExecution(i smithyhttp.BeforeExecutionInterceptor) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.Interceptors.BeforeExecution = append(o.Interceptors.BeforeExecution, i) + return nil + } +} + +// WithBeforeSerialization adds the BeforeSerializationInterceptor to config. +func WithBeforeSerialization(i smithyhttp.BeforeSerializationInterceptor) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.Interceptors.BeforeSerialization = append(o.Interceptors.BeforeSerialization, i) + return nil + } +} + +// WithAfterSerialization adds the AfterSerializationInterceptor to config. +func WithAfterSerialization(i smithyhttp.AfterSerializationInterceptor) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.Interceptors.AfterSerialization = append(o.Interceptors.AfterSerialization, i) + return nil + } +} + +// WithBeforeRetryLoop adds the BeforeRetryLoopInterceptor to config. +func WithBeforeRetryLoop(i smithyhttp.BeforeRetryLoopInterceptor) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.Interceptors.BeforeRetryLoop = append(o.Interceptors.BeforeRetryLoop, i) + return nil + } +} + +// WithBeforeAttempt adds the BeforeAttemptInterceptor to config. +func WithBeforeAttempt(i smithyhttp.BeforeAttemptInterceptor) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.Interceptors.BeforeAttempt = append(o.Interceptors.BeforeAttempt, i) + return nil + } +} + +// WithBeforeSigning adds the BeforeSigningInterceptor to config. +func WithBeforeSigning(i smithyhttp.BeforeSigningInterceptor) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.Interceptors.BeforeSigning = append(o.Interceptors.BeforeSigning, i) + return nil + } +} + +// WithAfterSigning adds the AfterSigningInterceptor to config. +func WithAfterSigning(i smithyhttp.AfterSigningInterceptor) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.Interceptors.AfterSigning = append(o.Interceptors.AfterSigning, i) + return nil + } +} + +// WithBeforeTransmit adds the BeforeTransmitInterceptor to config. +func WithBeforeTransmit(i smithyhttp.BeforeTransmitInterceptor) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.Interceptors.BeforeTransmit = append(o.Interceptors.BeforeTransmit, i) + return nil + } +} + +// WithAfterTransmit adds the AfterTransmitInterceptor to config. +func WithAfterTransmit(i smithyhttp.AfterTransmitInterceptor) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.Interceptors.AfterTransmit = append(o.Interceptors.AfterTransmit, i) + return nil + } +} + +// WithBeforeDeserialization adds the BeforeDeserializationInterceptor to config. +func WithBeforeDeserialization(i smithyhttp.BeforeDeserializationInterceptor) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.Interceptors.BeforeDeserialization = append(o.Interceptors.BeforeDeserialization, i) + return nil + } +} + +// WithAfterDeserialization adds the AfterDeserializationInterceptor to config. +func WithAfterDeserialization(i smithyhttp.AfterDeserializationInterceptor) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.Interceptors.AfterDeserialization = append(o.Interceptors.AfterDeserialization, i) + return nil + } +} + +// WithAfterAttempt adds the AfterAttemptInterceptor to config. +func WithAfterAttempt(i smithyhttp.AfterAttemptInterceptor) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.Interceptors.AfterAttempt = append(o.Interceptors.AfterAttempt, i) + return nil + } +} + +// WithAfterExecution adds the AfterExecutionInterceptor to config. +func WithAfterExecution(i smithyhttp.AfterExecutionInterceptor) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.Interceptors.AfterExecution = append(o.Interceptors.AfterExecution, i) + return nil + } +} + +// WithAuthSchemePreference sets the priority order of auth schemes on config. +// +// Schemes are expressed as names e.g. sigv4a or sigv4. +func WithAuthSchemePreference(schemeIDs ...string) LoadOptionsFunc { + return func(o *LoadOptions) error { + o.AuthSchemePreference = schemeIDs + return nil + } +} + +func (o LoadOptions) getAuthSchemePreference() ([]string, bool) { + if len(o.AuthSchemePreference) > 0 { + return o.AuthSchemePreference, true + } + return nil, false +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/provider.go b/vendor/github.com/aws/aws-sdk-go-v2/config/provider.go index a8ff40d846..18b9b5ad20 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/provider.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/provider.go @@ -753,3 +753,34 @@ func getRetryMode(ctx context.Context, configs configs) (v aws.RetryMode, found } return v, found, err } + +func getAuthSchemePreference(ctx context.Context, configs configs) ([]string, bool) { + type provider interface { + getAuthSchemePreference() ([]string, bool) + } + + for _, cfg := range configs { + if p, ok := cfg.(provider); ok { + if v, ok := p.getAuthSchemePreference(); ok { + return v, true + } + } + } + return nil, false +} + +type serviceOptionsProvider interface { + getServiceOptions(ctx context.Context) ([]func(string, any), bool, error) +} + +func getServiceOptions(ctx context.Context, configs configs) (v []func(string, any), found bool, err error) { + for _, c := range configs { + if p, ok := c.(serviceOptionsProvider); ok { + v, found, err = p.getServiceOptions(ctx) + if err != nil || found { + break + } + } + } + return v, found, err +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go b/vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go index a68bd0993f..92a16d718d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go @@ -411,3 +411,34 @@ func resolveRetryMode(ctx context.Context, cfg *aws.Config, configs configs) err return nil } + +func resolveInterceptors(ctx context.Context, cfg *aws.Config, configs configs) error { + // LoadOptions is the only thing that you can really configure interceptors + // on so just check that directly. + for _, c := range configs { + if loadopts, ok := c.(LoadOptions); ok { + cfg.Interceptors = loadopts.Interceptors.Copy() + } + } + return nil +} + +func resolveAuthSchemePreference(ctx context.Context, cfg *aws.Config, configs configs) error { + if pref, ok := getAuthSchemePreference(ctx, configs); ok { + cfg.AuthSchemePreference = pref + } + return nil +} + +func resolveServiceOptions(ctx context.Context, cfg *aws.Config, configs configs) error { + serviceOptions, found, err := getServiceOptions(ctx, configs) + if err != nil { + return err + } + if !found { + return nil + } + + cfg.ServiceOptions = serviceOptions + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/resolve_credentials.go b/vendor/github.com/aws/aws-sdk-go-v2/config/resolve_credentials.go index b00259df03..de83985999 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/resolve_credentials.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/resolve_credentials.go @@ -13,10 +13,12 @@ import ( "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds" "github.com/aws/aws-sdk-go-v2/credentials/endpointcreds" + "github.com/aws/aws-sdk-go-v2/credentials/logincreds" "github.com/aws/aws-sdk-go-v2/credentials/processcreds" "github.com/aws/aws-sdk-go-v2/credentials/ssocreds" "github.com/aws/aws-sdk-go-v2/credentials/stscreds" "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" + "github.com/aws/aws-sdk-go-v2/service/signin" "github.com/aws/aws-sdk-go-v2/service/sso" "github.com/aws/aws-sdk-go-v2/service/ssooidc" "github.com/aws/aws-sdk-go-v2/service/sts" @@ -172,7 +174,10 @@ func resolveCredsFromProfile(ctx context.Context, cfg *aws.Config, envConfig *En ctx = addCredentialSource(ctx, aws.CredentialSourceProfileSSO) } err = resolveSSOCredentials(ctx, cfg, sharedConfig, configs) - + case len(sharedConfig.LoginSession) > 0: + ctx = addCredentialSource(ctx, aws.CredentialSourceProfileLogin) + ctx = addCredentialSource(ctx, aws.CredentialSourceLogin) + err = resolveLoginCredentials(ctx, cfg, sharedConfig, configs) case len(sharedConfig.CredentialProcess) != 0: // Get credentials from CredentialProcess ctx = addCredentialSource(ctx, aws.CredentialSourceProfileProcess) @@ -625,3 +630,21 @@ func addCredentialSource(ctx context.Context, source aws.CredentialSource) conte func getCredentialSources(ctx context.Context) []aws.CredentialSource { return ctx.Value(credentialSource{}).([]aws.CredentialSource) } + +func resolveLoginCredentials(ctx context.Context, cfg *aws.Config, sharedCfg *SharedConfig, configs configs) error { + cacheDir := os.Getenv("AWS_LOGIN_CACHE_DIRECTORY") + tokenPath, err := logincreds.StandardCachedTokenFilepath(sharedCfg.LoginSession, cacheDir) + if err != nil { + return err + } + + svc := signin.NewFromConfig(*cfg) + provider := logincreds.New(svc, tokenPath, func(o *logincreds.Options) { + o.CredentialSources = getCredentialSources(ctx) + }) + cfg.Credentials, err = wrapWithCredentialsCache(ctx, configs, provider) + if err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/config/shared_config.go b/vendor/github.com/aws/aws-sdk-go-v2/config/shared_config.go index 00b071fe6f..5a0fea2220 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/config/shared_config.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/config/shared_config.go @@ -123,6 +123,10 @@ const ( responseChecksumValidationKey = "response_checksum_validation" checksumWhenSupported = "when_supported" checksumWhenRequired = "when_required" + + authSchemePreferenceKey = "auth_scheme_preference" + + loginSessionKey = "login_session" ) // defaultSharedConfigProfile allows for swapping the default profile for testing @@ -357,6 +361,12 @@ type SharedConfig struct { // ResponseChecksumValidation indicates if the response checksum should be validated ResponseChecksumValidation aws.ResponseChecksumValidation + + // Priority list of preferred auth scheme names (e.g. sigv4a). + AuthSchemePreference []string + + // Session ARN from an `aws login` session. + LoginSession string } func (c SharedConfig) getDefaultsMode(ctx context.Context) (value aws.DefaultsMode, ok bool, err error) { @@ -890,6 +900,10 @@ func mergeSections(dst *ini.Sections, src ini.Sections) error { ssoRegionKey, ssoRoleNameKey, ssoStartURLKey, + + authSchemePreferenceKey, + + loginSessionKey, } for i := range stringKeys { if err := mergeStringKey(&srcSection, &dstSection, sectionName, stringKeys[i]); err != nil { @@ -1166,6 +1180,10 @@ func (c *SharedConfig) setFromIniSection(profile string, section ini.Section) er updateString(&c.ServicesSectionName, section, servicesSectionKey) + c.AuthSchemePreference = toAuthSchemePreferenceList(section.String(authSchemePreferenceKey)) + + updateString(&c.LoginSession, section, loginSessionKey) + return nil } @@ -1678,3 +1696,10 @@ func updateUseFIPSEndpoint(dst *aws.FIPSEndpointState, section ini.Section, key return } + +func (c SharedConfig) getAuthSchemePreference() ([]string, bool) { + if len(c.AuthSchemePreference) > 0 { + return c.AuthSchemePreference, true + } + return nil, false +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md index d47d8629e0..547c330072 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md @@ -1,3 +1,133 @@ +# v1.19.2 (2025-11-25) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.1 (2025-11-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.0 (2025-11-19.2) + +* **Feature**: Add support for AWS Login credentials (package credentials/logincreds) to the default credential chain. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.25 (2025-11-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.24 (2025-11-12) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.23 (2025-11-11) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.22 (2025-11-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.21 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.18.20 (2025-10-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.19 (2025-10-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.18 (2025-10-22) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.17 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.16 (2025-09-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.15 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.14 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.13 (2025-09-22) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.12 (2025-09-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.11 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.10 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.9 (2025-08-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.8 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.7 (2025-08-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.6 (2025-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.5 (2025-08-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.4 (2025-08-11) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.3 (2025-08-04) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.2 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.1 (2025-07-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.17.71 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.17.70 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + # v1.17.69 (2025-06-10) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/go_module_metadata.go index 3ec6470b41..ff8fa09d1c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/credentials/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/go_module_metadata.go @@ -3,4 +3,4 @@ package credentials // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.17.69" +const goModuleVersion = "1.19.2" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/dpop.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/dpop.go new file mode 100644 index 0000000000..6dc0845fdf --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/dpop.go @@ -0,0 +1,150 @@ +package logincreds + +import ( + "context" + "crypto/ecdsa" + cryptorand "crypto/rand" + "crypto/sha256" + "crypto/x509" + "encoding/base64" + "encoding/json" + "encoding/pem" + "fmt" + + "github.com/aws/aws-sdk-go-v2/internal/sdk" + "github.com/aws/aws-sdk-go-v2/service/signin" + "github.com/aws/smithy-go/middleware" + smithyrand "github.com/aws/smithy-go/rand" + smithyhttp "github.com/aws/smithy-go/transport/http" +) + +// AWS signin DPOP always uses the P256 curve +const curvelen = 256 / 8 // bytes + +// https://datatracker.ietf.org/doc/html/rfc9449 +func mkdpop(token *loginToken, htu string) (string, error) { + key, err := parseKey(token.DPOPKey) + if err != nil { + return "", fmt.Errorf("parse key: %w", err) + } + + header, err := jsonb64(&dpopHeader{ + Typ: "dpop+jwt", + Alg: "ES256", + Jwk: &dpopHeaderJwk{ + Kty: "EC", + X: base64.RawURLEncoding.EncodeToString(key.X.Bytes()), + Y: base64.RawURLEncoding.EncodeToString(key.Y.Bytes()), + Crv: "P-256", + }, + }) + if err != nil { + return "", fmt.Errorf("marshal header: %w", err) + } + + uuid, err := smithyrand.NewUUID(cryptorand.Reader).GetUUID() + if err != nil { + return "", fmt.Errorf("uuid: %w", err) + } + + payload, err := jsonb64(&dpopPayload{ + Jti: uuid, + Htm: "POST", + Htu: htu, + Iat: sdk.NowTime().Unix(), + }) + if err != nil { + return "", fmt.Errorf("marshal payload: %w", err) + } + + msg := fmt.Sprintf("%s.%s", header, payload) + + h := sha256.New() + h.Write([]byte(msg)) + + r, s, err := ecdsa.Sign(cryptorand.Reader, key, h.Sum(nil)) + if err != nil { + return "", fmt.Errorf("sign: %w", err) + } + + // DPOP signatures are formatted in RAW r || s form (with each value padded + // to fit in curve size which in our case is always the 256 bits) - rather + // than encoded in something like asn.1 + sig := make([]byte, curvelen*2) + r.FillBytes(sig[0:curvelen]) + s.FillBytes(sig[curvelen:]) + + dpop := fmt.Sprintf("%s.%s", msg, base64.RawURLEncoding.EncodeToString(sig)) + return dpop, nil +} + +func parseKey(pemBlock string) (*ecdsa.PrivateKey, error) { + block, _ := pem.Decode([]byte(pemBlock)) + priv, err := x509.ParseECPrivateKey(block.Bytes) + if err != nil { + return nil, fmt.Errorf("parse ec private key: %w", err) + } + + return priv, nil +} + +func jsonb64(v any) (string, error) { + j, err := json.MarshalIndent(v, "", " ") + if err != nil { + return "", err + } + + return base64.RawURLEncoding.EncodeToString(j), nil +} + +type dpopHeader struct { + Typ string `json:"typ"` + Alg string `json:"alg"` + Jwk *dpopHeaderJwk `json:"jwk"` +} + +type dpopHeaderJwk struct { + Kty string `json:"kty"` + X string `json:"x"` + Y string `json:"y"` + Crv string `json:"crv"` +} + +type dpopPayload struct { + Jti string `json:"jti"` + Htm string `json:"htm"` + Htu string `json:"htu"` + Iat int64 `json:"iat"` +} + +type signDPOP struct { + Token *loginToken +} + +func addSignDPOP(token *loginToken) func(o *signin.Options) { + return signin.WithAPIOptions(func(stack *middleware.Stack) error { + return stack.Finalize.Add(&signDPOP{token}, middleware.After) + }) +} + +func (*signDPOP) ID() string { + return "signDPOP" +} + +func (m *signDPOP) HandleFinalize( + ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, md middleware.Metadata, err error, +) { + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, md, fmt.Errorf("unexpected transport type %T", req) + } + + dpop, err := mkdpop(m.Token, req.URL.String()) + if err != nil { + return out, md, fmt.Errorf("sign dpop: %w", err) + } + + req.Header.Set("DPoP", dpop) + return next.HandleFinalize(ctx, in) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/file.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/file.go new file mode 100644 index 0000000000..6cd5281d49 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/file.go @@ -0,0 +1,14 @@ +package logincreds + +import ( + "io" + "os" +) + +var openFile func(string) (io.ReadCloser, error) = func(name string) (io.ReadCloser, error) { + return os.Open(name) +} + +var createFile func(string) (io.WriteCloser, error) = func(name string) (io.WriteCloser, error) { + return os.Create(name) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/provider.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/provider.go new file mode 100644 index 0000000000..3e6357b87c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/provider.go @@ -0,0 +1,172 @@ +// Package logincreds implements AWS credential provision for sessions created +// via an `aws login` command. +package logincreds + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "os" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/internal/sdk" + "github.com/aws/aws-sdk-go-v2/service/signin" + "github.com/aws/aws-sdk-go-v2/service/signin/types" +) + +// ProviderName identifies the login provider. +const ProviderName = "LoginProvider" + +// TokenAPIClient provides the interface for the login session's token +// retrieval operation. +type TokenAPIClient interface { + CreateOAuth2Token(context.Context, *signin.CreateOAuth2TokenInput, ...func(*signin.Options)) (*signin.CreateOAuth2TokenOutput, error) +} + +// Provider supplies credentials for an `aws login` session. +type Provider struct { + options Options +} + +var _ aws.CredentialsProvider = (*Provider)(nil) + +// Options configures the Provider. +type Options struct { + Client TokenAPIClient + + // APIOptions to pass to the underlying CreateOAuth2Token operation. + ClientOptions []func(*signin.Options) + + // The path to the cached login token. + CachedTokenFilepath string + + // The chain of providers that was used to create this provider. + // + // These values are for reporting purposes and are not meant to be set up + // directly. + CredentialSources []aws.CredentialSource +} + +// New returns a new login session credentials provider. +func New(client TokenAPIClient, path string, opts ...func(*Options)) *Provider { + options := Options{ + Client: client, + CachedTokenFilepath: path, + } + + for _, opt := range opts { + opt(&options) + } + + return &Provider{options} +} + +// Retrieve generates a new set of temporary credentials using an `aws login` +// session. +func (p *Provider) Retrieve(ctx context.Context) (aws.Credentials, error) { + token, err := p.loadToken() + if err != nil { + return aws.Credentials{}, fmt.Errorf("load login token: %w", err) + } + if err := token.Validate(); err != nil { + return aws.Credentials{}, fmt.Errorf("validate login token: %w", err) + } + + // the token may have been refreshed elsewhere or the login session might + // have just been created + if sdk.NowTime().Before(token.AccessToken.ExpiresAt) { + return token.Credentials(), nil + } + + opts := make([]func(*signin.Options), len(p.options.ClientOptions)+1) + opts[0] = addSignDPOP(token) + copy(opts[1:], p.options.ClientOptions) + + out, err := p.options.Client.CreateOAuth2Token(ctx, &signin.CreateOAuth2TokenInput{ + TokenInput: &types.CreateOAuth2TokenRequestBody{ + ClientId: aws.String(token.ClientID), + GrantType: aws.String("refresh_token"), + RefreshToken: aws.String(token.RefreshToken), + }, + }, opts...) + if err != nil { + var terr *types.AccessDeniedException + if errors.As(err, &terr) { + err = toAccessDeniedError(terr) + } + return aws.Credentials{}, fmt.Errorf("create oauth2 token: %w", err) + } + + token.Update(out) + if err := p.saveToken(token); err != nil { + return aws.Credentials{}, fmt.Errorf("save token: %w", err) + } + + return token.Credentials(), nil +} + +// ProviderSources returns the credential chain that was used to construct this +// provider. +func (p *Provider) ProviderSources() []aws.CredentialSource { + if p.options.CredentialSources == nil { + return []aws.CredentialSource{aws.CredentialSourceLogin} + } + return p.options.CredentialSources +} + +func (p *Provider) loadToken() (*loginToken, error) { + f, err := openFile(p.options.CachedTokenFilepath) + if err != nil && os.IsNotExist(err) { + return nil, fmt.Errorf("token file not found, please reauthenticate") + } + if err != nil { + return nil, err + } + defer f.Close() + + j, err := io.ReadAll(f) + if err != nil { + return nil, err + } + + var t *loginToken + if err := json.Unmarshal(j, &t); err != nil { + return nil, err + } + + return t, nil +} + +func (p *Provider) saveToken(token *loginToken) error { + j, err := json.Marshal(token) + if err != nil { + return err + } + + f, err := createFile(p.options.CachedTokenFilepath) + if err != nil { + return err + } + defer f.Close() + + if _, err := f.Write(j); err != nil { + return err + } + + return nil +} + +func toAccessDeniedError(err *types.AccessDeniedException) error { + switch err.Error_ { + case types.OAuth2ErrorCodeTokenExpired: + return fmt.Errorf("login session has expired, please reauthenticate") + case types.OAuth2ErrorCodeUserCredentialsChanged: + return fmt.Errorf("login session password has changed, please reauthenticate") + case types.OAuth2ErrorCodeInsufficientPermissions: + return fmt.Errorf("insufficient permissions, you may be missing permissions for the CreateOAuth2Token action") + default: + return err + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/token.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/token.go new file mode 100644 index 0000000000..1a97b98cdc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/logincreds/token.go @@ -0,0 +1,110 @@ +package logincreds + +import ( + "crypto/sha256" + "encoding/hex" + "errors" + "fmt" + "path/filepath" + "strings" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/internal/sdk" + "github.com/aws/aws-sdk-go-v2/internal/shareddefaults" + "github.com/aws/aws-sdk-go-v2/service/signin" +) + +var userHomeDir = shareddefaults.UserHomeDir + +// StandardCachedTokenFilepath returns the filepath for the cached login token +// file. Key that will be used to compute a SHA256 value that is hex encoded. +// +// An overriden root dir can be provided, if not set the path defaults to +// ~/.aws/sso/cache. +func StandardCachedTokenFilepath(session, dir string) (string, error) { + session = strings.TrimSpace(session) + + if len(dir) == 0 { + dir = userHomeDir() + if len(dir) == 0 { + return "", errors.New("user home dir is blank") + } + dir = filepath.Join(dir, ".aws", "login", "cache") + } + + h := sha256.New() + h.Write([]byte(session)) + + filename := strings.ToLower(hex.EncodeToString(h.Sum(nil))) + ".json" + return filepath.Join(dir, filename), nil +} + +// contents of the token as they appear on disk +type loginToken struct { + AccessToken *loginTokenAccessToken `json:"accessToken"` + TokenType string `json:"tokenType"` + RefreshToken string `json:"refreshToken"` + IdentityToken string `json:"identityToken"` + ClientID string `json:"clientId"` + DPOPKey string `json:"dpopKey"` +} + +type loginTokenAccessToken struct { + AccessKeyID string `json:"accessKeyId"` + SecretAccessKey string `json:"secretAccessKey"` + SessionToken string `json:"sessionToken"` + AccountID string `json:"accountId"` + ExpiresAt time.Time `json:"expiresAt"` +} + +func (t *loginToken) Validate() error { + if t.AccessToken == nil { + return fmt.Errorf("missing accessToken") + } + if t.AccessToken.AccessKeyID == "" { + return fmt.Errorf("missing accessToken.accessKeyId") + } + if t.AccessToken.SecretAccessKey == "" { + return fmt.Errorf("missing accessToken.secretAccessKey") + } + if t.AccessToken.SessionToken == "" { + return fmt.Errorf("missing accessToken.sessionToken") + } + if t.AccessToken.AccountID == "" { + return fmt.Errorf("missing accessToken.accountId") + } + if t.AccessToken.ExpiresAt.IsZero() { + return fmt.Errorf("missing accessToken.expiresAt") + } + if t.ClientID == "" { + return fmt.Errorf("missing clientId") + } + if t.RefreshToken == "" { + return fmt.Errorf("missing refreshToken") + } + if t.DPOPKey == "" { + return fmt.Errorf("missing dpopKey") + } + return nil +} + +func (t *loginToken) Credentials() aws.Credentials { + return aws.Credentials{ + AccessKeyID: t.AccessToken.AccessKeyID, + SecretAccessKey: t.AccessToken.SecretAccessKey, + SessionToken: t.AccessToken.SessionToken, + Source: ProviderName, + CanExpire: true, + Expires: t.AccessToken.ExpiresAt, + AccountID: t.AccessToken.AccountID, + } +} + +func (t *loginToken) Update(out *signin.CreateOAuth2TokenOutput) { + t.AccessToken.AccessKeyID = *out.TokenOutput.AccessToken.AccessKeyId + t.AccessToken.SecretAccessKey = *out.TokenOutput.AccessToken.SecretAccessKey + t.AccessToken.SessionToken = *out.TokenOutput.AccessToken.SessionToken + t.AccessToken.ExpiresAt = sdk.NowTime().Add(time.Duration(*out.TokenOutput.ExpiresIn) * time.Second) + t.RefreshToken = *out.TokenOutput.RefreshToken +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/CHANGELOG.md index 4bd7a942fb..1797e1d665 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/CHANGELOG.md @@ -1,3 +1,80 @@ +# v1.18.14 (2025-11-19.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.13 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.18.12 (2025-10-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.11 (2025-10-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.10 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.9 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.8 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.7 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.6 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.5 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.4 (2025-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.3 (2025-08-11) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.2 (2025-08-04) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.1 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.0 (2025-07-29) + +* **Feature**: Add config switch `DisableDefaultMaxBackoff` that allows you to disable the default maximum backoff (1 second) for IMDS calls retry attempt + +# v1.17.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.16.33 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.16.32 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + # v1.16.31 (2025-06-10) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_client.go index 3f4a10e2c1..75edc4e9d6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_client.go @@ -75,7 +75,9 @@ func New(options Options, optFns ...func(*Options)) *Client { if options.Retryer == nil { options.Retryer = retry.NewStandard() } - options.Retryer = retry.AddWithMaxBackoffDelay(options.Retryer, 1*time.Second) + if !options.DisableDefaultMaxBackoff { + options.Retryer = retry.AddWithMaxBackoffDelay(options.Retryer, 1*time.Second) + } if options.ClientEnableState == ClientDefaultEnableState { if v := os.Getenv(disableClientEnvVar); strings.EqualFold(v, "true") { @@ -189,6 +191,10 @@ type Options struct { // can disable that behavior with this setting. DisableDefaultTimeout bool + // By default all IMDS client operations enforce a 1-second retry delay at maximum. + // You can disable that behavior with this setting. + DisableDefaultMaxBackoff bool + // provides the caching of API tokens used for operation calls. If unset, // the API token will not be retrieved for the operation. tokenProvider *tokenProvider diff --git a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/go_module_metadata.go index accba4083a..b763617b45 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/go_module_metadata.go @@ -3,4 +3,4 @@ package imds // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.16.31" +const goModuleVersion = "1.18.14" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md index b4990deff2..afcfb2cfdb 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md @@ -1,3 +1,76 @@ +# v1.4.14 (2025-11-19.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.13 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.4.12 (2025-10-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.11 (2025-10-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.10 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.9 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.8 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.7 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.6 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.5 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.4 (2025-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.3 (2025-08-11) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.2 (2025-08-04) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.1 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.4.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.3.37 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.3.36 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + # v1.3.35 (2025-06-10) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go index 19fd284472..816dad7453 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go @@ -3,4 +3,4 @@ package configsources // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.3.35" +const goModuleVersion = "1.4.14" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go index 5f0779997d..6ab4d9669f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go @@ -3,7 +3,8 @@ package awsrulesfn // GetPartition returns an AWS [Partition] for the region provided. If the -// partition cannot be determined nil will be returned. +// partition cannot be determined then the default partition (AWS commercial) +// will be returned. func GetPartition(region string) *PartitionConfig { return getPartition(partitions, region) } @@ -11,7 +12,7 @@ func GetPartition(region string) *PartitionConfig { var partitions = []Partition{ { ID: "aws", - RegionRegex: "^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$", + RegionRegex: "^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$", DefaultConfig: PartitionConfig{ Name: "aws", DnsSuffix: "amazonaws.com", @@ -35,6 +36,13 @@ var partitions = []Partition{ SupportsFIPS: nil, SupportsDualStack: nil, }, + "ap-east-2": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, "ap-northeast-1": { Name: nil, DnsSuffix: nil, @@ -98,6 +106,27 @@ var partitions = []Partition{ SupportsFIPS: nil, SupportsDualStack: nil, }, + "ap-southeast-5": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "ap-southeast-6": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "ap-southeast-7": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, "aws-global": { Name: nil, DnsSuffix: nil, @@ -196,6 +225,13 @@ var partitions = []Partition{ SupportsFIPS: nil, SupportsDualStack: nil, }, + "mx-central-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, "sa-east-1": { Name: nil, DnsSuffix: nil, @@ -269,32 +305,18 @@ var partitions = []Partition{ }, }, { - ID: "aws-us-gov", - RegionRegex: "^us\\-gov\\-\\w+\\-\\d+$", + ID: "aws-eusc", + RegionRegex: "^eusc\\-(de)\\-\\w+\\-\\d+$", DefaultConfig: PartitionConfig{ - Name: "aws-us-gov", - DnsSuffix: "amazonaws.com", - DualStackDnsSuffix: "api.aws", + Name: "aws-eusc", + DnsSuffix: "amazonaws.eu", + DualStackDnsSuffix: "api.amazonwebservices.eu", SupportsFIPS: true, SupportsDualStack: true, - ImplicitGlobalRegion: "us-gov-west-1", + ImplicitGlobalRegion: "eusc-de-east-1", }, Regions: map[string]RegionOverrides{ - "aws-us-gov-global": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-gov-east-1": { - Name: nil, - DnsSuffix: nil, - DualStackDnsSuffix: nil, - SupportsFIPS: nil, - SupportsDualStack: nil, - }, - "us-gov-west-1": { + "eusc-de-east-1": { Name: nil, DnsSuffix: nil, DualStackDnsSuffix: nil, @@ -309,9 +331,9 @@ var partitions = []Partition{ DefaultConfig: PartitionConfig{ Name: "aws-iso", DnsSuffix: "c2s.ic.gov", - DualStackDnsSuffix: "c2s.ic.gov", + DualStackDnsSuffix: "api.aws.ic.gov", SupportsFIPS: true, - SupportsDualStack: false, + SupportsDualStack: true, ImplicitGlobalRegion: "us-iso-east-1", }, Regions: map[string]RegionOverrides{ @@ -344,9 +366,9 @@ var partitions = []Partition{ DefaultConfig: PartitionConfig{ Name: "aws-iso-b", DnsSuffix: "sc2s.sgov.gov", - DualStackDnsSuffix: "sc2s.sgov.gov", + DualStackDnsSuffix: "api.aws.scloud", SupportsFIPS: true, - SupportsDualStack: false, + SupportsDualStack: true, ImplicitGlobalRegion: "us-isob-east-1", }, Regions: map[string]RegionOverrides{ @@ -364,6 +386,13 @@ var partitions = []Partition{ SupportsFIPS: nil, SupportsDualStack: nil, }, + "us-isob-west-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, }, }, { @@ -372,12 +401,19 @@ var partitions = []Partition{ DefaultConfig: PartitionConfig{ Name: "aws-iso-e", DnsSuffix: "cloud.adc-e.uk", - DualStackDnsSuffix: "cloud.adc-e.uk", + DualStackDnsSuffix: "api.cloud-aws.adc-e.uk", SupportsFIPS: true, - SupportsDualStack: false, + SupportsDualStack: true, ImplicitGlobalRegion: "eu-isoe-west-1", }, Regions: map[string]RegionOverrides{ + "aws-iso-e-global": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, "eu-isoe-west-1": { Name: nil, DnsSuffix: nil, @@ -393,11 +429,68 @@ var partitions = []Partition{ DefaultConfig: PartitionConfig{ Name: "aws-iso-f", DnsSuffix: "csp.hci.ic.gov", - DualStackDnsSuffix: "csp.hci.ic.gov", + DualStackDnsSuffix: "api.aws.hci.ic.gov", SupportsFIPS: true, - SupportsDualStack: false, + SupportsDualStack: true, ImplicitGlobalRegion: "us-isof-south-1", }, - Regions: map[string]RegionOverrides{}, + Regions: map[string]RegionOverrides{ + "aws-iso-f-global": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "us-isof-east-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "us-isof-south-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + }, + }, + { + ID: "aws-us-gov", + RegionRegex: "^us\\-gov\\-\\w+\\-\\d+$", + DefaultConfig: PartitionConfig{ + Name: "aws-us-gov", + DnsSuffix: "amazonaws.com", + DualStackDnsSuffix: "api.aws", + SupportsFIPS: true, + SupportsDualStack: true, + ImplicitGlobalRegion: "us-gov-west-1", + }, + Regions: map[string]RegionOverrides{ + "aws-us-gov-global": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "us-gov-east-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + "us-gov-west-1": { + Name: nil, + DnsSuffix: nil, + DualStackDnsSuffix: nil, + SupportsFIPS: nil, + SupportsDualStack: nil, + }, + }, }, } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json index a2bfa6ead4..c789264d2b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json @@ -17,6 +17,9 @@ "ap-east-1" : { "description" : "Asia Pacific (Hong Kong)" }, + "ap-east-2" : { + "description" : "Asia Pacific (Taipei)" + }, "ap-northeast-1" : { "description" : "Asia Pacific (Tokyo)" }, @@ -47,11 +50,14 @@ "ap-southeast-5" : { "description" : "Asia Pacific (Malaysia)" }, + "ap-southeast-6" : { + "description" : "Asia Pacific (New Zealand)" + }, "ap-southeast-7" : { "description" : "Asia Pacific (Thailand)" }, "aws-global" : { - "description" : "AWS Standard global region" + "description" : "aws global region" }, "ca-central-1" : { "description" : "Canada (Central)" @@ -124,7 +130,7 @@ "regionRegex" : "^cn\\-\\w+\\-\\d+$", "regions" : { "aws-cn-global" : { - "description" : "AWS China global region" + "description" : "aws-cn global region" }, "cn-north-1" : { "description" : "China (Beijing)" @@ -134,41 +140,35 @@ } } }, { - "id" : "aws-us-gov", + "id" : "aws-eusc", "outputs" : { - "dnsSuffix" : "amazonaws.com", - "dualStackDnsSuffix" : "api.aws", - "implicitGlobalRegion" : "us-gov-west-1", - "name" : "aws-us-gov", + "dnsSuffix" : "amazonaws.eu", + "dualStackDnsSuffix" : "api.amazonwebservices.eu", + "implicitGlobalRegion" : "eusc-de-east-1", + "name" : "aws-eusc", "supportsDualStack" : true, "supportsFIPS" : true }, - "regionRegex" : "^us\\-gov\\-\\w+\\-\\d+$", + "regionRegex" : "^eusc\\-(de)\\-\\w+\\-\\d+$", "regions" : { - "aws-us-gov-global" : { - "description" : "AWS GovCloud (US) global region" - }, - "us-gov-east-1" : { - "description" : "AWS GovCloud (US-East)" - }, - "us-gov-west-1" : { - "description" : "AWS GovCloud (US-West)" + "eusc-de-east-1" : { + "description" : "EU (Germany)" } } }, { "id" : "aws-iso", "outputs" : { "dnsSuffix" : "c2s.ic.gov", - "dualStackDnsSuffix" : "c2s.ic.gov", + "dualStackDnsSuffix" : "api.aws.ic.gov", "implicitGlobalRegion" : "us-iso-east-1", "name" : "aws-iso", - "supportsDualStack" : false, + "supportsDualStack" : true, "supportsFIPS" : true }, "regionRegex" : "^us\\-iso\\-\\w+\\-\\d+$", "regions" : { "aws-iso-global" : { - "description" : "AWS ISO (US) global region" + "description" : "aws-iso global region" }, "us-iso-east-1" : { "description" : "US ISO East" @@ -181,35 +181,38 @@ "id" : "aws-iso-b", "outputs" : { "dnsSuffix" : "sc2s.sgov.gov", - "dualStackDnsSuffix" : "sc2s.sgov.gov", + "dualStackDnsSuffix" : "api.aws.scloud", "implicitGlobalRegion" : "us-isob-east-1", "name" : "aws-iso-b", - "supportsDualStack" : false, + "supportsDualStack" : true, "supportsFIPS" : true }, "regionRegex" : "^us\\-isob\\-\\w+\\-\\d+$", "regions" : { "aws-iso-b-global" : { - "description" : "AWS ISOB (US) global region" + "description" : "aws-iso-b global region" }, "us-isob-east-1" : { "description" : "US ISOB East (Ohio)" + }, + "us-isob-west-1" : { + "description" : "US ISOB West" } } }, { "id" : "aws-iso-e", "outputs" : { "dnsSuffix" : "cloud.adc-e.uk", - "dualStackDnsSuffix" : "cloud.adc-e.uk", + "dualStackDnsSuffix" : "api.cloud-aws.adc-e.uk", "implicitGlobalRegion" : "eu-isoe-west-1", "name" : "aws-iso-e", - "supportsDualStack" : false, + "supportsDualStack" : true, "supportsFIPS" : true }, "regionRegex" : "^eu\\-isoe\\-\\w+\\-\\d+$", "regions" : { "aws-iso-e-global" : { - "description" : "AWS ISOE (Europe) global region" + "description" : "aws-iso-e global region" }, "eu-isoe-west-1" : { "description" : "EU ISOE West" @@ -219,16 +222,16 @@ "id" : "aws-iso-f", "outputs" : { "dnsSuffix" : "csp.hci.ic.gov", - "dualStackDnsSuffix" : "csp.hci.ic.gov", + "dualStackDnsSuffix" : "api.aws.hci.ic.gov", "implicitGlobalRegion" : "us-isof-south-1", "name" : "aws-iso-f", - "supportsDualStack" : false, + "supportsDualStack" : true, "supportsFIPS" : true }, "regionRegex" : "^us\\-isof\\-\\w+\\-\\d+$", "regions" : { "aws-iso-f-global" : { - "description" : "AWS ISOF global region" + "description" : "aws-iso-f global region" }, "us-isof-east-1" : { "description" : "US ISOF EAST" @@ -238,19 +241,25 @@ } } }, { - "id" : "aws-eusc", + "id" : "aws-us-gov", "outputs" : { - "dnsSuffix" : "amazonaws.eu", - "dualStackDnsSuffix" : "amazonaws.eu", - "implicitGlobalRegion" : "eusc-de-east-1", - "name" : "aws-eusc", - "supportsDualStack" : false, + "dnsSuffix" : "amazonaws.com", + "dualStackDnsSuffix" : "api.aws", + "implicitGlobalRegion" : "us-gov-west-1", + "name" : "aws-us-gov", + "supportsDualStack" : true, "supportsFIPS" : true }, - "regionRegex" : "^eusc\\-(de)\\-\\w+\\-\\d+$", + "regionRegex" : "^us\\-gov\\-\\w+\\-\\d+$", "regions" : { - "eusc-de-east-1" : { - "description" : "EU (Germany)" + "aws-us-gov-global" : { + "description" : "aws-us-gov global region" + }, + "us-gov-east-1" : { + "description" : "AWS GovCloud (US-East)" + }, + "us-gov-west-1" : { + "description" : "AWS GovCloud (US-West)" } } } ], diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md index b56edee377..caa16de3b3 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md @@ -1,3 +1,76 @@ +# v2.7.14 (2025-11-19.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.13 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v2.7.12 (2025-10-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.11 (2025-10-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.10 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.9 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.8 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.7 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.6 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.5 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.4 (2025-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.3 (2025-08-11) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.2 (2025-08-04) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.1 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.7.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.6.37 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v2.6.36 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + # v2.6.35 (2025-06-10) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go index e7ebb2f5fa..0606394d49 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go @@ -3,4 +3,4 @@ package endpoints // goModuleVersion is the tagged release for this module -const goModuleVersion = "2.6.35" +const goModuleVersion = "2.7.14" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/CHANGELOG.md index f729db535b..4791d328c0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/CHANGELOG.md @@ -1,3 +1,7 @@ +# v1.8.4 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. + # v1.8.3 (2025-02-18) * **Bug Fix**: Bump go version to 1.22 diff --git a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/go_module_metadata.go index 00df0e3cb9..f94970e774 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/internal/ini/go_module_metadata.go @@ -3,4 +3,4 @@ package ini // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.8.3" +const goModuleVersion = "1.8.4" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/CHANGELOG.md index 4c2604e6b5..d2615d1133 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/CHANGELOG.md @@ -1,3 +1,145 @@ +# v1.51.2 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.51.1 (2025-10-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.51.0 (2025-10-23) + +* **Feature**: Update endpoint ruleset parameters casing +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.50.7 (2025-10-22) + +* No change notes available for this release. + +# v1.50.6 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.50.5 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.50.4 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.50.3 (2025-09-10) + +* No change notes available for this release. + +# v1.50.2 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.50.1 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.50.0 (2025-08-28) + +* **Feature**: Remove incorrect endpoint tests + +# v1.49.3 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.49.2 (2025-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.49.1 (2025-08-20) + +* **Bug Fix**: Remove unused deserialization code. + +# v1.49.0 (2025-08-11) + +* **Feature**: Add support for configuring per-service Options via callback on global config. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.48.0 (2025-08-04) + +* **Feature**: Support configurable auth scheme preferences in service clients via AWS_AUTH_SCHEME_PREFERENCE in the environment, auth_scheme_preference in the config file, and through in-code settings on LoadDefaultConfig and client constructor methods. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.47.1 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.47.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.46.0 (2025-07-22) + +* **Feature**: Add support for Image Tag Mutability Exception feature, allowing repositories to define wildcard-based patterns that override the default image tag mutability settings. + +# v1.45.2 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.45.1 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.45.0 (2025-06-16) + +* **Feature**: The `DescribeImageScanning` API now includes `lastInUseAt` and `InUseCount` fields that can be used to prioritize vulnerability remediation for images that are actively being used. + +# v1.44.2 (2025-06-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.44.1 (2025-06-06) + +* No change notes available for this release. + +# v1.44.0 (2025-04-30) + +* **Feature**: Adds dualstack support for Amazon Elastic Container Registry (Amazon ECR). + +# v1.43.3 (2025-04-10) + +* No change notes available for this release. + +# v1.43.2 (2025-04-03) + +* No change notes available for this release. + +# v1.43.1 (2025-04-02) + +* **Documentation**: Fix for customer issues related to AWS account ID and size limitation for token. + +# v1.43.0 (2025-03-11) + +* **Feature**: This release adds Amazon ECR to Amazon ECR pull through cache rules support. + +# v1.42.1 (2025-03-04.2) + +* **Bug Fix**: Add assurance test for operation order. + +# v1.42.0 (2025-02-27) + +* **Feature**: Track credential providers via User-Agent Feature ids +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.41.1 (2025-02-18) + +* **Bug Fix**: Bump go version to 1.22 +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.41.0 (2025-02-07) + +* **Feature**: Adds support to handle the new basic scanning daily quota. + # v1.40.3 (2025-02-05) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_client.go index 1cc8f55cfd..5572342310 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_client.go @@ -420,24 +420,33 @@ func setResolvedDefaultsMode(o *Options) { // NewFromConfig returns a new client from the provided config. func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, + Region: cfg.Region, + DefaultsMode: cfg.DefaultsMode, + RuntimeEnvironment: cfg.RuntimeEnvironment, + HTTPClient: cfg.HTTPClient, + Credentials: cfg.Credentials, + APIOptions: cfg.APIOptions, + Logger: cfg.Logger, + ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, + AuthSchemePreference: cfg.AuthSchemePreference, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) resolveAWSRetryMode(cfg, &opts) resolveAWSEndpointResolver(cfg, &opts) + resolveInterceptors(cfg, &opts) resolveUseDualStackEndpoint(cfg, &opts) resolveUseFIPSEndpoint(cfg, &opts) resolveBaseEndpoint(cfg, &opts) - return New(opts, optFns...) + return New(opts, func(o *Options) { + for _, opt := range cfg.ServiceOptions { + opt(ServiceID, o) + } + for _, opt := range optFns { + opt(o) + } + }) } func resolveHTTPClient(o *Options) { @@ -551,6 +560,10 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } +func resolveInterceptors(cfg aws.Config, o *Options) { + o.Interceptors = cfg.Interceptors.Copy() +} + func addClientUserAgent(stack *middleware.Stack, options Options) error { ua, err := getOrAddRequestUserAgent(stack) if err != nil { @@ -762,6 +775,37 @@ func addUserAgentRetryMode(stack *middleware.Stack, options Options) error { return nil } +type setCredentialSourceMiddleware struct { + ua *awsmiddleware.RequestUserAgent + options Options +} + +func (m setCredentialSourceMiddleware) ID() string { return "SetCredentialSourceMiddleware" } + +func (m setCredentialSourceMiddleware) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) ( + out middleware.BuildOutput, metadata middleware.Metadata, err error, +) { + asProviderSource, ok := m.options.Credentials.(aws.CredentialProviderSource) + if !ok { + return next.HandleBuild(ctx, in) + } + providerSources := asProviderSource.ProviderSources() + for _, source := range providerSources { + m.ua.AddCredentialsSource(source) + } + return next.HandleBuild(ctx, in) +} + +func addCredentialSource(stack *middleware.Stack, options Options) error { + ua, err := getOrAddRequestUserAgent(stack) + if err != nil { + return err + } + + mw := setCredentialSourceMiddleware{ua: ua, options: options} + return stack.Build.Insert(&mw, "UserAgent", middleware.Before) +} + func resolveTracerProvider(options *Options) { if options.TracerProvider == nil { options.TracerProvider = &tracing.NopTracerProvider{} @@ -826,6 +870,69 @@ func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { }, "ResolveEndpointV2", middleware.After) } +func addInterceptBeforeRetryLoop(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptBeforeRetryLoop{ + Interceptors: opts.Interceptors.BeforeRetryLoop, + }, "Retry", middleware.Before) +} + +func addInterceptAttempt(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptAttempt{ + BeforeAttempt: opts.Interceptors.BeforeAttempt, + AfterAttempt: opts.Interceptors.AfterAttempt, + }, "Retry", middleware.After) +} + +func addInterceptExecution(stack *middleware.Stack, opts Options) error { + return stack.Initialize.Add(&smithyhttp.InterceptExecution{ + BeforeExecution: opts.Interceptors.BeforeExecution, + AfterExecution: opts.Interceptors.AfterExecution, + }, middleware.Before) +} + +func addInterceptBeforeSerialization(stack *middleware.Stack, opts Options) error { + return stack.Serialize.Insert(&smithyhttp.InterceptBeforeSerialization{ + Interceptors: opts.Interceptors.BeforeSerialization, + }, "OperationSerializer", middleware.Before) +} + +func addInterceptAfterSerialization(stack *middleware.Stack, opts Options) error { + return stack.Serialize.Insert(&smithyhttp.InterceptAfterSerialization{ + Interceptors: opts.Interceptors.AfterSerialization, + }, "OperationSerializer", middleware.After) +} + +func addInterceptBeforeSigning(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptBeforeSigning{ + Interceptors: opts.Interceptors.BeforeSigning, + }, "Signing", middleware.Before) +} + +func addInterceptAfterSigning(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptAfterSigning{ + Interceptors: opts.Interceptors.AfterSigning, + }, "Signing", middleware.After) +} + +func addInterceptTransmit(stack *middleware.Stack, opts Options) error { + return stack.Deserialize.Add(&smithyhttp.InterceptTransmit{ + BeforeTransmit: opts.Interceptors.BeforeTransmit, + AfterTransmit: opts.Interceptors.AfterTransmit, + }, middleware.After) +} + +func addInterceptBeforeDeserialization(stack *middleware.Stack, opts Options) error { + return stack.Deserialize.Insert(&smithyhttp.InterceptBeforeDeserialization{ + Interceptors: opts.Interceptors.BeforeDeserialization, + }, "OperationDeserializer", middleware.After) // (deserialize stack is called in reverse) +} + +func addInterceptAfterDeserialization(stack *middleware.Stack, opts Options) error { + return stack.Deserialize.Insert(&smithyhttp.InterceptAfterDeserialization{ + Interceptors: opts.Interceptors.AfterDeserialization, + }, "OperationDeserializer", middleware.Before) +} + type spanInitializeStart struct { } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchCheckLayerAvailability.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchCheckLayerAvailability.go index a0a36f6a6c..5ab6935844 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchCheckLayerAvailability.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchCheckLayerAvailability.go @@ -134,6 +134,9 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpBatchCheckLayerAvailabilityValidationMiddleware(stack); err != nil { return err } @@ -155,6 +158,36 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchDeleteImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchDeleteImage.go index ea63234bbf..80ea58e623 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchDeleteImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchDeleteImage.go @@ -136,6 +136,9 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpBatchDeleteImageValidationMiddleware(stack); err != nil { return err } @@ -157,6 +160,36 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetImage.go index 5bff06008f..a9e25ba0af 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetImage.go @@ -137,6 +137,9 @@ func (c *Client) addOperationBatchGetImageMiddlewares(stack *middleware.Stack, o if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpBatchGetImageValidationMiddleware(stack); err != nil { return err } @@ -158,6 +161,36 @@ func (c *Client) addOperationBatchGetImageMiddlewares(stack *middleware.Stack, o if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetRepositoryScanningConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetRepositoryScanningConfiguration.go index ba467c87b6..246683be21 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetRepositoryScanningConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetRepositoryScanningConfiguration.go @@ -115,6 +115,9 @@ func (c *Client) addOperationBatchGetRepositoryScanningConfigurationMiddlewares( if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpBatchGetRepositoryScanningConfigurationValidationMiddleware(stack); err != nil { return err } @@ -136,6 +139,36 @@ func (c *Client) addOperationBatchGetRepositoryScanningConfigurationMiddlewares( if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CompleteLayerUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CompleteLayerUpload.go index 3106abb294..d86d911f26 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CompleteLayerUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CompleteLayerUpload.go @@ -144,6 +144,9 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpCompleteLayerUploadValidationMiddleware(stack); err != nil { return err } @@ -165,6 +168,36 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreatePullThroughCacheRule.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreatePullThroughCacheRule.go index b7f4e1407f..16a5ba9520 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreatePullThroughCacheRule.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreatePullThroughCacheRule.go @@ -37,6 +37,9 @@ type CreatePullThroughCacheRuleInput struct { // The repository name prefix to use when caching images from the source registry. // + // There is always an assumed / applied to the end of the prefix. If you specify + // ecr-public as the prefix, Amazon ECR treats that as ecr-public/ . + // // This member is required. EcrRepositoryPrefix *string @@ -44,19 +47,24 @@ type CreatePullThroughCacheRuleInput struct { // pull through cache rule. The following is the syntax to use for each supported // upstream registry. // - // - Amazon ECR Public ( ecr-public ) - public.ecr.aws + // - Amazon ECR ( ecr ) – .dkr.ecr..amazonaws.com + // + // - Amazon ECR Public ( ecr-public ) – public.ecr.aws // - // - Docker Hub ( docker-hub ) - registry-1.docker.io + // - Docker Hub ( docker-hub ) – registry-1.docker.io // - // - Quay ( quay ) - quay.io + // - GitHub Container Registry ( github-container-registry ) – ghcr.io // - // - Kubernetes ( k8s ) - registry.k8s.io + // - GitLab Container Registry ( gitlab-container-registry ) – + // registry.gitlab.com // - // - GitHub Container Registry ( github-container-registry ) - ghcr.io + // - Kubernetes ( k8s ) – registry.k8s.io // - // - Microsoft Azure Container Registry ( azure-container-registry ) - + // - Microsoft Azure Container Registry ( azure-container-registry ) – // .azurecr.io // + // - Quay ( quay ) – quay.io + // // This member is required. UpstreamRegistryUrl *string @@ -64,6 +72,11 @@ type CreatePullThroughCacheRuleInput struct { // secret that identifies the credentials to authenticate to the upstream registry. CredentialArn *string + // Amazon Resource Name (ARN) of the IAM role to be assumed by Amazon ECR to + // authenticate to the ECR upstream registry. This role must be in the same account + // as the registry that you are configuring. + CustomRoleArn *string + // The Amazon Web Services account ID associated with the registry to create the // pull through cache rule for. If you do not specify a registry, the default // registry is assumed. @@ -72,6 +85,10 @@ type CreatePullThroughCacheRuleInput struct { // The name of the upstream registry. UpstreamRegistry types.UpstreamRegistry + // The repository name prefix of the upstream registry to match with the upstream + // repository name. When this field isn't specified, Amazon ECR will use the ROOT . + UpstreamRepositoryPrefix *string + noSmithyDocumentSerde } @@ -85,6 +102,9 @@ type CreatePullThroughCacheRuleOutput struct { // secret associated with the pull through cache rule. CredentialArn *string + // The ARN of the IAM role associated with the pull through cache rule. + CustomRoleArn *string + // The Amazon ECR repository prefix associated with the pull through cache rule. EcrRepositoryPrefix *string @@ -97,6 +117,9 @@ type CreatePullThroughCacheRuleOutput struct { // The upstream registry URL associated with the pull through cache rule. UpstreamRegistryUrl *string + // The upstream repository prefix associated with the pull through cache rule. + UpstreamRepositoryPrefix *string + // Metadata pertaining to the operation's result. ResultMetadata middleware.Metadata @@ -167,6 +190,9 @@ func (c *Client) addOperationCreatePullThroughCacheRuleMiddlewares(stack *middle if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpCreatePullThroughCacheRuleValidationMiddleware(stack); err != nil { return err } @@ -188,6 +214,36 @@ func (c *Client) addOperationCreatePullThroughCacheRuleMiddlewares(stack *middle if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepository.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepository.go index b51da6915d..f4a17f3cdc 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepository.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepository.go @@ -57,6 +57,10 @@ type CreateRepositoryInput struct { // will be immutable which will prevent them from being overwritten. ImageTagMutability types.ImageTagMutability + // Creates a repository with a list of filters that define which image tags can + // override the default image tag mutability setting. + ImageTagMutabilityExclusionFilters []types.ImageTagMutabilityExclusionFilter + // The Amazon Web Services account ID associated with the registry to create the // repository. If you do not specify a registry, the default registry is assumed. RegistryId *string @@ -145,6 +149,9 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpCreateRepositoryValidationMiddleware(stack); err != nil { return err } @@ -166,6 +173,36 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepositoryCreationTemplate.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepositoryCreationTemplate.go index 5f94b037de..2c438c12a3 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepositoryCreationTemplate.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepositoryCreationTemplate.go @@ -77,6 +77,10 @@ type CreateRepositoryCreationTemplateInput struct { // will be immutable which will prevent them from being overwritten. ImageTagMutability types.ImageTagMutability + // Creates a repository creation template with a list of filters that define which + // image tags can override the default image tag mutability setting. + ImageTagMutabilityExclusionFilters []types.ImageTagMutabilityExclusionFilter + // The lifecycle policy to use for repositories created using the template. LifecyclePolicy *string @@ -172,6 +176,9 @@ func (c *Client) addOperationCreateRepositoryCreationTemplateMiddlewares(stack * if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpCreateRepositoryCreationTemplateValidationMiddleware(stack); err != nil { return err } @@ -193,6 +200,36 @@ func (c *Client) addOperationCreateRepositoryCreationTemplateMiddlewares(stack * if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteLifecyclePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteLifecyclePolicy.go index 73f3f88266..33e3558b0f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteLifecyclePolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteLifecyclePolicy.go @@ -126,6 +126,9 @@ func (c *Client) addOperationDeleteLifecyclePolicyMiddlewares(stack *middleware. if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpDeleteLifecyclePolicyValidationMiddleware(stack); err != nil { return err } @@ -147,6 +150,36 @@ func (c *Client) addOperationDeleteLifecyclePolicyMiddlewares(stack *middleware. if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeletePullThroughCacheRule.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeletePullThroughCacheRule.go index 8fabe7584d..bb18f774d9 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeletePullThroughCacheRule.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeletePullThroughCacheRule.go @@ -52,6 +52,9 @@ type DeletePullThroughCacheRuleOutput struct { // secret associated with the pull through cache rule. CredentialArn *string + // The ARN of the IAM role associated with the pull through cache rule. + CustomRoleArn *string + // The Amazon ECR repository prefix associated with the request. EcrRepositoryPrefix *string @@ -61,6 +64,9 @@ type DeletePullThroughCacheRuleOutput struct { // The upstream registry URL associated with the pull through cache rule. UpstreamRegistryUrl *string + // The upstream repository prefix associated with the pull through cache rule. + UpstreamRepositoryPrefix *string + // Metadata pertaining to the operation's result. ResultMetadata middleware.Metadata @@ -131,6 +137,9 @@ func (c *Client) addOperationDeletePullThroughCacheRuleMiddlewares(stack *middle if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpDeletePullThroughCacheRuleValidationMiddleware(stack); err != nil { return err } @@ -152,6 +161,36 @@ func (c *Client) addOperationDeletePullThroughCacheRuleMiddlewares(stack *middle if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRegistryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRegistryPolicy.go index 05405eee71..dbefac8b6e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRegistryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRegistryPolicy.go @@ -108,6 +108,9 @@ func (c *Client) addOperationDeleteRegistryPolicyMiddlewares(stack *middleware.S if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteRegistryPolicy(options.Region), middleware.Before); err != nil { return err } @@ -126,6 +129,36 @@ func (c *Client) addOperationDeleteRegistryPolicyMiddlewares(stack *middleware.S if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepository.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepository.go index feea5319fb..71208befdc 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepository.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepository.go @@ -123,6 +123,9 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpDeleteRepositoryValidationMiddleware(stack); err != nil { return err } @@ -144,6 +147,36 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryCreationTemplate.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryCreationTemplate.go index 98fa1cd10a..de1c3eff36 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryCreationTemplate.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryCreationTemplate.go @@ -116,6 +116,9 @@ func (c *Client) addOperationDeleteRepositoryCreationTemplateMiddlewares(stack * if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpDeleteRepositoryCreationTemplateValidationMiddleware(stack); err != nil { return err } @@ -137,6 +140,36 @@ func (c *Client) addOperationDeleteRepositoryCreationTemplateMiddlewares(stack * if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryPolicy.go index 9ad27321f1..2e9b4055bc 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryPolicy.go @@ -123,6 +123,9 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpDeleteRepositoryPolicyValidationMiddleware(stack); err != nil { return err } @@ -144,6 +147,36 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageReplicationStatus.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageReplicationStatus.go index f674ea0cbe..405a79517c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageReplicationStatus.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageReplicationStatus.go @@ -127,6 +127,9 @@ func (c *Client) addOperationDescribeImageReplicationStatusMiddlewares(stack *mi if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpDescribeImageReplicationStatusValidationMiddleware(stack); err != nil { return err } @@ -148,6 +151,36 @@ func (c *Client) addOperationDescribeImageReplicationStatusMiddlewares(stack *mi if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageScanFindings.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageScanFindings.go index b332e59383..ba960ad8e4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageScanFindings.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageScanFindings.go @@ -160,6 +160,9 @@ func (c *Client) addOperationDescribeImageScanFindingsMiddlewares(stack *middlew if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpDescribeImageScanFindingsValidationMiddleware(stack); err != nil { return err } @@ -181,6 +184,36 @@ func (c *Client) addOperationDescribeImageScanFindingsMiddlewares(stack *middlew if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImages.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImages.go index 7d7e1a705d..902da4bfb5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImages.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImages.go @@ -13,10 +13,16 @@ import ( // Returns metadata about the images in a repository. // -// Beginning with Docker version 1.9, the Docker client compresses image layers +// Starting with Docker version 1.9, the Docker client compresses image layers // before pushing them to a V2 Docker registry. The output of the docker images -// command shows the uncompressed image size, so it may return a larger image size -// than the image sizes returned by DescribeImages. +// command shows the uncompressed image size. Therefore, Docker might return a +// larger image than the image shown in the Amazon Web Services Management Console. +// +// The new version of Amazon ECR Basic Scanning doesn't use the ImageDetail$imageScanFindingsSummary and ImageDetail$imageScanStatus attributes +// from the API response to return scan results. Use the DescribeImageScanFindingsAPI instead. For more +// information about Amazon Web Services native basic scanning, see [Scan images for software vulnerabilities in Amazon ECR]. +// +// [Scan images for software vulnerabilities in Amazon ECR]: https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html func (c *Client) DescribeImages(ctx context.Context, params *DescribeImagesInput, optFns ...func(*Options)) (*DescribeImagesOutput, error) { if params == nil { params = &DescribeImagesInput{} @@ -151,6 +157,9 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpDescribeImagesValidationMiddleware(stack); err != nil { return err } @@ -172,6 +181,36 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribePullThroughCacheRules.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribePullThroughCacheRules.go index 95933334e0..8bc3693414 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribePullThroughCacheRules.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribePullThroughCacheRules.go @@ -141,6 +141,9 @@ func (c *Client) addOperationDescribePullThroughCacheRulesMiddlewares(stack *mid if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribePullThroughCacheRules(options.Region), middleware.Before); err != nil { return err } @@ -159,6 +162,36 @@ func (c *Client) addOperationDescribePullThroughCacheRulesMiddlewares(stack *mid if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRegistry.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRegistry.go index 5d5620ec0c..a446bfa39f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRegistry.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRegistry.go @@ -110,6 +110,9 @@ func (c *Client) addOperationDescribeRegistryMiddlewares(stack *middleware.Stack if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeRegistry(options.Region), middleware.Before); err != nil { return err } @@ -128,6 +131,36 @@ func (c *Client) addOperationDescribeRegistryMiddlewares(stack *middleware.Stack if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositories.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositories.go index dc23fd0fb4..61ad20dbf6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositories.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositories.go @@ -144,6 +144,9 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeRepositories(options.Region), middleware.Before); err != nil { return err } @@ -162,6 +165,36 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositoryCreationTemplates.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositoryCreationTemplates.go index a5b6cd7086..9ad5265c1d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositoryCreationTemplates.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositoryCreationTemplates.go @@ -144,6 +144,9 @@ func (c *Client) addOperationDescribeRepositoryCreationTemplatesMiddlewares(stac if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeRepositoryCreationTemplates(options.Region), middleware.Before); err != nil { return err } @@ -162,6 +165,36 @@ func (c *Client) addOperationDescribeRepositoryCreationTemplatesMiddlewares(stac if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAccountSetting.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAccountSetting.go index 81d103ae23..9451c475b1 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAccountSetting.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAccountSetting.go @@ -117,6 +117,9 @@ func (c *Client) addOperationGetAccountSettingMiddlewares(stack *middleware.Stac if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpGetAccountSettingValidationMiddleware(stack); err != nil { return err } @@ -138,6 +141,36 @@ func (c *Client) addOperationGetAccountSettingMiddlewares(stack *middleware.Stac if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAuthorizationToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAuthorizationToken.go index c29ba7b44e..18b1f7e74f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAuthorizationToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAuthorizationToken.go @@ -56,6 +56,9 @@ type GetAuthorizationTokenOutput struct { // A list of authorization token data objects that correspond to the registryIds // values in the request. + // + // The size of the authorization token returned by Amazon ECR is not fixed. We + // recommend that you don't make assumptions about the maximum size. AuthorizationData []types.AuthorizationData // Metadata pertaining to the operation's result. @@ -128,6 +131,9 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetAuthorizationToken(options.Region), middleware.Before); err != nil { return err } @@ -146,6 +152,36 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetDownloadUrlForLayer.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetDownloadUrlForLayer.go index 891045572e..320c3ad346 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetDownloadUrlForLayer.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetDownloadUrlForLayer.go @@ -132,6 +132,9 @@ func (c *Client) addOperationGetDownloadUrlForLayerMiddlewares(stack *middleware if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpGetDownloadUrlForLayerValidationMiddleware(stack); err != nil { return err } @@ -153,6 +156,36 @@ func (c *Client) addOperationGetDownloadUrlForLayerMiddlewares(stack *middleware if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicy.go index 408a61534d..6d2b25a6fc 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicy.go @@ -126,6 +126,9 @@ func (c *Client) addOperationGetLifecyclePolicyMiddlewares(stack *middleware.Sta if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpGetLifecyclePolicyValidationMiddleware(stack); err != nil { return err } @@ -147,6 +150,36 @@ func (c *Client) addOperationGetLifecyclePolicyMiddlewares(stack *middleware.Sta if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicyPreview.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicyPreview.go index 482152df72..9573b3d7c5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicyPreview.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicyPreview.go @@ -51,8 +51,8 @@ type GetLifecyclePolicyPreviewInput struct { // single page along with a nextToken 
 response element. The remaining results of // the initial request can be seen by sending
 another // GetLifecyclePolicyPreviewRequest request with the returned nextToken 
 value. - // This value can be between 1 and 1000. If this
 parameter is not used, then - // GetLifecyclePolicyPreviewRequest returns up to
 100 results and a nextToken + // This value can be between 1 and 100. If this
 parameter is not used, then + // GetLifecyclePolicyPreviewRequest returns up to
100 results and a nextToken // value, if
 applicable. This option cannot be used when you specify images with // imageIds . MaxResults *int32 @@ -169,6 +169,9 @@ func (c *Client) addOperationGetLifecyclePolicyPreviewMiddlewares(stack *middlew if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpGetLifecyclePolicyPreviewValidationMiddleware(stack); err != nil { return err } @@ -190,6 +193,36 @@ func (c *Client) addOperationGetLifecyclePolicyPreviewMiddlewares(stack *middlew if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } @@ -404,8 +437,8 @@ type GetLifecyclePolicyPreviewPaginatorOptions struct { // single page along with a nextToken 
 response element. The remaining results of // the initial request can be seen by sending
 another // GetLifecyclePolicyPreviewRequest request with the returned nextToken 
 value. - // This value can be between 1 and 1000. If this
 parameter is not used, then - // GetLifecyclePolicyPreviewRequest returns up to
 100 results and a nextToken + // This value can be between 1 and 100. If this
 parameter is not used, then + // GetLifecyclePolicyPreviewRequest returns up to
100 results and a nextToken // value, if
 applicable. This option cannot be used when you specify images with // imageIds . Limit int32 diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryPolicy.go index 420344e663..c84fc4793d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryPolicy.go @@ -108,6 +108,9 @@ func (c *Client) addOperationGetRegistryPolicyMiddlewares(stack *middleware.Stac if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRegistryPolicy(options.Region), middleware.Before); err != nil { return err } @@ -126,6 +129,36 @@ func (c *Client) addOperationGetRegistryPolicyMiddlewares(stack *middleware.Stac if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryScanningConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryScanningConfiguration.go index 5955ff467e..ec243a8481 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryScanningConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryScanningConfiguration.go @@ -109,6 +109,9 @@ func (c *Client) addOperationGetRegistryScanningConfigurationMiddlewares(stack * if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRegistryScanningConfiguration(options.Region), middleware.Before); err != nil { return err } @@ -127,6 +130,36 @@ func (c *Client) addOperationGetRegistryScanningConfigurationMiddlewares(stack * if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRepositoryPolicy.go index a7325987f8..49a8dafa45 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRepositoryPolicy.go @@ -122,6 +122,9 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpGetRepositoryPolicyValidationMiddleware(stack); err != nil { return err } @@ -143,6 +146,36 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_InitiateLayerUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_InitiateLayerUpload.go index f5b62d505e..8df33c6229 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_InitiateLayerUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_InitiateLayerUpload.go @@ -128,6 +128,9 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpInitiateLayerUploadValidationMiddleware(stack); err != nil { return err } @@ -149,6 +152,36 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListImages.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListImages.go index 09f0f065a3..e6bee37504 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListImages.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListImages.go @@ -150,6 +150,9 @@ func (c *Client) addOperationListImagesMiddlewares(stack *middleware.Stack, opti if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpListImagesValidationMiddleware(stack); err != nil { return err } @@ -171,6 +174,36 @@ func (c *Client) addOperationListImagesMiddlewares(stack *middleware.Stack, opti if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListTagsForResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListTagsForResource.go index 00ecd807f1..8ca66d3b10 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListTagsForResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListTagsForResource.go @@ -113,6 +113,9 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpListTagsForResourceValidationMiddleware(stack); err != nil { return err } @@ -134,6 +137,36 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutAccountSetting.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutAccountSetting.go index 2075a4127e..307963e80a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutAccountSetting.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutAccountSetting.go @@ -122,6 +122,9 @@ func (c *Client) addOperationPutAccountSettingMiddlewares(stack *middleware.Stac if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpPutAccountSettingValidationMiddleware(stack); err != nil { return err } @@ -143,6 +146,36 @@ func (c *Client) addOperationPutAccountSettingMiddlewares(stack *middleware.Stac if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImage.go index d63228f6d1..d15bd664cb 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImage.go @@ -143,6 +143,9 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpPutImageValidationMiddleware(stack); err != nil { return err } @@ -164,6 +167,36 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageScanningConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageScanningConfiguration.go index 322c84dae0..87640bdc5b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageScanningConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageScanningConfiguration.go @@ -135,6 +135,9 @@ func (c *Client) addOperationPutImageScanningConfigurationMiddlewares(stack *mid if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpPutImageScanningConfigurationValidationMiddleware(stack); err != nil { return err } @@ -156,6 +159,36 @@ func (c *Client) addOperationPutImageScanningConfigurationMiddlewares(stack *mid if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageTagMutability.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageTagMutability.go index e1b4c3c93e..430eb52650 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageTagMutability.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageTagMutability.go @@ -44,6 +44,10 @@ type PutImageTagMutabilityInput struct { // This member is required. RepositoryName *string + // Creates or updates a repository with filters that define which image tags can + // override the default image tag mutability setting. + ImageTagMutabilityExclusionFilters []types.ImageTagMutabilityExclusionFilter + // The Amazon Web Services account ID associated with the registry that contains // the repository in which to update the image tag mutability settings. If you do // not specify a registry, the default registry is assumed. @@ -57,6 +61,11 @@ type PutImageTagMutabilityOutput struct { // The image tag mutability setting for the repository. ImageTagMutability types.ImageTagMutability + // Returns a list of filters that were defined for a repository. These filters + // determine which image tags can override the default image tag mutability setting + // of the repository. + ImageTagMutabilityExclusionFilters []types.ImageTagMutabilityExclusionFilter + // The registry ID associated with the request. RegistryId *string @@ -133,6 +142,9 @@ func (c *Client) addOperationPutImageTagMutabilityMiddlewares(stack *middleware. if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpPutImageTagMutabilityValidationMiddleware(stack); err != nil { return err } @@ -154,6 +166,36 @@ func (c *Client) addOperationPutImageTagMutabilityMiddlewares(stack *middleware. if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutLifecyclePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutLifecyclePolicy.go index 4e8121861b..c028d9b285 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutLifecyclePolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutLifecyclePolicy.go @@ -130,6 +130,9 @@ func (c *Client) addOperationPutLifecyclePolicyMiddlewares(stack *middleware.Sta if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpPutLifecyclePolicyValidationMiddleware(stack); err != nil { return err } @@ -151,6 +154,36 @@ func (c *Client) addOperationPutLifecyclePolicyMiddlewares(stack *middleware.Sta if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryPolicy.go index c806dbf572..3606be43c6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryPolicy.go @@ -124,6 +124,9 @@ func (c *Client) addOperationPutRegistryPolicyMiddlewares(stack *middleware.Stac if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpPutRegistryPolicyValidationMiddleware(stack); err != nil { return err } @@ -145,6 +148,36 @@ func (c *Client) addOperationPutRegistryPolicyMiddlewares(stack *middleware.Stac if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryScanningConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryScanningConfiguration.go index c57f87d7d5..257e8e7d66 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryScanningConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryScanningConfiguration.go @@ -126,6 +126,9 @@ func (c *Client) addOperationPutRegistryScanningConfigurationMiddlewares(stack * if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpPutRegistryScanningConfigurationValidationMiddleware(stack); err != nil { return err } @@ -147,6 +150,36 @@ func (c *Client) addOperationPutRegistryScanningConfigurationMiddlewares(stack * if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutReplicationConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutReplicationConfiguration.go index 24fd26d696..b5f7b778f7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutReplicationConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutReplicationConfiguration.go @@ -124,6 +124,9 @@ func (c *Client) addOperationPutReplicationConfigurationMiddlewares(stack *middl if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpPutReplicationConfigurationValidationMiddleware(stack); err != nil { return err } @@ -145,6 +148,36 @@ func (c *Client) addOperationPutReplicationConfigurationMiddlewares(stack *middl if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_SetRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_SetRepositoryPolicy.go index 36a788b70a..9394b38412 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_SetRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_SetRepositoryPolicy.go @@ -139,6 +139,9 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpSetRepositoryPolicyValidationMiddleware(stack); err != nil { return err } @@ -160,6 +163,36 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartImageScan.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartImageScan.go index 1f3e794e84..0f1d35884d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartImageScan.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartImageScan.go @@ -11,12 +11,15 @@ import ( smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Starts an image vulnerability scan. An image scan can only be started once per -// 24 hours on an individual image. This limit includes if an image was scanned on -// initial push. For more information, see [Image scanning]in the Amazon Elastic Container -// Registry User Guide. +// Starts a basic image vulnerability scan. // -// [Image scanning]: https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html +// A basic image scan can only be started once per 24 hours on an individual +// image. This limit includes if an image was scanned on initial push. You can +// start up to 100,000 basic scans per 24 hours. This limit includes both scans on +// initial push and scans initiated by the StartImageScan API. For more +// information, see [Basic scanning]in the Amazon Elastic Container Registry User Guide. +// +// [Basic scanning]: https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning-basic.html func (c *Client) StartImageScan(ctx context.Context, params *StartImageScanInput, optFns ...func(*Options)) (*StartImageScanOutput, error) { if params == nil { params = &StartImageScanInput{} @@ -136,6 +139,9 @@ func (c *Client) addOperationStartImageScanMiddlewares(stack *middleware.Stack, if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpStartImageScanValidationMiddleware(stack); err != nil { return err } @@ -157,6 +163,36 @@ func (c *Client) addOperationStartImageScanMiddlewares(stack *middleware.Stack, if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartLifecyclePolicyPreview.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartLifecyclePolicyPreview.go index a2b2bb1b44..33b1f98fc8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartLifecyclePolicyPreview.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartLifecyclePolicyPreview.go @@ -132,6 +132,9 @@ func (c *Client) addOperationStartLifecyclePolicyPreviewMiddlewares(stack *middl if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpStartLifecyclePolicyPreviewValidationMiddleware(stack); err != nil { return err } @@ -153,6 +156,36 @@ func (c *Client) addOperationStartLifecyclePolicyPreviewMiddlewares(stack *middl if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_TagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_TagResource.go index 3974ab0268..0d0e785977 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_TagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_TagResource.go @@ -117,6 +117,9 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpTagResourceValidationMiddleware(stack); err != nil { return err } @@ -138,6 +141,36 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UntagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UntagResource.go index e28d0d0182..b5ff38af20 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UntagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UntagResource.go @@ -113,6 +113,9 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpUntagResourceValidationMiddleware(stack); err != nil { return err } @@ -134,6 +137,36 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UpdatePullThroughCacheRule.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UpdatePullThroughCacheRule.go index d40712e4f6..b8bc8f968f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UpdatePullThroughCacheRule.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UpdatePullThroughCacheRule.go @@ -29,17 +29,20 @@ func (c *Client) UpdatePullThroughCacheRule(ctx context.Context, params *UpdateP type UpdatePullThroughCacheRuleInput struct { - // The Amazon Resource Name (ARN) of the Amazon Web Services Secrets Manager - // secret that identifies the credentials to authenticate to the upstream registry. - // - // This member is required. - CredentialArn *string - // The repository name prefix to use when caching images from the source registry. // // This member is required. EcrRepositoryPrefix *string + // The Amazon Resource Name (ARN) of the Amazon Web Services Secrets Manager + // secret that identifies the credentials to authenticate to the upstream registry. + CredentialArn *string + + // Amazon Resource Name (ARN) of the IAM role to be assumed by Amazon ECR to + // authenticate to the ECR upstream registry. This role must be in the same account + // as the registry that you are configuring. + CustomRoleArn *string + // The Amazon Web Services account ID associated with the registry associated with // the pull through cache rule. If you do not specify a registry, the default // registry is assumed. @@ -54,6 +57,9 @@ type UpdatePullThroughCacheRuleOutput struct { // secret associated with the pull through cache rule. CredentialArn *string + // The ARN of the IAM role associated with the pull through cache rule. + CustomRoleArn *string + // The Amazon ECR repository prefix associated with the pull through cache rule. EcrRepositoryPrefix *string @@ -64,6 +70,9 @@ type UpdatePullThroughCacheRuleOutput struct { // was updated. UpdatedAt *time.Time + // The upstream repository prefix associated with the pull through cache rule. + UpstreamRepositoryPrefix *string + // Metadata pertaining to the operation's result. ResultMetadata middleware.Metadata @@ -134,6 +143,9 @@ func (c *Client) addOperationUpdatePullThroughCacheRuleMiddlewares(stack *middle if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpUpdatePullThroughCacheRuleValidationMiddleware(stack); err != nil { return err } @@ -155,6 +167,36 @@ func (c *Client) addOperationUpdatePullThroughCacheRuleMiddlewares(stack *middle if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UpdateRepositoryCreationTemplate.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UpdateRepositoryCreationTemplate.go index 1371216054..52e02ad3d6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UpdateRepositoryCreationTemplate.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UpdateRepositoryCreationTemplate.go @@ -65,6 +65,10 @@ type UpdateRepositoryCreationTemplateInput struct { // repository will be immutable which will prevent them from being overwritten. ImageTagMutability types.ImageTagMutability + // Updates a repository with filters that define which image tags can override the + // default image tag mutability setting. + ImageTagMutabilityExclusionFilters []types.ImageTagMutabilityExclusionFilter + // Updates the lifecycle policy associated with the specified repository creation // template. LifecyclePolicy *string @@ -161,6 +165,9 @@ func (c *Client) addOperationUpdateRepositoryCreationTemplateMiddlewares(stack * if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpUpdateRepositoryCreationTemplateValidationMiddleware(stack); err != nil { return err } @@ -182,6 +189,36 @@ func (c *Client) addOperationUpdateRepositoryCreationTemplateMiddlewares(stack * if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UploadLayerPart.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UploadLayerPart.go index acfbd50e25..a75e740e9d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UploadLayerPart.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UploadLayerPart.go @@ -154,6 +154,9 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpUploadLayerPartValidationMiddleware(stack); err != nil { return err } @@ -175,6 +178,36 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ValidatePullThroughCacheRule.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ValidatePullThroughCacheRule.go index 34eeb8959c..607c42be70 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ValidatePullThroughCacheRule.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ValidatePullThroughCacheRule.go @@ -49,6 +49,9 @@ type ValidatePullThroughCacheRuleOutput struct { // secret associated with the pull through cache rule. CredentialArn *string + // The ARN of the IAM role associated with the pull through cache rule. + CustomRoleArn *string + // The Amazon ECR repository prefix associated with the pull through cache rule. EcrRepositoryPrefix *string @@ -70,6 +73,9 @@ type ValidatePullThroughCacheRuleOutput struct { // The upstream registry URL associated with the pull through cache rule. UpstreamRegistryUrl *string + // The upstream repository prefix associated with the pull through cache rule. + UpstreamRepositoryPrefix *string + // Metadata pertaining to the operation's result. ResultMetadata middleware.Metadata @@ -140,6 +146,9 @@ func (c *Client) addOperationValidatePullThroughCacheRuleMiddlewares(stack *midd if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpValidatePullThroughCacheRuleValidationMiddleware(stack); err != nil { return err } @@ -161,6 +170,36 @@ func (c *Client) addOperationValidatePullThroughCacheRuleMiddlewares(stack *midd if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/auth.go index a542aa8f1a..3cb6f139b8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/auth.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/auth.go @@ -12,6 +12,8 @@ import ( "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/tracing" smithyhttp "github.com/aws/smithy-go/transport/http" + "slices" + "strings" ) func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) { @@ -169,7 +171,8 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid } func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { - for _, option := range options { + sorted := sortAuthOptions(options, m.options.AuthSchemePreference) + for _, option := range sorted { if option.SchemeID == smithyauth.SchemeIDAnonymous { return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true } @@ -188,6 +191,29 @@ func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) return nil, false } +func sortAuthOptions(options []*smithyauth.Option, preferred []string) []*smithyauth.Option { + byPriority := make([]*smithyauth.Option, 0, len(options)) + for _, prefName := range preferred { + for _, option := range options { + optName := option.SchemeID + if parts := strings.Split(option.SchemeID, "#"); len(parts) == 2 { + optName = parts[1] + } + if prefName == optName { + byPriority = append(byPriority, option) + } + } + } + for _, option := range options { + if !slices.ContainsFunc(byPriority, func(o *smithyauth.Option) bool { + return o.SchemeID == option.SchemeID + }) { + byPriority = append(byPriority, option) + } + } + return byPriority +} + type resolvedAuthSchemeKey struct{} type resolvedAuthScheme struct { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/deserializers.go index ac5093fcdb..26353b7b7b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/deserializers.go @@ -19,17 +19,8 @@ import ( "io" "math" "strings" - "time" ) -func deserializeS3Expires(v string) (*time.Time, error) { - t, err := smithytime.ParseHTTPDate(v) - if err != nil { - return nil, nil - } - return &t, nil -} - type awsAwsjson11_deserializeOpBatchCheckLayerAvailability struct { } @@ -7627,6 +7618,35 @@ func awsAwsjson11_deserializeDocumentAwsEcrContainerImageDetails(v **types.AwsEc return err } + case "inUseCount": + if value != nil { + jtv, ok := value.(json.Number) + if !ok { + return fmt.Errorf("expected InUseCount to be json.Number, got %T instead", value) + } + i64, err := jtv.Int64() + if err != nil { + return err + } + sv.InUseCount = ptr.Int64(i64) + } + + case "lastInUseAt": + if value != nil { + switch jtv := value.(type) { + case json.Number: + f64, err := jtv.Float64() + if err != nil { + return err + } + sv.LastInUseAt = ptr.Time(smithytime.ParseEpochSeconds(f64)) + + default: + return fmt.Errorf("expected Date to be a JSON Number, got %T instead", value) + + } + } + case "platform": if value != nil { jtv, ok := value.(string) @@ -9496,6 +9516,89 @@ func awsAwsjson11_deserializeDocumentImageTagList(v *[]string, value interface{} return nil } +func awsAwsjson11_deserializeDocumentImageTagMutabilityExclusionFilter(v **types.ImageTagMutabilityExclusionFilter, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.ImageTagMutabilityExclusionFilter + if *v == nil { + sv = &types.ImageTagMutabilityExclusionFilter{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "filter": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected ImageTagMutabilityExclusionFilterValue to be of type string, got %T instead", value) + } + sv.Filter = ptr.String(jtv) + } + + case "filterType": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected ImageTagMutabilityExclusionFilterType to be of type string, got %T instead", value) + } + sv.FilterType = types.ImageTagMutabilityExclusionFilterType(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson11_deserializeDocumentImageTagMutabilityExclusionFilters(v *[]types.ImageTagMutabilityExclusionFilter, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.([]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var cv []types.ImageTagMutabilityExclusionFilter + if *v == nil { + cv = []types.ImageTagMutabilityExclusionFilter{} + } else { + cv = *v + } + + for _, value := range shape { + var col types.ImageTagMutabilityExclusionFilter + destAddr := &col + if err := awsAwsjson11_deserializeDocumentImageTagMutabilityExclusionFilter(&destAddr, value); err != nil { + return err + } + col = *destAddr + cv = append(cv, col) + + } + *v = cv + return nil +} + func awsAwsjson11_deserializeDocumentImageTagsList(v *[]string, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -10661,6 +10764,15 @@ func awsAwsjson11_deserializeDocumentPullThroughCacheRule(v **types.PullThroughC sv.CredentialArn = ptr.String(jtv) } + case "customRoleArn": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected CustomRoleArn to be of type string, got %T instead", value) + } + sv.CustomRoleArn = ptr.String(jtv) + } + case "ecrRepositoryPrefix": if value != nil { jtv, ok := value.(string) @@ -10713,6 +10825,15 @@ func awsAwsjson11_deserializeDocumentPullThroughCacheRule(v **types.PullThroughC sv.UpstreamRegistryUrl = ptr.String(jtv) } + case "upstreamRepositoryPrefix": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected PullThroughCacheRuleRepositoryPrefix to be of type string, got %T instead", value) + } + sv.UpstreamRepositoryPrefix = ptr.String(jtv) + } + default: _, _ = key, value @@ -11484,6 +11605,11 @@ func awsAwsjson11_deserializeDocumentRepository(v **types.Repository, value inte sv.ImageTagMutability = types.ImageTagMutability(jtv) } + case "imageTagMutabilityExclusionFilters": + if err := awsAwsjson11_deserializeDocumentImageTagMutabilityExclusionFilters(&sv.ImageTagMutabilityExclusionFilters, value); err != nil { + return err + } + case "registryId": if value != nil { jtv, ok := value.(string) @@ -11644,6 +11770,11 @@ func awsAwsjson11_deserializeDocumentRepositoryCreationTemplate(v **types.Reposi sv.ImageTagMutability = types.ImageTagMutability(jtv) } + case "imageTagMutabilityExclusionFilters": + if err := awsAwsjson11_deserializeDocumentImageTagMutabilityExclusionFilters(&sv.ImageTagMutabilityExclusionFilters, value); err != nil { + return err + } + case "lifecyclePolicy": if value != nil { jtv, ok := value.(string) @@ -13525,6 +13656,15 @@ func awsAwsjson11_deserializeOpDocumentCreatePullThroughCacheRuleOutput(v **Crea sv.CredentialArn = ptr.String(jtv) } + case "customRoleArn": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected CustomRoleArn to be of type string, got %T instead", value) + } + sv.CustomRoleArn = ptr.String(jtv) + } + case "ecrRepositoryPrefix": if value != nil { jtv, ok := value.(string) @@ -13561,6 +13701,15 @@ func awsAwsjson11_deserializeOpDocumentCreatePullThroughCacheRuleOutput(v **Crea sv.UpstreamRegistryUrl = ptr.String(jtv) } + case "upstreamRepositoryPrefix": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected PullThroughCacheRuleRepositoryPrefix to be of type string, got %T instead", value) + } + sv.UpstreamRepositoryPrefix = ptr.String(jtv) + } + default: _, _ = key, value @@ -13772,6 +13921,15 @@ func awsAwsjson11_deserializeOpDocumentDeletePullThroughCacheRuleOutput(v **Dele sv.CredentialArn = ptr.String(jtv) } + case "customRoleArn": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected CustomRoleArn to be of type string, got %T instead", value) + } + sv.CustomRoleArn = ptr.String(jtv) + } + case "ecrRepositoryPrefix": if value != nil { jtv, ok := value.(string) @@ -13799,6 +13957,15 @@ func awsAwsjson11_deserializeOpDocumentDeletePullThroughCacheRuleOutput(v **Dele sv.UpstreamRegistryUrl = ptr.String(jtv) } + case "upstreamRepositoryPrefix": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected PullThroughCacheRuleRepositoryPrefix to be of type string, got %T instead", value) + } + sv.UpstreamRepositoryPrefix = ptr.String(jtv) + } + default: _, _ = key, value @@ -15103,6 +15270,11 @@ func awsAwsjson11_deserializeOpDocumentPutImageTagMutabilityOutput(v **PutImageT sv.ImageTagMutability = types.ImageTagMutability(jtv) } + case "imageTagMutabilityExclusionFilters": + if err := awsAwsjson11_deserializeDocumentImageTagMutabilityExclusionFilters(&sv.ImageTagMutabilityExclusionFilters, value); err != nil { + return err + } + case "registryId": if value != nil { jtv, ok := value.(string) @@ -15586,6 +15758,15 @@ func awsAwsjson11_deserializeOpDocumentUpdatePullThroughCacheRuleOutput(v **Upda sv.CredentialArn = ptr.String(jtv) } + case "customRoleArn": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected CustomRoleArn to be of type string, got %T instead", value) + } + sv.CustomRoleArn = ptr.String(jtv) + } + case "ecrRepositoryPrefix": if value != nil { jtv, ok := value.(string) @@ -15620,6 +15801,15 @@ func awsAwsjson11_deserializeOpDocumentUpdatePullThroughCacheRuleOutput(v **Upda } } + case "upstreamRepositoryPrefix": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected PullThroughCacheRuleRepositoryPrefix to be of type string, got %T instead", value) + } + sv.UpstreamRepositoryPrefix = ptr.String(jtv) + } + default: _, _ = key, value @@ -15776,6 +15966,15 @@ func awsAwsjson11_deserializeOpDocumentValidatePullThroughCacheRuleOutput(v **Va sv.CredentialArn = ptr.String(jtv) } + case "customRoleArn": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected CustomRoleArn to be of type string, got %T instead", value) + } + sv.CustomRoleArn = ptr.String(jtv) + } + case "ecrRepositoryPrefix": if value != nil { jtv, ok := value.(string) @@ -15821,6 +16020,15 @@ func awsAwsjson11_deserializeOpDocumentValidatePullThroughCacheRuleOutput(v **Va sv.UpstreamRegistryUrl = ptr.String(jtv) } + case "upstreamRepositoryPrefix": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected PullThroughCacheRuleRepositoryPrefix to be of type string, got %T instead", value) + } + sv.UpstreamRepositoryPrefix = ptr.String(jtv) + } + default: _, _ = key, value diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/endpoints.go index c593447cd6..a31be84672 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/endpoints.go @@ -328,7 +328,9 @@ func (r *resolver) ResolveEndpoint( return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err) } _UseDualStack := *params.UseDualStack + _ = _UseDualStack _UseFIPS := *params.UseFIPS + _ = _UseFIPS if exprVal := params.Endpoint; exprVal != nil { _Endpoint := *exprVal @@ -361,6 +363,44 @@ func (r *resolver) ResolveEndpoint( if _UseDualStack == true { if true == _PartitionResult.SupportsFIPS { if true == _PartitionResult.SupportsDualStack { + if "aws" == _PartitionResult.Name { + uriString := func() string { + var out strings.Builder + out.WriteString("https://ecr-fips.") + out.WriteString(_Region) + out.WriteString(".api.aws") + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + if "aws-us-gov" == _PartitionResult.Name { + uriString := func() string { + var out strings.Builder + out.WriteString("https://ecr-fips.") + out.WriteString(_Region) + out.WriteString(".api.aws") + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } uriString := func() string { var out strings.Builder out.WriteString("https://api.ecr-fips.") @@ -447,6 +487,63 @@ func (r *resolver) ResolveEndpoint( } if _UseDualStack == true { if true == _PartitionResult.SupportsDualStack { + if "aws" == _PartitionResult.Name { + uriString := func() string { + var out strings.Builder + out.WriteString("https://ecr.") + out.WriteString(_Region) + out.WriteString(".api.aws") + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + if "aws-cn" == _PartitionResult.Name { + uriString := func() string { + var out strings.Builder + out.WriteString("https://ecr.") + out.WriteString(_Region) + out.WriteString(".api.amazonwebservices.com.cn") + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + if "aws-us-gov" == _PartitionResult.Name { + uriString := func() string { + var out strings.Builder + out.WriteString("https://ecr.") + out.WriteString(_Region) + out.WriteString(".api.aws") + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } uriString := func() string { var out strings.Builder out.WriteString("https://api.ecr.") diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/generated.json index ed8ecd06af..1fbf8a87dd 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/generated.json @@ -70,12 +70,13 @@ "protocol_test.go", "serializers.go", "snapshot_test.go", + "sra_operation_order_test.go", "types/enums.go", "types/errors.go", "types/types.go", "validators.go" ], - "go": "1.15", + "go": "1.23", "module": "github.com/aws/aws-sdk-go-v2/service/ecr", "unstable": false } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/go_module_metadata.go index 0adcf28e30..23e5772ebf 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/go_module_metadata.go @@ -3,4 +3,4 @@ package ecr // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.40.3" +const goModuleVersion = "1.51.2" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints/endpoints.go index ebf04b8807..9e1519b619 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints/endpoints.go @@ -87,6 +87,7 @@ func New() *Resolver { var partitionRegexp = struct { Aws *regexp.Regexp AwsCn *regexp.Regexp + AwsEusc *regexp.Regexp AwsIso *regexp.Regexp AwsIsoB *regexp.Regexp AwsIsoE *regexp.Regexp @@ -96,6 +97,7 @@ var partitionRegexp = struct { Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$"), AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"), + AwsEusc: regexp.MustCompile("^eusc\\-(de)\\-\\w+\\-\\d+$"), AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"), AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"), AwsIsoE: regexp.MustCompile("^eu\\-isoe\\-\\w+\\-\\d+$"), @@ -173,6 +175,9 @@ var defaultPartitions = endpoints.Partitions{ Region: "ap-east-1", }, }, + endpoints.EndpointKey{ + Region: "ap-east-2", + }: endpoints.Endpoint{}, endpoints.EndpointKey{ Region: "ap-northeast-1", }: endpoints.Endpoint{ @@ -343,6 +348,9 @@ var defaultPartitions = endpoints.Partitions{ Region: "ap-southeast-5", }, }, + endpoints.EndpointKey{ + Region: "ap-southeast-6", + }: endpoints.Endpoint{}, endpoints.EndpointKey{ Region: "ap-southeast-7", }: endpoints.Endpoint{ @@ -972,6 +980,27 @@ var defaultPartitions = endpoints.Partitions{ }, }, }, + { + ID: "aws-eusc", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "api.ecr-fips.{region}.amazonaws.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "api.ecr.{region}.amazonaws.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + RegionRegex: partitionRegexp.AwsEusc, + IsRegionalized: true, + }, { ID: "aws-iso", Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ @@ -1040,6 +1069,9 @@ var defaultPartitions = endpoints.Partitions{ Region: "us-isob-east-1", }, }, + endpoints.EndpointKey{ + Region: "us-isob-west-1", + }: endpoints.Endpoint{}, }, }, { @@ -1062,6 +1094,16 @@ var defaultPartitions = endpoints.Partitions{ }, RegionRegex: partitionRegexp.AwsIsoE, IsRegionalized: true, + Endpoints: endpoints.Endpoints{ + endpoints.EndpointKey{ + Region: "eu-isoe-west-1", + }: endpoints.Endpoint{ + Hostname: "api.ecr.eu-isoe-west-1.cloud.adc-e.uk", + CredentialScope: endpoints.CredentialScope{ + Region: "eu-isoe-west-1", + }, + }, + }, }, { ID: "aws-iso-f", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/options.go index 8d993c73e2..a29926131a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/options.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/options.go @@ -119,12 +119,18 @@ type Options struct { // implementation if nil. HTTPClient HTTPClient + // Client registry of operation interceptors. + Interceptors smithyhttp.InterceptorRegistry + // The auth scheme resolver which determines how to authenticate for each // operation. AuthSchemeResolver AuthSchemeResolver // The list of auth schemes supported by the client. AuthSchemes []smithyhttp.AuthScheme + + // Priority list of preferred auth scheme names (e.g. sigv4a). + AuthSchemePreference []string } // Copy creates a clone where the APIOptions list is deep copied. @@ -132,6 +138,7 @@ func (o Options) Copy() Options { to := o to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) copy(to.APIOptions, o.APIOptions) + to.Interceptors = o.Interceptors.Copy() return to } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/serializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/serializers.go index db1b0d7a16..328b461922 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/serializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/serializers.go @@ -3114,6 +3114,36 @@ func awsAwsjson11_serializeDocumentImageScanningConfiguration(v *types.ImageScan return nil } +func awsAwsjson11_serializeDocumentImageTagMutabilityExclusionFilter(v *types.ImageTagMutabilityExclusionFilter, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.Filter != nil { + ok := object.Key("filter") + ok.String(*v.Filter) + } + + if len(v.FilterType) > 0 { + ok := object.Key("filterType") + ok.String(string(v.FilterType)) + } + + return nil +} + +func awsAwsjson11_serializeDocumentImageTagMutabilityExclusionFilters(v []types.ImageTagMutabilityExclusionFilter, value smithyjson.Value) error { + array := value.Array() + defer array.Close() + + for i := range v { + av := array.Value() + if err := awsAwsjson11_serializeDocumentImageTagMutabilityExclusionFilter(&v[i], av); err != nil { + return err + } + } + return nil +} + func awsAwsjson11_serializeDocumentLayerDigestList(v []string, value smithyjson.Value) error { array := value.Array() defer array.Close() @@ -3557,6 +3587,11 @@ func awsAwsjson11_serializeOpDocumentCreatePullThroughCacheRuleInput(v *CreatePu ok.String(*v.CredentialArn) } + if v.CustomRoleArn != nil { + ok := object.Key("customRoleArn") + ok.String(*v.CustomRoleArn) + } + if v.EcrRepositoryPrefix != nil { ok := object.Key("ecrRepositoryPrefix") ok.String(*v.EcrRepositoryPrefix) @@ -3577,6 +3612,11 @@ func awsAwsjson11_serializeOpDocumentCreatePullThroughCacheRuleInput(v *CreatePu ok.String(*v.UpstreamRegistryUrl) } + if v.UpstreamRepositoryPrefix != nil { + ok := object.Key("upstreamRepositoryPrefix") + ok.String(*v.UpstreamRepositoryPrefix) + } + return nil } @@ -3613,6 +3653,13 @@ func awsAwsjson11_serializeOpDocumentCreateRepositoryCreationTemplateInput(v *Cr ok.String(string(v.ImageTagMutability)) } + if v.ImageTagMutabilityExclusionFilters != nil { + ok := object.Key("imageTagMutabilityExclusionFilters") + if err := awsAwsjson11_serializeDocumentImageTagMutabilityExclusionFilters(v.ImageTagMutabilityExclusionFilters, ok); err != nil { + return err + } + } + if v.LifecyclePolicy != nil { ok := object.Key("lifecyclePolicy") ok.String(*v.LifecyclePolicy) @@ -3661,6 +3708,13 @@ func awsAwsjson11_serializeOpDocumentCreateRepositoryInput(v *CreateRepositoryIn ok.String(string(v.ImageTagMutability)) } + if v.ImageTagMutabilityExclusionFilters != nil { + ok := object.Key("imageTagMutabilityExclusionFilters") + if err := awsAwsjson11_serializeDocumentImageTagMutabilityExclusionFilters(v.ImageTagMutabilityExclusionFilters, ok); err != nil { + return err + } + } + if v.RegistryId != nil { ok := object.Key("registryId") ok.String(*v.RegistryId) @@ -4248,6 +4302,13 @@ func awsAwsjson11_serializeOpDocumentPutImageTagMutabilityInput(v *PutImageTagMu ok.String(string(v.ImageTagMutability)) } + if v.ImageTagMutabilityExclusionFilters != nil { + ok := object.Key("imageTagMutabilityExclusionFilters") + if err := awsAwsjson11_serializeDocumentImageTagMutabilityExclusionFilters(v.ImageTagMutabilityExclusionFilters, ok); err != nil { + return err + } + } + if v.RegistryId != nil { ok := object.Key("registryId") ok.String(*v.RegistryId) @@ -4448,6 +4509,11 @@ func awsAwsjson11_serializeOpDocumentUpdatePullThroughCacheRuleInput(v *UpdatePu ok.String(*v.CredentialArn) } + if v.CustomRoleArn != nil { + ok := object.Key("customRoleArn") + ok.String(*v.CustomRoleArn) + } + if v.EcrRepositoryPrefix != nil { ok := object.Key("ecrRepositoryPrefix") ok.String(*v.EcrRepositoryPrefix) @@ -4494,6 +4560,13 @@ func awsAwsjson11_serializeOpDocumentUpdateRepositoryCreationTemplateInput(v *Up ok.String(string(v.ImageTagMutability)) } + if v.ImageTagMutabilityExclusionFilters != nil { + ok := object.Key("imageTagMutabilityExclusionFilters") + if err := awsAwsjson11_serializeDocumentImageTagMutabilityExclusionFilters(v.ImageTagMutabilityExclusionFilters, ok); err != nil { + return err + } + } + if v.LifecyclePolicy != nil { ok := object.Key("lifecyclePolicy") ok.String(*v.LifecyclePolicy) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go index 52470b4ebe..4d7b6cc588 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go @@ -106,8 +106,10 @@ type ImageTagMutability string // Enum values for ImageTagMutability const ( - ImageTagMutabilityMutable ImageTagMutability = "MUTABLE" - ImageTagMutabilityImmutable ImageTagMutability = "IMMUTABLE" + ImageTagMutabilityMutable ImageTagMutability = "MUTABLE" + ImageTagMutabilityImmutable ImageTagMutability = "IMMUTABLE" + ImageTagMutabilityImmutableWithExclusion ImageTagMutability = "IMMUTABLE_WITH_EXCLUSION" + ImageTagMutabilityMutableWithExclusion ImageTagMutability = "MUTABLE_WITH_EXCLUSION" ) // Values returns all known values for ImageTagMutability. Note that this can be @@ -118,6 +120,26 @@ func (ImageTagMutability) Values() []ImageTagMutability { return []ImageTagMutability{ "MUTABLE", "IMMUTABLE", + "IMMUTABLE_WITH_EXCLUSION", + "MUTABLE_WITH_EXCLUSION", + } +} + +type ImageTagMutabilityExclusionFilterType string + +// Enum values for ImageTagMutabilityExclusionFilterType +const ( + ImageTagMutabilityExclusionFilterTypeWildcard ImageTagMutabilityExclusionFilterType = "WILDCARD" +) + +// Values returns all known values for ImageTagMutabilityExclusionFilterType. Note +// that this can be expanded in the future, and so it is only as up to date as the +// client. +// +// The ordering of this slice is not guaranteed to be stable across updates. +func (ImageTagMutabilityExclusionFilterType) Values() []ImageTagMutabilityExclusionFilterType { + return []ImageTagMutabilityExclusionFilterType{ + "WILDCARD", } } @@ -309,6 +331,7 @@ const ( ScanStatusPending ScanStatus = "PENDING" ScanStatusScanEligibilityExpired ScanStatus = "SCAN_ELIGIBILITY_EXPIRED" ScanStatusFindingsUnavailable ScanStatus = "FINDINGS_UNAVAILABLE" + ScanStatusLimitExceeded ScanStatus = "LIMIT_EXCEEDED" ) // Values returns all known values for ScanStatus. Note that this can be expanded @@ -325,6 +348,7 @@ func (ScanStatus) Values() []ScanStatus { "PENDING", "SCAN_ELIGIBILITY_EXPIRED", "FINDINGS_UNAVAILABLE", + "LIMIT_EXCEEDED", } } @@ -372,6 +396,7 @@ type UpstreamRegistry string // Enum values for UpstreamRegistry const ( + UpstreamRegistryEcr UpstreamRegistry = "ecr" UpstreamRegistryEcrPublic UpstreamRegistry = "ecr-public" UpstreamRegistryQuay UpstreamRegistry = "quay" UpstreamRegistryK8s UpstreamRegistry = "k8s" @@ -387,6 +412,7 @@ const ( // The ordering of this slice is not guaranteed to be stable across updates. func (UpstreamRegistry) Values() []UpstreamRegistry { return []UpstreamRegistry{ + "ecr", "ecr-public", "quay", "k8s", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go index 7bab166264..699b73fd87 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go @@ -57,6 +57,12 @@ type AwsEcrContainerImageDetails struct { // The image tags attached to the Amazon ECR container image. ImageTags []string + // The number of Amazon ECS or Amazon EKS clusters currently running the image. + InUseCount *int64 + + // The most recent date and time a cluster was running the image. + LastInUseAt *time.Time + // The platform of the Amazon ECR container image. Platform *string @@ -326,10 +332,10 @@ type ImageDetail struct { // If the image is a manifest list, this will be the max size of all manifests in // the list. // - // Beginning with Docker version 1.9, the Docker client compresses image layers + // Starting with Docker version 1.9, the Docker client compresses image layers // before pushing them to a V2 Docker registry. The output of the docker images - // command shows the uncompressed image size, so it may return a larger image size - // than the image sizes returned by DescribeImages. + // command shows the uncompressed image size. Therefore, Docker might return a + // larger image than the image shown in the Amazon Web Services Management Console. ImageSizeInBytes *int64 // The list of tags associated with this image. @@ -485,6 +491,25 @@ type ImageScanStatus struct { noSmithyDocumentSerde } +// Overrides the default image tag mutability setting of the repository for image +// tags that match the specified filters. +type ImageTagMutabilityExclusionFilter struct { + + // The value to use when filtering image tags. Must be either a regular expression + // pattern or a tag prefix value based on the specified filter type. + // + // This member is required. + Filter *string + + // Specifies the type of filter to use for excluding image tags from the + // repository's mutability setting. + // + // This member is required. + FilterType ImageTagMutabilityExclusionFilterType + + noSmithyDocumentSerde +} + // An object representing an Amazon ECR image layer. type Layer struct { @@ -626,6 +651,9 @@ type PullThroughCacheRule struct { // rule. CredentialArn *string + // The ARN of the IAM role associated with the pull through cache rule. + CustomRoleArn *string + // The Amazon ECR repository prefix associated with the pull through cache rule. EcrRepositoryPrefix *string @@ -644,6 +672,9 @@ type PullThroughCacheRule struct { // The upstream registry URL associated with the pull through cache rule. UpstreamRegistryUrl *string + // The upstream repository prefix associated with the pull through cache rule. + UpstreamRepositoryPrefix *string + noSmithyDocumentSerde } @@ -765,6 +796,11 @@ type Repository struct { // The tag mutability setting for the repository. ImageTagMutability ImageTagMutability + // The image tag mutability exclusion filters associated with the repository. + // These filters specify which image tags can override the repository's default + // image tag mutability setting. + ImageTagMutabilityExclusionFilters []ImageTagMutabilityExclusionFilter + // The Amazon Web Services account ID associated with the registry that contains // the repository. RegistryId *string @@ -816,6 +852,11 @@ type RepositoryCreationTemplate struct { // will be immutable which will prevent them from being overwritten. ImageTagMutability ImageTagMutability + // Defines the image tag mutability exclusion filters to apply when creating + // repositories from this template. These filters specify which image tags can + // override the repository's default image tag mutability setting. + ImageTagMutabilityExclusionFilters []ImageTagMutabilityExclusionFilter + // The lifecycle policy to use for repositories created using the template. LifecyclePolicy *string @@ -823,7 +864,7 @@ type RepositoryCreationTemplate struct { // template. Prefix *string - // he repository policy to apply to repositories created using the template. A + // The repository policy to apply to repositories created using the template. A // repository policy is a permissions policy associated with a repository to // control access permissions. RepositoryPolicy *string diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/validators.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/validators.go index 930a3ccd83..c3ae2dcd55 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/validators.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/validators.go @@ -1024,6 +1024,41 @@ func validateEncryptionConfigurationForRepositoryCreationTemplate(v *types.Encry } } +func validateImageTagMutabilityExclusionFilter(v *types.ImageTagMutabilityExclusionFilter) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "ImageTagMutabilityExclusionFilter"} + if len(v.FilterType) == 0 { + invalidParams.Add(smithy.NewErrParamRequired("FilterType")) + } + if v.Filter == nil { + invalidParams.Add(smithy.NewErrParamRequired("Filter")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + +func validateImageTagMutabilityExclusionFilters(v []types.ImageTagMutabilityExclusionFilter) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "ImageTagMutabilityExclusionFilters"} + for i := range v { + if err := validateImageTagMutabilityExclusionFilter(&v[i]); err != nil { + invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) + } + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + func validateRegistryScanningRule(v *types.RegistryScanningRule) error { if v == nil { return nil @@ -1389,6 +1424,11 @@ func validateOpCreateRepositoryCreationTemplateInput(v *CreateRepositoryCreation invalidParams.AddNested("ResourceTags", err.(smithy.InvalidParamsError)) } } + if v.ImageTagMutabilityExclusionFilters != nil { + if err := validateImageTagMutabilityExclusionFilters(v.ImageTagMutabilityExclusionFilters); err != nil { + invalidParams.AddNested("ImageTagMutabilityExclusionFilters", err.(smithy.InvalidParamsError)) + } + } if v.AppliedFor == nil { invalidParams.Add(smithy.NewErrParamRequired("AppliedFor")) } @@ -1412,6 +1452,11 @@ func validateOpCreateRepositoryInput(v *CreateRepositoryInput) error { invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) } } + if v.ImageTagMutabilityExclusionFilters != nil { + if err := validateImageTagMutabilityExclusionFilters(v.ImageTagMutabilityExclusionFilters); err != nil { + invalidParams.AddNested("ImageTagMutabilityExclusionFilters", err.(smithy.InvalidParamsError)) + } + } if v.EncryptionConfiguration != nil { if err := validateEncryptionConfiguration(v.EncryptionConfiguration); err != nil { invalidParams.AddNested("EncryptionConfiguration", err.(smithy.InvalidParamsError)) @@ -1738,6 +1783,11 @@ func validateOpPutImageTagMutabilityInput(v *PutImageTagMutabilityInput) error { if len(v.ImageTagMutability) == 0 { invalidParams.Add(smithy.NewErrParamRequired("ImageTagMutability")) } + if v.ImageTagMutabilityExclusionFilters != nil { + if err := validateImageTagMutabilityExclusionFilters(v.ImageTagMutabilityExclusionFilters); err != nil { + invalidParams.AddNested("ImageTagMutabilityExclusionFilters", err.(smithy.InvalidParamsError)) + } + } if invalidParams.Len() > 0 { return invalidParams } else { @@ -1913,9 +1963,6 @@ func validateOpUpdatePullThroughCacheRuleInput(v *UpdatePullThroughCacheRuleInpu if v.EcrRepositoryPrefix == nil { invalidParams.Add(smithy.NewErrParamRequired("EcrRepositoryPrefix")) } - if v.CredentialArn == nil { - invalidParams.Add(smithy.NewErrParamRequired("CredentialArn")) - } if invalidParams.Len() > 0 { return invalidParams } else { @@ -1941,6 +1988,11 @@ func validateOpUpdateRepositoryCreationTemplateInput(v *UpdateRepositoryCreation invalidParams.AddNested("ResourceTags", err.(smithy.InvalidParamsError)) } } + if v.ImageTagMutabilityExclusionFilters != nil { + if err := validateImageTagMutabilityExclusionFilters(v.ImageTagMutabilityExclusionFilters); err != nil { + invalidParams.AddNested("ImageTagMutabilityExclusionFilters", err.(smithy.InvalidParamsError)) + } + } if invalidParams.Len() > 0 { return invalidParams } else { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/CHANGELOG.md index 4b60c6b16d..fc4ce6fefb 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/CHANGELOG.md @@ -1,3 +1,110 @@ +# v1.38.2 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.38.1 (2025-10-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.0 (2025-10-23) + +* **Feature**: Update endpoint ruleset parameters casing +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.37.7 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.37.6 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.37.5 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.37.4 (2025-09-10) + +* No change notes available for this release. + +# v1.37.3 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.37.2 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.37.1 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.37.0 (2025-08-21) + +* **Feature**: Remove incorrect endpoint tests +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.36.1 (2025-08-20) + +* **Bug Fix**: Remove unused deserialization code. + +# v1.36.0 (2025-08-11) + +* **Feature**: Add support for configuring per-service Options via callback on global config. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.35.0 (2025-08-04) + +* **Feature**: Support configurable auth scheme preferences in service clients via AWS_AUTH_SCHEME_PREFERENCE in the environment, auth_scheme_preference in the config file, and through in-code settings on LoadDefaultConfig and client constructor methods. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.34.1 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.34.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.3 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.2 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.1 (2025-06-10) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.0 (2025-04-30) + +* **Feature**: Adds dualstack support for Amazon Elastic Container Registry Public (Amazon ECR Public). + +# v1.32.2 (2025-04-03) + +* No change notes available for this release. + +# v1.32.1 (2025-03-04.2) + +* **Bug Fix**: Add assurance test for operation order. + +# v1.32.0 (2025-02-27) + +* **Feature**: Track credential providers via User-Agent Feature ids +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.3 (2025-02-18) + +* **Bug Fix**: Bump go version to 1.22 +* **Dependency Update**: Updated to the latest SDK module versions + # v1.31.2 (2025-02-05) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_client.go index 6ec6c3ec1c..c16587275b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_client.go @@ -420,24 +420,33 @@ func setResolvedDefaultsMode(o *Options) { // NewFromConfig returns a new client from the provided config. func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, + Region: cfg.Region, + DefaultsMode: cfg.DefaultsMode, + RuntimeEnvironment: cfg.RuntimeEnvironment, + HTTPClient: cfg.HTTPClient, + Credentials: cfg.Credentials, + APIOptions: cfg.APIOptions, + Logger: cfg.Logger, + ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, + AuthSchemePreference: cfg.AuthSchemePreference, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) resolveAWSRetryMode(cfg, &opts) resolveAWSEndpointResolver(cfg, &opts) + resolveInterceptors(cfg, &opts) resolveUseDualStackEndpoint(cfg, &opts) resolveUseFIPSEndpoint(cfg, &opts) resolveBaseEndpoint(cfg, &opts) - return New(opts, optFns...) + return New(opts, func(o *Options) { + for _, opt := range cfg.ServiceOptions { + opt(ServiceID, o) + } + for _, opt := range optFns { + opt(o) + } + }) } func resolveHTTPClient(o *Options) { @@ -551,6 +560,10 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } +func resolveInterceptors(cfg aws.Config, o *Options) { + o.Interceptors = cfg.Interceptors.Copy() +} + func addClientUserAgent(stack *middleware.Stack, options Options) error { ua, err := getOrAddRequestUserAgent(stack) if err != nil { @@ -762,6 +775,37 @@ func addUserAgentRetryMode(stack *middleware.Stack, options Options) error { return nil } +type setCredentialSourceMiddleware struct { + ua *awsmiddleware.RequestUserAgent + options Options +} + +func (m setCredentialSourceMiddleware) ID() string { return "SetCredentialSourceMiddleware" } + +func (m setCredentialSourceMiddleware) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) ( + out middleware.BuildOutput, metadata middleware.Metadata, err error, +) { + asProviderSource, ok := m.options.Credentials.(aws.CredentialProviderSource) + if !ok { + return next.HandleBuild(ctx, in) + } + providerSources := asProviderSource.ProviderSources() + for _, source := range providerSources { + m.ua.AddCredentialsSource(source) + } + return next.HandleBuild(ctx, in) +} + +func addCredentialSource(stack *middleware.Stack, options Options) error { + ua, err := getOrAddRequestUserAgent(stack) + if err != nil { + return err + } + + mw := setCredentialSourceMiddleware{ua: ua, options: options} + return stack.Build.Insert(&mw, "UserAgent", middleware.Before) +} + func resolveTracerProvider(options *Options) { if options.TracerProvider == nil { options.TracerProvider = &tracing.NopTracerProvider{} @@ -826,6 +870,69 @@ func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { }, "ResolveEndpointV2", middleware.After) } +func addInterceptBeforeRetryLoop(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptBeforeRetryLoop{ + Interceptors: opts.Interceptors.BeforeRetryLoop, + }, "Retry", middleware.Before) +} + +func addInterceptAttempt(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptAttempt{ + BeforeAttempt: opts.Interceptors.BeforeAttempt, + AfterAttempt: opts.Interceptors.AfterAttempt, + }, "Retry", middleware.After) +} + +func addInterceptExecution(stack *middleware.Stack, opts Options) error { + return stack.Initialize.Add(&smithyhttp.InterceptExecution{ + BeforeExecution: opts.Interceptors.BeforeExecution, + AfterExecution: opts.Interceptors.AfterExecution, + }, middleware.Before) +} + +func addInterceptBeforeSerialization(stack *middleware.Stack, opts Options) error { + return stack.Serialize.Insert(&smithyhttp.InterceptBeforeSerialization{ + Interceptors: opts.Interceptors.BeforeSerialization, + }, "OperationSerializer", middleware.Before) +} + +func addInterceptAfterSerialization(stack *middleware.Stack, opts Options) error { + return stack.Serialize.Insert(&smithyhttp.InterceptAfterSerialization{ + Interceptors: opts.Interceptors.AfterSerialization, + }, "OperationSerializer", middleware.After) +} + +func addInterceptBeforeSigning(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptBeforeSigning{ + Interceptors: opts.Interceptors.BeforeSigning, + }, "Signing", middleware.Before) +} + +func addInterceptAfterSigning(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptAfterSigning{ + Interceptors: opts.Interceptors.AfterSigning, + }, "Signing", middleware.After) +} + +func addInterceptTransmit(stack *middleware.Stack, opts Options) error { + return stack.Deserialize.Add(&smithyhttp.InterceptTransmit{ + BeforeTransmit: opts.Interceptors.BeforeTransmit, + AfterTransmit: opts.Interceptors.AfterTransmit, + }, middleware.After) +} + +func addInterceptBeforeDeserialization(stack *middleware.Stack, opts Options) error { + return stack.Deserialize.Insert(&smithyhttp.InterceptBeforeDeserialization{ + Interceptors: opts.Interceptors.BeforeDeserialization, + }, "OperationDeserializer", middleware.After) // (deserialize stack is called in reverse) +} + +func addInterceptAfterDeserialization(stack *middleware.Stack, opts Options) error { + return stack.Deserialize.Insert(&smithyhttp.InterceptAfterDeserialization{ + Interceptors: opts.Interceptors.AfterDeserialization, + }, "OperationDeserializer", middleware.Before) +} + type spanInitializeStart struct { } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchCheckLayerAvailability.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchCheckLayerAvailability.go index dc0aeccdcd..7f16bb3029 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchCheckLayerAvailability.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchCheckLayerAvailability.go @@ -133,6 +133,9 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpBatchCheckLayerAvailabilityValidationMiddleware(stack); err != nil { return err } @@ -154,6 +157,36 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchDeleteImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchDeleteImage.go index 01302e7712..7694a6ba6b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchDeleteImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchDeleteImage.go @@ -134,6 +134,9 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpBatchDeleteImageValidationMiddleware(stack); err != nil { return err } @@ -155,6 +158,36 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CompleteLayerUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CompleteLayerUpload.go index 0e5f50ea9e..f73e6b3711 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CompleteLayerUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CompleteLayerUpload.go @@ -145,6 +145,9 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpCompleteLayerUploadValidationMiddleware(stack); err != nil { return err } @@ -166,6 +169,36 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CreateRepository.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CreateRepository.go index 4ca5c18847..53e0ecc202 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CreateRepository.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CreateRepository.go @@ -132,6 +132,9 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpCreateRepositoryValidationMiddleware(stack); err != nil { return err } @@ -153,6 +156,36 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepository.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepository.go index ca7cd7d3fb..e718c4548e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepository.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepository.go @@ -124,6 +124,9 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpDeleteRepositoryValidationMiddleware(stack); err != nil { return err } @@ -145,6 +148,36 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepositoryPolicy.go index 831a8483e4..e11d3a7bf8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepositoryPolicy.go @@ -123,6 +123,9 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpDeleteRepositoryPolicyValidationMiddleware(stack); err != nil { return err } @@ -144,6 +147,36 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImageTags.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImageTags.go index f43b7776f6..513c80ccce 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImageTags.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImageTags.go @@ -140,6 +140,9 @@ func (c *Client) addOperationDescribeImageTagsMiddlewares(stack *middleware.Stac if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpDescribeImageTagsValidationMiddleware(stack); err != nil { return err } @@ -161,6 +164,36 @@ func (c *Client) addOperationDescribeImageTagsMiddlewares(stack *middleware.Stac if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImages.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImages.go index d77c2e2ac0..301988ca2a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImages.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImages.go @@ -149,6 +149,9 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpDescribeImagesValidationMiddleware(stack); err != nil { return err } @@ -170,6 +173,36 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRegistries.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRegistries.go index 47aa6f4076..a6ae39c27c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRegistries.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRegistries.go @@ -135,6 +135,9 @@ func (c *Client) addOperationDescribeRegistriesMiddlewares(stack *middleware.Sta if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeRegistries(options.Region), middleware.Before); err != nil { return err } @@ -153,6 +156,36 @@ func (c *Client) addOperationDescribeRegistriesMiddlewares(stack *middleware.Sta if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRepositories.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRepositories.go index 96642a085b..7e2cd311e6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRepositories.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRepositories.go @@ -144,6 +144,9 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeRepositories(options.Region), middleware.Before); err != nil { return err } @@ -162,6 +165,36 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetAuthorizationToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetAuthorizationToken.go index ced2aec493..9da633f0d3 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetAuthorizationToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetAuthorizationToken.go @@ -110,6 +110,9 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetAuthorizationToken(options.Region), middleware.Before); err != nil { return err } @@ -128,6 +131,36 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRegistryCatalogData.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRegistryCatalogData.go index 3b46f123ec..a5c0846887 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRegistryCatalogData.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRegistryCatalogData.go @@ -108,6 +108,9 @@ func (c *Client) addOperationGetRegistryCatalogDataMiddlewares(stack *middleware if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRegistryCatalogData(options.Region), middleware.Before); err != nil { return err } @@ -126,6 +129,36 @@ func (c *Client) addOperationGetRegistryCatalogDataMiddlewares(stack *middleware if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryCatalogData.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryCatalogData.go index 5f80026f18..72c119e926 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryCatalogData.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryCatalogData.go @@ -118,6 +118,9 @@ func (c *Client) addOperationGetRepositoryCatalogDataMiddlewares(stack *middlewa if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpGetRepositoryCatalogDataValidationMiddleware(stack); err != nil { return err } @@ -139,6 +142,36 @@ func (c *Client) addOperationGetRepositoryCatalogDataMiddlewares(stack *middlewa if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryPolicy.go index ea637e3af4..2c5c102645 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryPolicy.go @@ -123,6 +123,9 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpGetRepositoryPolicyValidationMiddleware(stack); err != nil { return err } @@ -144,6 +147,36 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_InitiateLayerUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_InitiateLayerUpload.go index a8e642aab2..469869e5e9 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_InitiateLayerUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_InitiateLayerUpload.go @@ -128,6 +128,9 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpInitiateLayerUploadValidationMiddleware(stack); err != nil { return err } @@ -149,6 +152,36 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_ListTagsForResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_ListTagsForResource.go index 9624524c06..48a4b704a4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_ListTagsForResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_ListTagsForResource.go @@ -113,6 +113,9 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpListTagsForResourceValidationMiddleware(stack); err != nil { return err } @@ -134,6 +137,36 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutImage.go index 25f8cda005..a67ced52d7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutImage.go @@ -144,6 +144,9 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpPutImageValidationMiddleware(stack); err != nil { return err } @@ -165,6 +168,36 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRegistryCatalogData.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRegistryCatalogData.go index 233fba1575..c448579d41 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRegistryCatalogData.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRegistryCatalogData.go @@ -116,6 +116,9 @@ func (c *Client) addOperationPutRegistryCatalogDataMiddlewares(stack *middleware if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutRegistryCatalogData(options.Region), middleware.Before); err != nil { return err } @@ -134,6 +137,36 @@ func (c *Client) addOperationPutRegistryCatalogDataMiddlewares(stack *middleware if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRepositoryCatalogData.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRepositoryCatalogData.go index 59bf740b22..6d934273f5 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRepositoryCatalogData.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRepositoryCatalogData.go @@ -123,6 +123,9 @@ func (c *Client) addOperationPutRepositoryCatalogDataMiddlewares(stack *middlewa if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpPutRepositoryCatalogDataValidationMiddleware(stack); err != nil { return err } @@ -144,6 +147,36 @@ func (c *Client) addOperationPutRepositoryCatalogDataMiddlewares(stack *middlewa if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_SetRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_SetRepositoryPolicy.go index d49bc941be..b6620a62c2 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_SetRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_SetRepositoryPolicy.go @@ -139,6 +139,9 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpSetRepositoryPolicyValidationMiddleware(stack); err != nil { return err } @@ -160,6 +163,36 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_TagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_TagResource.go index 1dfb2dd784..7f9fa7c5c7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_TagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_TagResource.go @@ -119,6 +119,9 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpTagResourceValidationMiddleware(stack); err != nil { return err } @@ -140,6 +143,36 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UntagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UntagResource.go index 83b57e0ad9..246242640d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UntagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UntagResource.go @@ -113,6 +113,9 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpUntagResourceValidationMiddleware(stack); err != nil { return err } @@ -134,6 +137,36 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UploadLayerPart.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UploadLayerPart.go index 9a81c0597f..6c7124bc83 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UploadLayerPart.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UploadLayerPart.go @@ -154,6 +154,9 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = addUserAgentRetryMode(stack, options); err != nil { return err } + if err = addCredentialSource(stack, options); err != nil { + return err + } if err = addOpUploadLayerPartValidationMiddleware(stack); err != nil { return err } @@ -175,6 +178,36 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptExecution(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSerialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterSerialization(stack, options); err != nil { + return err + } + if err = addInterceptBeforeSigning(stack, options); err != nil { + return err + } + if err = addInterceptAfterSigning(stack, options); err != nil { + return err + } + if err = addInterceptTransmit(stack, options); err != nil { + return err + } + if err = addInterceptBeforeDeserialization(stack, options); err != nil { + return err + } + if err = addInterceptAfterDeserialization(stack, options); err != nil { + return err + } if err = addSpanInitializeStart(stack); err != nil { return err } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/auth.go index 0d60de1a4e..662380bae8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/auth.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/auth.go @@ -12,6 +12,8 @@ import ( "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/tracing" smithyhttp "github.com/aws/smithy-go/transport/http" + "slices" + "strings" ) func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) { @@ -169,7 +171,8 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid } func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { - for _, option := range options { + sorted := sortAuthOptions(options, m.options.AuthSchemePreference) + for _, option := range sorted { if option.SchemeID == smithyauth.SchemeIDAnonymous { return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true } @@ -188,6 +191,29 @@ func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) return nil, false } +func sortAuthOptions(options []*smithyauth.Option, preferred []string) []*smithyauth.Option { + byPriority := make([]*smithyauth.Option, 0, len(options)) + for _, prefName := range preferred { + for _, option := range options { + optName := option.SchemeID + if parts := strings.Split(option.SchemeID, "#"); len(parts) == 2 { + optName = parts[1] + } + if prefName == optName { + byPriority = append(byPriority, option) + } + } + } + for _, option := range options { + if !slices.ContainsFunc(byPriority, func(o *smithyauth.Option) bool { + return o.SchemeID == option.SchemeID + }) { + byPriority = append(byPriority, option) + } + } + return byPriority +} + type resolvedAuthSchemeKey struct{} type resolvedAuthScheme struct { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/deserializers.go index e8796324de..cb064151e8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/deserializers.go @@ -18,17 +18,8 @@ import ( smithyhttp "github.com/aws/smithy-go/transport/http" "io" "strings" - "time" ) -func deserializeS3Expires(v string) (*time.Time, error) { - t, err := smithytime.ParseHTTPDate(v) - if err != nil { - return nil, nil - } - return &t, nil -} - type awsAwsjson11_deserializeOpBatchCheckLayerAvailability struct { } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/endpoints.go index 39d8005662..c3615f4521 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/endpoints.go @@ -328,7 +328,9 @@ func (r *resolver) ResolveEndpoint( return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err) } _UseDualStack := *params.UseDualStack + _ = _UseDualStack _UseFIPS := *params.UseFIPS + _ = _UseFIPS if exprVal := params.Endpoint; exprVal != nil { _Endpoint := *exprVal @@ -409,6 +411,25 @@ func (r *resolver) ResolveEndpoint( } if _UseDualStack == true { if true == _PartitionResult.SupportsDualStack { + if "aws" == _PartitionResult.Name { + uriString := func() string { + var out strings.Builder + out.WriteString("https://ecr-public.") + out.WriteString(_Region) + out.WriteString(".api.aws") + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } uriString := func() string { var out strings.Builder out.WriteString("https://api.ecr-public.") diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/generated.json index f11524a5fe..c368599bda 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/generated.json @@ -44,12 +44,13 @@ "protocol_test.go", "serializers.go", "snapshot_test.go", + "sra_operation_order_test.go", "types/enums.go", "types/errors.go", "types/types.go", "validators.go" ], - "go": "1.15", + "go": "1.23", "module": "github.com/aws/aws-sdk-go-v2/service/ecrpublic", "unstable": false } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/go_module_metadata.go index 8fd54c55f3..5822caec9d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/go_module_metadata.go @@ -3,4 +3,4 @@ package ecrpublic // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.31.2" +const goModuleVersion = "1.38.2" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints/endpoints.go index 9a16fe412b..78baf149cf 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints/endpoints.go @@ -87,6 +87,7 @@ func New() *Resolver { var partitionRegexp = struct { Aws *regexp.Regexp AwsCn *regexp.Regexp + AwsEusc *regexp.Regexp AwsIso *regexp.Regexp AwsIsoB *regexp.Regexp AwsIsoE *regexp.Regexp @@ -96,6 +97,7 @@ var partitionRegexp = struct { Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$"), AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"), + AwsEusc: regexp.MustCompile("^eusc\\-(de)\\-\\w+\\-\\d+$"), AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"), AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"), AwsIsoE: regexp.MustCompile("^eu\\-isoe\\-\\w+\\-\\d+$"), @@ -201,6 +203,27 @@ var defaultPartitions = endpoints.Partitions{ RegionRegex: partitionRegexp.AwsCn, IsRegionalized: true, }, + { + ID: "aws-eusc", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "api.ecr-public-fips.{region}.amazonaws.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "api.ecr-public.{region}.amazonaws.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + RegionRegex: partitionRegexp.AwsEusc, + IsRegionalized: true, + }, { ID: "aws-iso", Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/options.go index c10ee3d0cf..58cccb886d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/options.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/options.go @@ -119,12 +119,18 @@ type Options struct { // implementation if nil. HTTPClient HTTPClient + // Client registry of operation interceptors. + Interceptors smithyhttp.InterceptorRegistry + // The auth scheme resolver which determines how to authenticate for each // operation. AuthSchemeResolver AuthSchemeResolver // The list of auth schemes supported by the client. AuthSchemes []smithyhttp.AuthScheme + + // Priority list of preferred auth scheme names (e.g. sigv4a). + AuthSchemePreference []string } // Copy creates a clone where the APIOptions list is deep copied. @@ -132,6 +138,7 @@ func (o Options) Copy() Options { to := o to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) copy(to.APIOptions, o.APIOptions) + to.Interceptors = o.Interceptors.Copy() return to } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md index c81265a25d..c05f82ea41 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md @@ -1,3 +1,23 @@ +# v1.13.3 (2025-11-04) + +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.13.2 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. + +# v1.13.1 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. + +# v1.13.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. + +# v1.12.4 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. + # v1.12.3 (2025-02-18) * **Bug Fix**: Bump go version to 1.22 diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go index d83e533eff..6a4c336055 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go @@ -3,4 +3,4 @@ package acceptencoding // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.12.3" +const goModuleVersion = "1.13.3" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md index ec8f6ce5b0..0db87c8abb 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md @@ -1,3 +1,76 @@ +# v1.13.14 (2025-11-19.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.13 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.13.12 (2025-10-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.11 (2025-10-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.10 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.9 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.8 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.7 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.6 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.5 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.4 (2025-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.3 (2025-08-11) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.2 (2025-08-04) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.1 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.13.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.18 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.12.17 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + # v1.12.16 (2025-06-10) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go index 03377a3d9b..b9c350a2bd 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go @@ -3,4 +3,4 @@ package presignedurl // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.12.16" +const goModuleVersion = "1.13.14" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/CHANGELOG.md new file mode 100644 index 0000000000..fa50673703 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/CHANGELOG.md @@ -0,0 +1,13 @@ +# v1.0.2 (2025-11-25) + +* **Bug Fix**: Add error check for endpoint param binding during auth scheme resolution to fix panic reported in #3234 + +# v1.0.1 (2025-11-19.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.0.0 (2025-11-19) + +* **Release**: New AWS service client module +* **Feature**: AWS Sign-In manages authentication for AWS services. This service provides secure authentication flows for accessing AWS resources from the console and developer tools. This release adds the CreateOAuth2Token API, which can be used to fetch OAuth2 access tokens and refresh tokens from Sign-In. + diff --git a/vendor/github.com/go-jose/go-jose/v3/LICENSE b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/LICENSE.txt similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/LICENSE rename to vendor/github.com/aws/aws-sdk-go-v2/service/signin/LICENSE.txt diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_client.go new file mode 100644 index 0000000000..d2db11d2aa --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_client.go @@ -0,0 +1,949 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package signin + +import ( + "context" + "errors" + "fmt" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/defaults" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + "github.com/aws/aws-sdk-go-v2/aws/retry" + "github.com/aws/aws-sdk-go-v2/aws/signer/v4" + awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" + internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" + internalmiddleware "github.com/aws/aws-sdk-go-v2/internal/middleware" + smithy "github.com/aws/smithy-go" + smithyauth "github.com/aws/smithy-go/auth" + smithydocument "github.com/aws/smithy-go/document" + "github.com/aws/smithy-go/logging" + "github.com/aws/smithy-go/metrics" + "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/tracing" + smithyhttp "github.com/aws/smithy-go/transport/http" + "net" + "net/http" + "sync/atomic" + "time" +) + +const ServiceID = "Signin" +const ServiceAPIVersion = "2023-01-01" + +type operationMetrics struct { + Duration metrics.Float64Histogram + SerializeDuration metrics.Float64Histogram + ResolveIdentityDuration metrics.Float64Histogram + ResolveEndpointDuration metrics.Float64Histogram + SignRequestDuration metrics.Float64Histogram + DeserializeDuration metrics.Float64Histogram +} + +func (m *operationMetrics) histogramFor(name string) metrics.Float64Histogram { + switch name { + case "client.call.duration": + return m.Duration + case "client.call.serialization_duration": + return m.SerializeDuration + case "client.call.resolve_identity_duration": + return m.ResolveIdentityDuration + case "client.call.resolve_endpoint_duration": + return m.ResolveEndpointDuration + case "client.call.signing_duration": + return m.SignRequestDuration + case "client.call.deserialization_duration": + return m.DeserializeDuration + default: + panic("unrecognized operation metric") + } +} + +func timeOperationMetric[T any]( + ctx context.Context, metric string, fn func() (T, error), + opts ...metrics.RecordMetricOption, +) (T, error) { + mm := getOperationMetrics(ctx) + if mm == nil { // not using the metrics system + return fn() + } + + instr := mm.histogramFor(metric) + opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) + + start := time.Now() + v, err := fn() + end := time.Now() + + elapsed := end.Sub(start) + instr.Record(ctx, float64(elapsed)/1e9, opts...) + return v, err +} + +func startMetricTimer(ctx context.Context, metric string, opts ...metrics.RecordMetricOption) func() { + mm := getOperationMetrics(ctx) + if mm == nil { // not using the metrics system + return func() {} + } + + instr := mm.histogramFor(metric) + opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) + + var ended bool + start := time.Now() + return func() { + if ended { + return + } + ended = true + + end := time.Now() + + elapsed := end.Sub(start) + instr.Record(ctx, float64(elapsed)/1e9, opts...) + } +} + +func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption { + return func(o *metrics.RecordMetricOptions) { + o.Properties.Set("rpc.service", middleware.GetServiceID(ctx)) + o.Properties.Set("rpc.method", middleware.GetOperationName(ctx)) + } +} + +type operationMetricsKey struct{} + +func withOperationMetrics(parent context.Context, mp metrics.MeterProvider) (context.Context, error) { + if _, ok := mp.(metrics.NopMeterProvider); ok { + // not using the metrics system - setting up the metrics context is a memory-intensive operation + // so we should skip it in this case + return parent, nil + } + + meter := mp.Meter("github.com/aws/aws-sdk-go-v2/service/signin") + om := &operationMetrics{} + + var err error + + om.Duration, err = operationMetricTimer(meter, "client.call.duration", + "Overall call duration (including retries and time to send or receive request and response body)") + if err != nil { + return nil, err + } + om.SerializeDuration, err = operationMetricTimer(meter, "client.call.serialization_duration", + "The time it takes to serialize a message body") + if err != nil { + return nil, err + } + om.ResolveIdentityDuration, err = operationMetricTimer(meter, "client.call.auth.resolve_identity_duration", + "The time taken to acquire an identity (AWS credentials, bearer token, etc) from an Identity Provider") + if err != nil { + return nil, err + } + om.ResolveEndpointDuration, err = operationMetricTimer(meter, "client.call.resolve_endpoint_duration", + "The time it takes to resolve an endpoint (endpoint resolver, not DNS) for the request") + if err != nil { + return nil, err + } + om.SignRequestDuration, err = operationMetricTimer(meter, "client.call.auth.signing_duration", + "The time it takes to sign a request") + if err != nil { + return nil, err + } + om.DeserializeDuration, err = operationMetricTimer(meter, "client.call.deserialization_duration", + "The time it takes to deserialize a message body") + if err != nil { + return nil, err + } + + return context.WithValue(parent, operationMetricsKey{}, om), nil +} + +func operationMetricTimer(m metrics.Meter, name, desc string) (metrics.Float64Histogram, error) { + return m.Float64Histogram(name, func(o *metrics.InstrumentOptions) { + o.UnitLabel = "s" + o.Description = desc + }) +} + +func getOperationMetrics(ctx context.Context) *operationMetrics { + if v := ctx.Value(operationMetricsKey{}); v != nil { + return v.(*operationMetrics) + } + return nil +} + +func operationTracer(p tracing.TracerProvider) tracing.Tracer { + return p.Tracer("github.com/aws/aws-sdk-go-v2/service/signin") +} + +// Client provides the API client to make operations call for AWS Sign-In Service. +type Client struct { + options Options + + // Difference between the time reported by the server and the client + timeOffset *atomic.Int64 +} + +// New returns an initialized Client based on the functional options. Provide +// additional functional options to further configure the behavior of the client, +// such as changing the client's endpoint or adding custom middleware behavior. +func New(options Options, optFns ...func(*Options)) *Client { + options = options.Copy() + + resolveDefaultLogger(&options) + + setResolvedDefaultsMode(&options) + + resolveRetryer(&options) + + resolveHTTPClient(&options) + + resolveHTTPSignerV4(&options) + + resolveEndpointResolverV2(&options) + + resolveTracerProvider(&options) + + resolveMeterProvider(&options) + + resolveAuthSchemeResolver(&options) + + for _, fn := range optFns { + fn(&options) + } + + finalizeRetryMaxAttempts(&options) + + ignoreAnonymousAuth(&options) + + wrapWithAnonymousAuth(&options) + + resolveAuthSchemes(&options) + + client := &Client{ + options: options, + } + + initializeTimeOffsetResolver(client) + + return client +} + +// Options returns a copy of the client configuration. +// +// Callers SHOULD NOT perform mutations on any inner structures within client +// config. Config overrides should instead be made on a per-operation basis through +// functional options. +func (c *Client) Options() Options { + return c.options.Copy() +} + +func (c *Client) invokeOperation( + ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error, +) ( + result interface{}, metadata middleware.Metadata, err error, +) { + ctx = middleware.ClearStackValues(ctx) + ctx = middleware.WithServiceID(ctx, ServiceID) + ctx = middleware.WithOperationName(ctx, opID) + + stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) + options := c.options.Copy() + + for _, fn := range optFns { + fn(&options) + } + + finalizeOperationRetryMaxAttempts(&options, *c) + + finalizeClientEndpointResolverOptions(&options) + + for _, fn := range stackFns { + if err := fn(stack, options); err != nil { + return nil, metadata, err + } + } + + for _, fn := range options.APIOptions { + if err := fn(stack); err != nil { + return nil, metadata, err + } + } + + ctx, err = withOperationMetrics(ctx, options.MeterProvider) + if err != nil { + return nil, metadata, err + } + + tracer := operationTracer(options.TracerProvider) + spanName := fmt.Sprintf("%s.%s", ServiceID, opID) + + ctx = tracing.WithOperationTracer(ctx, tracer) + + ctx, span := tracer.StartSpan(ctx, spanName, func(o *tracing.SpanOptions) { + o.Kind = tracing.SpanKindClient + o.Properties.Set("rpc.system", "aws-api") + o.Properties.Set("rpc.method", opID) + o.Properties.Set("rpc.service", ServiceID) + }) + endTimer := startMetricTimer(ctx, "client.call.duration") + defer endTimer() + defer span.End() + + handler := smithyhttp.NewClientHandlerWithOptions(options.HTTPClient, func(o *smithyhttp.ClientHandler) { + o.Meter = options.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/signin") + }) + decorated := middleware.DecorateHandler(handler, stack) + result, metadata, err = decorated.Handle(ctx, params) + if err != nil { + span.SetProperty("exception.type", fmt.Sprintf("%T", err)) + span.SetProperty("exception.message", err.Error()) + + var aerr smithy.APIError + if errors.As(err, &aerr) { + span.SetProperty("api.error_code", aerr.ErrorCode()) + span.SetProperty("api.error_message", aerr.ErrorMessage()) + span.SetProperty("api.error_fault", aerr.ErrorFault().String()) + } + + err = &smithy.OperationError{ + ServiceID: ServiceID, + OperationName: opID, + Err: err, + } + } + + span.SetProperty("error", err != nil) + if err == nil { + span.SetStatus(tracing.SpanStatusOK) + } else { + span.SetStatus(tracing.SpanStatusError) + } + + return result, metadata, err +} + +type operationInputKey struct{} + +func setOperationInput(ctx context.Context, input interface{}) context.Context { + return middleware.WithStackValue(ctx, operationInputKey{}, input) +} + +func getOperationInput(ctx context.Context) interface{} { + return middleware.GetStackValue(ctx, operationInputKey{}) +} + +type setOperationInputMiddleware struct { +} + +func (*setOperationInputMiddleware) ID() string { + return "setOperationInput" +} + +func (m *setOperationInputMiddleware) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + ctx = setOperationInput(ctx, in.Parameters) + return next.HandleSerialize(ctx, in) +} + +func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, operation string) error { + if err := stack.Finalize.Add(&resolveAuthSchemeMiddleware{operation: operation, options: options}, middleware.Before); err != nil { + return fmt.Errorf("add ResolveAuthScheme: %w", err) + } + if err := stack.Finalize.Insert(&getIdentityMiddleware{options: options}, "ResolveAuthScheme", middleware.After); err != nil { + return fmt.Errorf("add GetIdentity: %v", err) + } + if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil { + return fmt.Errorf("add ResolveEndpointV2: %v", err) + } + if err := stack.Finalize.Insert(&signRequestMiddleware{options: options}, "ResolveEndpointV2", middleware.After); err != nil { + return fmt.Errorf("add Signing: %w", err) + } + return nil +} +func resolveAuthSchemeResolver(options *Options) { + if options.AuthSchemeResolver == nil { + options.AuthSchemeResolver = &defaultAuthSchemeResolver{} + } +} + +func resolveAuthSchemes(options *Options) { + if options.AuthSchemes == nil { + options.AuthSchemes = []smithyhttp.AuthScheme{ + internalauth.NewHTTPAuthScheme("aws.auth#sigv4", &internalauthsmithy.V4SignerAdapter{ + Signer: options.HTTPSignerV4, + Logger: options.Logger, + LogSigning: options.ClientLogMode.IsSigning(), + }), + } + } +} + +type noSmithyDocumentSerde = smithydocument.NoSerde + +type legacyEndpointContextSetter struct { + LegacyResolver EndpointResolver +} + +func (*legacyEndpointContextSetter) ID() string { + return "legacyEndpointContextSetter" +} + +func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + if m.LegacyResolver != nil { + ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) + } + + return next.HandleInitialize(ctx, in) + +} +func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error { + return stack.Initialize.Add(&legacyEndpointContextSetter{ + LegacyResolver: o.EndpointResolver, + }, middleware.Before) +} + +func resolveDefaultLogger(o *Options) { + if o.Logger != nil { + return + } + o.Logger = logging.Nop{} +} + +func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error { + return middleware.AddSetLoggerMiddleware(stack, o.Logger) +} + +func setResolvedDefaultsMode(o *Options) { + if len(o.resolvedDefaultsMode) > 0 { + return + } + + var mode aws.DefaultsMode + mode.SetFromString(string(o.DefaultsMode)) + + if mode == aws.DefaultsModeAuto { + mode = defaults.ResolveDefaultsModeAuto(o.Region, o.RuntimeEnvironment) + } + + o.resolvedDefaultsMode = mode +} + +// NewFromConfig returns a new client from the provided config. +func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { + opts := Options{ + Region: cfg.Region, + DefaultsMode: cfg.DefaultsMode, + RuntimeEnvironment: cfg.RuntimeEnvironment, + HTTPClient: cfg.HTTPClient, + Credentials: cfg.Credentials, + APIOptions: cfg.APIOptions, + Logger: cfg.Logger, + ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, + AuthSchemePreference: cfg.AuthSchemePreference, + } + resolveAWSRetryerProvider(cfg, &opts) + resolveAWSRetryMaxAttempts(cfg, &opts) + resolveAWSRetryMode(cfg, &opts) + resolveAWSEndpointResolver(cfg, &opts) + resolveInterceptors(cfg, &opts) + resolveUseDualStackEndpoint(cfg, &opts) + resolveUseFIPSEndpoint(cfg, &opts) + resolveBaseEndpoint(cfg, &opts) + return New(opts, func(o *Options) { + for _, opt := range cfg.ServiceOptions { + opt(ServiceID, o) + } + for _, opt := range optFns { + opt(o) + } + }) +} + +func resolveHTTPClient(o *Options) { + var buildable *awshttp.BuildableClient + + if o.HTTPClient != nil { + var ok bool + buildable, ok = o.HTTPClient.(*awshttp.BuildableClient) + if !ok { + return + } + } else { + buildable = awshttp.NewBuildableClient() + } + + modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode) + if err == nil { + buildable = buildable.WithDialerOptions(func(dialer *net.Dialer) { + if dialerTimeout, ok := modeConfig.GetConnectTimeout(); ok { + dialer.Timeout = dialerTimeout + } + }) + + buildable = buildable.WithTransportOptions(func(transport *http.Transport) { + if tlsHandshakeTimeout, ok := modeConfig.GetTLSNegotiationTimeout(); ok { + transport.TLSHandshakeTimeout = tlsHandshakeTimeout + } + }) + } + + o.HTTPClient = buildable +} + +func resolveRetryer(o *Options) { + if o.Retryer != nil { + return + } + + if len(o.RetryMode) == 0 { + modeConfig, err := defaults.GetModeConfiguration(o.resolvedDefaultsMode) + if err == nil { + o.RetryMode = modeConfig.RetryMode + } + } + if len(o.RetryMode) == 0 { + o.RetryMode = aws.RetryModeStandard + } + + var standardOptions []func(*retry.StandardOptions) + if v := o.RetryMaxAttempts; v != 0 { + standardOptions = append(standardOptions, func(so *retry.StandardOptions) { + so.MaxAttempts = v + }) + } + + switch o.RetryMode { + case aws.RetryModeAdaptive: + var adaptiveOptions []func(*retry.AdaptiveModeOptions) + if len(standardOptions) != 0 { + adaptiveOptions = append(adaptiveOptions, func(ao *retry.AdaptiveModeOptions) { + ao.StandardOptions = append(ao.StandardOptions, standardOptions...) + }) + } + o.Retryer = retry.NewAdaptiveMode(adaptiveOptions...) + + default: + o.Retryer = retry.NewStandard(standardOptions...) + } +} + +func resolveAWSRetryerProvider(cfg aws.Config, o *Options) { + if cfg.Retryer == nil { + return + } + o.Retryer = cfg.Retryer() +} + +func resolveAWSRetryMode(cfg aws.Config, o *Options) { + if len(cfg.RetryMode) == 0 { + return + } + o.RetryMode = cfg.RetryMode +} +func resolveAWSRetryMaxAttempts(cfg aws.Config, o *Options) { + if cfg.RetryMaxAttempts == 0 { + return + } + o.RetryMaxAttempts = cfg.RetryMaxAttempts +} + +func finalizeRetryMaxAttempts(o *Options) { + if o.RetryMaxAttempts == 0 { + return + } + + o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) +} + +func finalizeOperationRetryMaxAttempts(o *Options, client Client) { + if v := o.RetryMaxAttempts; v == 0 || v == client.options.RetryMaxAttempts { + return + } + + o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) +} + +func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { + if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { + return + } + o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) +} + +func resolveInterceptors(cfg aws.Config, o *Options) { + o.Interceptors = cfg.Interceptors.Copy() +} + +func addClientUserAgent(stack *middleware.Stack, options Options) error { + ua, err := getOrAddRequestUserAgent(stack) + if err != nil { + return err + } + + ua.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "signin", goModuleVersion) + if len(options.AppID) > 0 { + ua.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID) + } + + return nil +} + +func getOrAddRequestUserAgent(stack *middleware.Stack) (*awsmiddleware.RequestUserAgent, error) { + id := (*awsmiddleware.RequestUserAgent)(nil).ID() + mw, ok := stack.Build.Get(id) + if !ok { + mw = awsmiddleware.NewRequestUserAgent() + if err := stack.Build.Add(mw, middleware.After); err != nil { + return nil, err + } + } + + ua, ok := mw.(*awsmiddleware.RequestUserAgent) + if !ok { + return nil, fmt.Errorf("%T for %s middleware did not match expected type", mw, id) + } + + return ua, nil +} + +type HTTPSignerV4 interface { + SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4.SignerOptions)) error +} + +func resolveHTTPSignerV4(o *Options) { + if o.HTTPSignerV4 != nil { + return + } + o.HTTPSignerV4 = newDefaultV4Signer(*o) +} + +func newDefaultV4Signer(o Options) *v4.Signer { + return v4.NewSigner(func(so *v4.SignerOptions) { + so.Logger = o.Logger + so.LogSigning = o.ClientLogMode.IsSigning() + }) +} + +func addClientRequestID(stack *middleware.Stack) error { + return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After) +} + +func addComputeContentLength(stack *middleware.Stack) error { + return stack.Build.Add(&smithyhttp.ComputeContentLength{}, middleware.After) +} + +func addRawResponseToMetadata(stack *middleware.Stack) error { + return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before) +} + +func addRecordResponseTiming(stack *middleware.Stack) error { + return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After) +} + +func addSpanRetryLoop(stack *middleware.Stack, options Options) error { + return stack.Finalize.Insert(&spanRetryLoop{options: options}, "Retry", middleware.Before) +} + +type spanRetryLoop struct { + options Options +} + +func (*spanRetryLoop) ID() string { + return "spanRetryLoop" +} + +func (m *spanRetryLoop) HandleFinalize( + ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, +) ( + middleware.FinalizeOutput, middleware.Metadata, error, +) { + tracer := operationTracer(m.options.TracerProvider) + ctx, span := tracer.StartSpan(ctx, "RetryLoop") + defer span.End() + + return next.HandleFinalize(ctx, in) +} +func addStreamingEventsPayload(stack *middleware.Stack) error { + return stack.Finalize.Add(&v4.StreamingEventsPayload{}, middleware.Before) +} + +func addUnsignedPayload(stack *middleware.Stack) error { + return stack.Finalize.Insert(&v4.UnsignedPayload{}, "ResolveEndpointV2", middleware.After) +} + +func addComputePayloadSHA256(stack *middleware.Stack) error { + return stack.Finalize.Insert(&v4.ComputePayloadSHA256{}, "ResolveEndpointV2", middleware.After) +} + +func addContentSHA256Header(stack *middleware.Stack) error { + return stack.Finalize.Insert(&v4.ContentSHA256Header{}, (*v4.ComputePayloadSHA256)(nil).ID(), middleware.After) +} + +func addIsWaiterUserAgent(o *Options) { + o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error { + ua, err := getOrAddRequestUserAgent(stack) + if err != nil { + return err + } + + ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureWaiter) + return nil + }) +} + +func addIsPaginatorUserAgent(o *Options) { + o.APIOptions = append(o.APIOptions, func(stack *middleware.Stack) error { + ua, err := getOrAddRequestUserAgent(stack) + if err != nil { + return err + } + + ua.AddUserAgentFeature(awsmiddleware.UserAgentFeaturePaginator) + return nil + }) +} + +func addRetry(stack *middleware.Stack, o Options) error { + attempt := retry.NewAttemptMiddleware(o.Retryer, smithyhttp.RequestCloner, func(m *retry.Attempt) { + m.LogAttempts = o.ClientLogMode.IsRetries() + m.OperationMeter = o.MeterProvider.Meter("github.com/aws/aws-sdk-go-v2/service/signin") + }) + if err := stack.Finalize.Insert(attempt, "ResolveAuthScheme", middleware.Before); err != nil { + return err + } + if err := stack.Finalize.Insert(&retry.MetricsHeader{}, attempt.ID(), middleware.After); err != nil { + return err + } + return nil +} + +// resolves dual-stack endpoint configuration +func resolveUseDualStackEndpoint(cfg aws.Config, o *Options) error { + if len(cfg.ConfigSources) == 0 { + return nil + } + value, found, err := internalConfig.ResolveUseDualStackEndpoint(context.Background(), cfg.ConfigSources) + if err != nil { + return err + } + if found { + o.EndpointOptions.UseDualStackEndpoint = value + } + return nil +} + +// resolves FIPS endpoint configuration +func resolveUseFIPSEndpoint(cfg aws.Config, o *Options) error { + if len(cfg.ConfigSources) == 0 { + return nil + } + value, found, err := internalConfig.ResolveUseFIPSEndpoint(context.Background(), cfg.ConfigSources) + if err != nil { + return err + } + if found { + o.EndpointOptions.UseFIPSEndpoint = value + } + return nil +} + +func resolveAccountID(identity smithyauth.Identity, mode aws.AccountIDEndpointMode) *string { + if mode == aws.AccountIDEndpointModeDisabled { + return nil + } + + if ca, ok := identity.(*internalauthsmithy.CredentialsAdapter); ok && ca.Credentials.AccountID != "" { + return aws.String(ca.Credentials.AccountID) + } + + return nil +} + +func addTimeOffsetBuild(stack *middleware.Stack, c *Client) error { + mw := internalmiddleware.AddTimeOffsetMiddleware{Offset: c.timeOffset} + if err := stack.Build.Add(&mw, middleware.After); err != nil { + return err + } + return stack.Deserialize.Insert(&mw, "RecordResponseTiming", middleware.Before) +} +func initializeTimeOffsetResolver(c *Client) { + c.timeOffset = new(atomic.Int64) +} + +func addUserAgentRetryMode(stack *middleware.Stack, options Options) error { + ua, err := getOrAddRequestUserAgent(stack) + if err != nil { + return err + } + + switch options.Retryer.(type) { + case *retry.Standard: + ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeStandard) + case *retry.AdaptiveMode: + ua.AddUserAgentFeature(awsmiddleware.UserAgentFeatureRetryModeAdaptive) + } + return nil +} + +type setCredentialSourceMiddleware struct { + ua *awsmiddleware.RequestUserAgent + options Options +} + +func (m setCredentialSourceMiddleware) ID() string { return "SetCredentialSourceMiddleware" } + +func (m setCredentialSourceMiddleware) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) ( + out middleware.BuildOutput, metadata middleware.Metadata, err error, +) { + asProviderSource, ok := m.options.Credentials.(aws.CredentialProviderSource) + if !ok { + return next.HandleBuild(ctx, in) + } + providerSources := asProviderSource.ProviderSources() + for _, source := range providerSources { + m.ua.AddCredentialsSource(source) + } + return next.HandleBuild(ctx, in) +} + +func addCredentialSource(stack *middleware.Stack, options Options) error { + ua, err := getOrAddRequestUserAgent(stack) + if err != nil { + return err + } + + mw := setCredentialSourceMiddleware{ua: ua, options: options} + return stack.Build.Insert(&mw, "UserAgent", middleware.Before) +} + +func resolveTracerProvider(options *Options) { + if options.TracerProvider == nil { + options.TracerProvider = &tracing.NopTracerProvider{} + } +} + +func resolveMeterProvider(options *Options) { + if options.MeterProvider == nil { + options.MeterProvider = metrics.NopMeterProvider{} + } +} + +func addRecursionDetection(stack *middleware.Stack) error { + return stack.Build.Add(&awsmiddleware.RecursionDetection{}, middleware.After) +} + +func addRequestIDRetrieverMiddleware(stack *middleware.Stack) error { + return stack.Deserialize.Insert(&awsmiddleware.RequestIDRetriever{}, "OperationDeserializer", middleware.Before) + +} + +func addResponseErrorMiddleware(stack *middleware.Stack) error { + return stack.Deserialize.Insert(&awshttp.ResponseErrorWrapper{}, "RequestIDRetriever", middleware.Before) + +} + +func addRequestResponseLogging(stack *middleware.Stack, o Options) error { + return stack.Deserialize.Add(&smithyhttp.RequestResponseLogger{ + LogRequest: o.ClientLogMode.IsRequest(), + LogRequestWithBody: o.ClientLogMode.IsRequestWithBody(), + LogResponse: o.ClientLogMode.IsResponse(), + LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), + }, middleware.After) +} + +type disableHTTPSMiddleware struct { + DisableHTTPS bool +} + +func (*disableHTTPSMiddleware) ID() string { + return "disableHTTPS" +} + +func (m *disableHTTPSMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.DisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { + req.URL.Scheme = "http" + } + + return next.HandleFinalize(ctx, in) +} + +func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { + return stack.Finalize.Insert(&disableHTTPSMiddleware{ + DisableHTTPS: o.EndpointOptions.DisableHTTPS, + }, "ResolveEndpointV2", middleware.After) +} + +func addInterceptBeforeRetryLoop(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptBeforeRetryLoop{ + Interceptors: opts.Interceptors.BeforeRetryLoop, + }, "Retry", middleware.Before) +} + +func addInterceptAttempt(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptAttempt{ + BeforeAttempt: opts.Interceptors.BeforeAttempt, + AfterAttempt: opts.Interceptors.AfterAttempt, + }, "Retry", middleware.After) +} + +func addInterceptors(stack *middleware.Stack, opts Options) error { + // middlewares are expensive, don't add all of these interceptor ones unless the caller + // actually has at least one interceptor configured + // + // at the moment it's all-or-nothing because some of the middlewares here are responsible for + // setting fields in the interceptor context for future ones + if len(opts.Interceptors.BeforeExecution) == 0 && + len(opts.Interceptors.BeforeSerialization) == 0 && len(opts.Interceptors.AfterSerialization) == 0 && + len(opts.Interceptors.BeforeRetryLoop) == 0 && + len(opts.Interceptors.BeforeAttempt) == 0 && + len(opts.Interceptors.BeforeSigning) == 0 && len(opts.Interceptors.AfterSigning) == 0 && + len(opts.Interceptors.BeforeTransmit) == 0 && len(opts.Interceptors.AfterTransmit) == 0 && + len(opts.Interceptors.BeforeDeserialization) == 0 && len(opts.Interceptors.AfterDeserialization) == 0 && + len(opts.Interceptors.AfterAttempt) == 0 && len(opts.Interceptors.AfterExecution) == 0 { + return nil + } + + return errors.Join( + stack.Initialize.Add(&smithyhttp.InterceptExecution{ + BeforeExecution: opts.Interceptors.BeforeExecution, + AfterExecution: opts.Interceptors.AfterExecution, + }, middleware.Before), + stack.Serialize.Insert(&smithyhttp.InterceptBeforeSerialization{ + Interceptors: opts.Interceptors.BeforeSerialization, + }, "OperationSerializer", middleware.Before), + stack.Serialize.Insert(&smithyhttp.InterceptAfterSerialization{ + Interceptors: opts.Interceptors.AfterSerialization, + }, "OperationSerializer", middleware.After), + stack.Finalize.Insert(&smithyhttp.InterceptBeforeSigning{ + Interceptors: opts.Interceptors.BeforeSigning, + }, "Signing", middleware.Before), + stack.Finalize.Insert(&smithyhttp.InterceptAfterSigning{ + Interceptors: opts.Interceptors.AfterSigning, + }, "Signing", middleware.After), + stack.Deserialize.Add(&smithyhttp.InterceptTransmit{ + BeforeTransmit: opts.Interceptors.BeforeTransmit, + AfterTransmit: opts.Interceptors.AfterTransmit, + }, middleware.After), + stack.Deserialize.Insert(&smithyhttp.InterceptBeforeDeserialization{ + Interceptors: opts.Interceptors.BeforeDeserialization, + }, "OperationDeserializer", middleware.After), // (deserialize stack is called in reverse) + stack.Deserialize.Insert(&smithyhttp.InterceptAfterDeserialization{ + Interceptors: opts.Interceptors.AfterDeserialization, + }, "OperationDeserializer", middleware.Before), + ) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_CreateOAuth2Token.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_CreateOAuth2Token.go new file mode 100644 index 0000000000..54ba42422d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/api_op_CreateOAuth2Token.go @@ -0,0 +1,209 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package signin + +import ( + "context" + "fmt" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + "github.com/aws/aws-sdk-go-v2/service/signin/types" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" +) + +// CreateOAuth2Token API +// +// Path: /v1/token Request Method: POST Content-Type: application/json or +// application/x-www-form-urlencoded +// +// This API implements OAuth 2.0 flows for AWS Sign-In CLI clients, supporting +// both: +// +// - Authorization code redemption (grant_type=authorization_code) - NOT +// idempotent +// - Token refresh (grant_type=refresh_token) - Idempotent within token validity +// window +// +// The operation behavior is determined by the grant_type parameter in the request +// body: +// +// Authorization Code Flow (NOT Idempotent): +// +// - JSON or form-encoded body with client_id, grant_type=authorization_code, +// code, redirect_uri, code_verifier +// - Returns access_token, token_type, expires_in, refresh_token, and id_token +// - Each authorization code can only be used ONCE for security (prevents replay +// attacks) +// +// Token Refresh Flow (Idempotent): +// +// - JSON or form-encoded body with client_id, grant_type=refresh_token, +// refresh_token +// - Returns access_token, token_type, expires_in, and refresh_token (no +// id_token) +// - Multiple calls with same refresh_token return consistent results within +// validity window +// +// Authentication and authorization: +// +// - Confidential clients: sigv4 signing required with signin:ExchangeToken +// permissions +// - CLI clients (public): authn/authz skipped based on client_id & grant_type +// +// Note: This operation cannot be marked as @idempotent because it handles both +// idempotent (token refresh) and non-idempotent (auth code redemption) flows in a +// single endpoint. +func (c *Client) CreateOAuth2Token(ctx context.Context, params *CreateOAuth2TokenInput, optFns ...func(*Options)) (*CreateOAuth2TokenOutput, error) { + if params == nil { + params = &CreateOAuth2TokenInput{} + } + + result, metadata, err := c.invokeOperation(ctx, "CreateOAuth2Token", params, optFns, c.addOperationCreateOAuth2TokenMiddlewares) + if err != nil { + return nil, err + } + + out := result.(*CreateOAuth2TokenOutput) + out.ResultMetadata = metadata + return out, nil +} + +// Input structure for CreateOAuth2Token operation +// +// Contains flattened token operation inputs for both authorization code and +// refresh token flows. The operation type is determined by the grant_type +// parameter in the request body. +type CreateOAuth2TokenInput struct { + + // Flattened token operation inputs The specific operation is determined by + // grant_type in the request body + // + // This member is required. + TokenInput *types.CreateOAuth2TokenRequestBody + + noSmithyDocumentSerde +} + +// Output structure for CreateOAuth2Token operation +// +// Contains flattened token operation outputs for both authorization code and +// refresh token flows. The response content depends on the grant_type from the +// original request. +type CreateOAuth2TokenOutput struct { + + // Flattened token operation outputs The specific response fields depend on the + // grant_type used in the request + // + // This member is required. + TokenOutput *types.CreateOAuth2TokenResponseBody + + // Metadata pertaining to the operation's result. + ResultMetadata middleware.Metadata + + noSmithyDocumentSerde +} + +func (c *Client) addOperationCreateOAuth2TokenMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } + err = stack.Serialize.Add(&awsRestjson1_serializeOpCreateOAuth2Token{}, middleware.After) + if err != nil { + return err + } + err = stack.Deserialize.Add(&awsRestjson1_deserializeOpCreateOAuth2Token{}, middleware.After) + if err != nil { + return err + } + if err := addProtocolFinalizerMiddlewares(stack, options, "CreateOAuth2Token"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } + if err = addSetLoggerMiddleware(stack, options); err != nil { + return err + } + if err = addClientRequestID(stack); err != nil { + return err + } + if err = addComputeContentLength(stack); err != nil { + return err + } + if err = addResolveEndpointMiddleware(stack, options); err != nil { + return err + } + if err = addRetry(stack, options); err != nil { + return err + } + if err = addRawResponseToMetadata(stack); err != nil { + return err + } + if err = addRecordResponseTiming(stack); err != nil { + return err + } + if err = addSpanRetryLoop(stack, options); err != nil { + return err + } + if err = addClientUserAgent(stack, options); err != nil { + return err + } + if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } + if err = addTimeOffsetBuild(stack, c); err != nil { + return err + } + if err = addUserAgentRetryMode(stack, options); err != nil { + return err + } + if err = addCredentialSource(stack, options); err != nil { + return err + } + if err = addOpCreateOAuth2TokenValidationMiddleware(stack); err != nil { + return err + } + if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateOAuth2Token(options.Region), middleware.Before); err != nil { + return err + } + if err = addRecursionDetection(stack); err != nil { + return err + } + if err = addRequestIDRetrieverMiddleware(stack); err != nil { + return err + } + if err = addResponseErrorMiddleware(stack); err != nil { + return err + } + if err = addRequestResponseLogging(stack, options); err != nil { + return err + } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptors(stack, options); err != nil { + return err + } + return nil +} + +func newServiceMetadataMiddleware_opCreateOAuth2Token(region string) *awsmiddleware.RegisterServiceMetadata { + return &awsmiddleware.RegisterServiceMetadata{ + Region: region, + ServiceID: ServiceID, + OperationName: "CreateOAuth2Token", + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/auth.go new file mode 100644 index 0000000000..cf6b365041 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/auth.go @@ -0,0 +1,351 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package signin + +import ( + "context" + "fmt" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + smithy "github.com/aws/smithy-go" + smithyauth "github.com/aws/smithy-go/auth" + "github.com/aws/smithy-go/metrics" + "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/tracing" + smithyhttp "github.com/aws/smithy-go/transport/http" + "slices" + "strings" +) + +func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) error { + params.Region = options.Region + return nil +} + +type setLegacyContextSigningOptionsMiddleware struct { +} + +func (*setLegacyContextSigningOptionsMiddleware) ID() string { + return "setLegacyContextSigningOptions" +} + +func (m *setLegacyContextSigningOptionsMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + rscheme := getResolvedAuthScheme(ctx) + schemeID := rscheme.Scheme.SchemeID() + + if sn := awsmiddleware.GetSigningName(ctx); sn != "" { + if schemeID == "aws.auth#sigv4" { + smithyhttp.SetSigV4SigningName(&rscheme.SignerProperties, sn) + } else if schemeID == "aws.auth#sigv4a" { + smithyhttp.SetSigV4ASigningName(&rscheme.SignerProperties, sn) + } + } + + if sr := awsmiddleware.GetSigningRegion(ctx); sr != "" { + if schemeID == "aws.auth#sigv4" { + smithyhttp.SetSigV4SigningRegion(&rscheme.SignerProperties, sr) + } else if schemeID == "aws.auth#sigv4a" { + smithyhttp.SetSigV4ASigningRegions(&rscheme.SignerProperties, []string{sr}) + } + } + + return next.HandleFinalize(ctx, in) +} + +func addSetLegacyContextSigningOptionsMiddleware(stack *middleware.Stack) error { + return stack.Finalize.Insert(&setLegacyContextSigningOptionsMiddleware{}, "Signing", middleware.Before) +} + +type withAnonymous struct { + resolver AuthSchemeResolver +} + +var _ AuthSchemeResolver = (*withAnonymous)(nil) + +func (v *withAnonymous) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { + opts, err := v.resolver.ResolveAuthSchemes(ctx, params) + if err != nil { + return nil, err + } + + opts = append(opts, &smithyauth.Option{ + SchemeID: smithyauth.SchemeIDAnonymous, + }) + return opts, nil +} + +func wrapWithAnonymousAuth(options *Options) { + if _, ok := options.AuthSchemeResolver.(*defaultAuthSchemeResolver); !ok { + return + } + + options.AuthSchemeResolver = &withAnonymous{ + resolver: options.AuthSchemeResolver, + } +} + +// AuthResolverParameters contains the set of inputs necessary for auth scheme +// resolution. +type AuthResolverParameters struct { + // The name of the operation being invoked. + Operation string + + // The region in which the operation is being invoked. + Region string +} + +func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) (*AuthResolverParameters, error) { + params := &AuthResolverParameters{ + Operation: operation, + } + + if err := bindAuthParamsRegion(ctx, params, input, options); err != nil { + return nil, err + } + + return params, nil +} + +// AuthSchemeResolver returns a set of possible authentication options for an +// operation. +type AuthSchemeResolver interface { + ResolveAuthSchemes(context.Context, *AuthResolverParameters) ([]*smithyauth.Option, error) +} + +type defaultAuthSchemeResolver struct{} + +var _ AuthSchemeResolver = (*defaultAuthSchemeResolver)(nil) + +func (*defaultAuthSchemeResolver) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { + if overrides, ok := operationAuthOptions[params.Operation]; ok { + return overrides(params), nil + } + return serviceAuthOptions(params), nil +} + +var operationAuthOptions = map[string]func(*AuthResolverParameters) []*smithyauth.Option{ + "CreateOAuth2Token": func(params *AuthResolverParameters) []*smithyauth.Option { + return []*smithyauth.Option{ + {SchemeID: smithyauth.SchemeIDAnonymous}, + } + }, +} + +func serviceAuthOptions(params *AuthResolverParameters) []*smithyauth.Option { + return []*smithyauth.Option{ + { + SchemeID: smithyauth.SchemeIDSigV4, + SignerProperties: func() smithy.Properties { + var props smithy.Properties + smithyhttp.SetSigV4SigningName(&props, "signin") + smithyhttp.SetSigV4SigningRegion(&props, params.Region) + return props + }(), + }, + } +} + +type resolveAuthSchemeMiddleware struct { + operation string + options Options +} + +func (*resolveAuthSchemeMiddleware) ID() string { + return "ResolveAuthScheme" +} + +func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + _, span := tracing.StartSpan(ctx, "ResolveAuthScheme") + defer span.End() + + params, err := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options) + if err != nil { + return out, metadata, fmt.Errorf("bind auth scheme params: %w", err) + } + options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("resolve auth scheme: %w", err) + } + + scheme, ok := m.selectScheme(options) + if !ok { + return out, metadata, fmt.Errorf("could not select an auth scheme") + } + + ctx = setResolvedAuthScheme(ctx, scheme) + + span.SetProperty("auth.scheme_id", scheme.Scheme.SchemeID()) + span.End() + return next.HandleFinalize(ctx, in) +} + +func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { + sorted := sortAuthOptions(options, m.options.AuthSchemePreference) + for _, option := range sorted { + if option.SchemeID == smithyauth.SchemeIDAnonymous { + return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true + } + + for _, scheme := range m.options.AuthSchemes { + if scheme.SchemeID() != option.SchemeID { + continue + } + + if scheme.IdentityResolver(m.options) != nil { + return newResolvedAuthScheme(scheme, option), true + } + } + } + + return nil, false +} + +func sortAuthOptions(options []*smithyauth.Option, preferred []string) []*smithyauth.Option { + byPriority := make([]*smithyauth.Option, 0, len(options)) + for _, prefName := range preferred { + for _, option := range options { + optName := option.SchemeID + if parts := strings.Split(option.SchemeID, "#"); len(parts) == 2 { + optName = parts[1] + } + if prefName == optName { + byPriority = append(byPriority, option) + } + } + } + for _, option := range options { + if !slices.ContainsFunc(byPriority, func(o *smithyauth.Option) bool { + return o.SchemeID == option.SchemeID + }) { + byPriority = append(byPriority, option) + } + } + return byPriority +} + +type resolvedAuthSchemeKey struct{} + +type resolvedAuthScheme struct { + Scheme smithyhttp.AuthScheme + IdentityProperties smithy.Properties + SignerProperties smithy.Properties +} + +func newResolvedAuthScheme(scheme smithyhttp.AuthScheme, option *smithyauth.Option) *resolvedAuthScheme { + return &resolvedAuthScheme{ + Scheme: scheme, + IdentityProperties: option.IdentityProperties, + SignerProperties: option.SignerProperties, + } +} + +func setResolvedAuthScheme(ctx context.Context, scheme *resolvedAuthScheme) context.Context { + return middleware.WithStackValue(ctx, resolvedAuthSchemeKey{}, scheme) +} + +func getResolvedAuthScheme(ctx context.Context) *resolvedAuthScheme { + v, _ := middleware.GetStackValue(ctx, resolvedAuthSchemeKey{}).(*resolvedAuthScheme) + return v +} + +type getIdentityMiddleware struct { + options Options +} + +func (*getIdentityMiddleware) ID() string { + return "GetIdentity" +} + +func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + innerCtx, span := tracing.StartSpan(ctx, "GetIdentity") + defer span.End() + + rscheme := getResolvedAuthScheme(innerCtx) + if rscheme == nil { + return out, metadata, fmt.Errorf("no resolved auth scheme") + } + + resolver := rscheme.Scheme.IdentityResolver(m.options) + if resolver == nil { + return out, metadata, fmt.Errorf("no identity resolver") + } + + identity, err := timeOperationMetric(ctx, "client.call.resolve_identity_duration", + func() (smithyauth.Identity, error) { + return resolver.GetIdentity(innerCtx, rscheme.IdentityProperties) + }, + func(o *metrics.RecordMetricOptions) { + o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID()) + }) + if err != nil { + return out, metadata, fmt.Errorf("get identity: %w", err) + } + + ctx = setIdentity(ctx, identity) + + span.End() + return next.HandleFinalize(ctx, in) +} + +type identityKey struct{} + +func setIdentity(ctx context.Context, identity smithyauth.Identity) context.Context { + return middleware.WithStackValue(ctx, identityKey{}, identity) +} + +func getIdentity(ctx context.Context) smithyauth.Identity { + v, _ := middleware.GetStackValue(ctx, identityKey{}).(smithyauth.Identity) + return v +} + +type signRequestMiddleware struct { + options Options +} + +func (*signRequestMiddleware) ID() string { + return "Signing" +} + +func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + _, span := tracing.StartSpan(ctx, "SignRequest") + defer span.End() + + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request) + } + + rscheme := getResolvedAuthScheme(ctx) + if rscheme == nil { + return out, metadata, fmt.Errorf("no resolved auth scheme") + } + + identity := getIdentity(ctx) + if identity == nil { + return out, metadata, fmt.Errorf("no identity") + } + + signer := rscheme.Scheme.Signer() + if signer == nil { + return out, metadata, fmt.Errorf("no signer") + } + + _, err = timeOperationMetric(ctx, "client.call.signing_duration", func() (any, error) { + return nil, signer.SignRequest(ctx, req, identity, rscheme.SignerProperties) + }, func(o *metrics.RecordMetricOptions) { + o.Properties.Set("auth.scheme_id", rscheme.Scheme.SchemeID()) + }) + if err != nil { + return out, metadata, fmt.Errorf("sign request: %w", err) + } + + span.End() + return next.HandleFinalize(ctx, in) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/deserializers.go new file mode 100644 index 0000000000..b74b612e6b --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/deserializers.go @@ -0,0 +1,655 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package signin + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "github.com/aws/aws-sdk-go-v2/aws/protocol/restjson" + "github.com/aws/aws-sdk-go-v2/service/signin/types" + smithy "github.com/aws/smithy-go" + smithyio "github.com/aws/smithy-go/io" + "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" + "github.com/aws/smithy-go/tracing" + smithyhttp "github.com/aws/smithy-go/transport/http" + "io" + "strings" +) + +type awsRestjson1_deserializeOpCreateOAuth2Token struct { +} + +func (*awsRestjson1_deserializeOpCreateOAuth2Token) ID() string { + return "OperationDeserializer" +} + +func (m *awsRestjson1_deserializeOpCreateOAuth2Token) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( + out middleware.DeserializeOutput, metadata middleware.Metadata, err error, +) { + out, metadata, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, metadata, err + } + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + response, ok := out.RawResponse.(*smithyhttp.Response) + if !ok { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} + } + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsRestjson1_deserializeOpErrorCreateOAuth2Token(response, &metadata) + } + output := &CreateOAuth2TokenOutput{} + out.Result = output + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(response.Body, ringBuffer) + + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return out, metadata, err + } + + err = awsRestjson1_deserializeDocumentCreateOAuth2TokenResponseBody(&output.TokenOutput, shape) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return out, metadata, &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body with invalid JSON, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + span.End() + return out, metadata, err +} + +func awsRestjson1_deserializeOpErrorCreateOAuth2Token(response *smithyhttp.Response, metadata *middleware.Metadata) error { + var errorBuffer bytes.Buffer + if _, err := io.Copy(&errorBuffer, response.Body); err != nil { + return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} + } + errorBody := bytes.NewReader(errorBuffer.Bytes()) + + errorCode := "UnknownError" + errorMessage := errorCode + + headerCode := response.Header.Get("X-Amzn-ErrorType") + if len(headerCode) != 0 { + errorCode = restjson.SanitizeErrorCode(headerCode) + } + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + jsonCode, message, err := restjson.GetErrorInfo(decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + if len(headerCode) == 0 && len(jsonCode) != 0 { + errorCode = restjson.SanitizeErrorCode(jsonCode) + } + if len(message) != 0 { + errorMessage = message + } + + switch { + case strings.EqualFold("AccessDeniedException", errorCode): + return awsRestjson1_deserializeErrorAccessDeniedException(response, errorBody) + + case strings.EqualFold("InternalServerException", errorCode): + return awsRestjson1_deserializeErrorInternalServerException(response, errorBody) + + case strings.EqualFold("TooManyRequestsError", errorCode): + return awsRestjson1_deserializeErrorTooManyRequestsError(response, errorBody) + + case strings.EqualFold("ValidationException", errorCode): + return awsRestjson1_deserializeErrorValidationException(response, errorBody) + + default: + genericError := &smithy.GenericAPIError{ + Code: errorCode, + Message: errorMessage, + } + return genericError + + } +} + +func awsRestjson1_deserializeOpDocumentCreateOAuth2TokenOutput(v **CreateOAuth2TokenOutput, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *CreateOAuth2TokenOutput + if *v == nil { + sv = &CreateOAuth2TokenOutput{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "tokenOutput": + if err := awsRestjson1_deserializeDocumentCreateOAuth2TokenResponseBody(&sv.TokenOutput, value); err != nil { + return err + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsRestjson1_deserializeErrorAccessDeniedException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.AccessDeniedException{} + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + err := awsRestjson1_deserializeDocumentAccessDeniedException(&output, shape) + + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + + return output +} + +func awsRestjson1_deserializeErrorInternalServerException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.InternalServerException{} + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + err := awsRestjson1_deserializeDocumentInternalServerException(&output, shape) + + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + + return output +} + +func awsRestjson1_deserializeErrorTooManyRequestsError(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.TooManyRequestsError{} + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + err := awsRestjson1_deserializeDocumentTooManyRequestsError(&output, shape) + + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + + return output +} + +func awsRestjson1_deserializeErrorValidationException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.ValidationException{} + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + err := awsRestjson1_deserializeDocumentValidationException(&output, shape) + + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + + return output +} + +func awsRestjson1_deserializeDocumentAccessDeniedException(v **types.AccessDeniedException, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.AccessDeniedException + if *v == nil { + sv = &types.AccessDeniedException{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "error": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected OAuth2ErrorCode to be of type string, got %T instead", value) + } + sv.Error_ = types.OAuth2ErrorCode(jtv) + } + + case "message", "Message": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.Message = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsRestjson1_deserializeDocumentAccessToken(v **types.AccessToken, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.AccessToken + if *v == nil { + sv = &types.AccessToken{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "accessKeyId": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.AccessKeyId = ptr.String(jtv) + } + + case "secretAccessKey": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.SecretAccessKey = ptr.String(jtv) + } + + case "sessionToken": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.SessionToken = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsRestjson1_deserializeDocumentCreateOAuth2TokenResponseBody(v **types.CreateOAuth2TokenResponseBody, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.CreateOAuth2TokenResponseBody + if *v == nil { + sv = &types.CreateOAuth2TokenResponseBody{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "accessToken": + if err := awsRestjson1_deserializeDocumentAccessToken(&sv.AccessToken, value); err != nil { + return err + } + + case "expiresIn": + if value != nil { + jtv, ok := value.(json.Number) + if !ok { + return fmt.Errorf("expected ExpiresIn to be json.Number, got %T instead", value) + } + i64, err := jtv.Int64() + if err != nil { + return err + } + sv.ExpiresIn = ptr.Int32(int32(i64)) + } + + case "idToken": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected IdToken to be of type string, got %T instead", value) + } + sv.IdToken = ptr.String(jtv) + } + + case "refreshToken": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected RefreshToken to be of type string, got %T instead", value) + } + sv.RefreshToken = ptr.String(jtv) + } + + case "tokenType": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected TokenType to be of type string, got %T instead", value) + } + sv.TokenType = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsRestjson1_deserializeDocumentInternalServerException(v **types.InternalServerException, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.InternalServerException + if *v == nil { + sv = &types.InternalServerException{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "error": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected OAuth2ErrorCode to be of type string, got %T instead", value) + } + sv.Error_ = types.OAuth2ErrorCode(jtv) + } + + case "message", "Message": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.Message = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsRestjson1_deserializeDocumentTooManyRequestsError(v **types.TooManyRequestsError, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.TooManyRequestsError + if *v == nil { + sv = &types.TooManyRequestsError{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "error": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected OAuth2ErrorCode to be of type string, got %T instead", value) + } + sv.Error_ = types.OAuth2ErrorCode(jtv) + } + + case "message", "Message": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.Message = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsRestjson1_deserializeDocumentValidationException(v **types.ValidationException, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.ValidationException + if *v == nil { + sv = &types.ValidationException{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "error": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected OAuth2ErrorCode to be of type string, got %T instead", value) + } + sv.Error_ = types.OAuth2ErrorCode(jtv) + } + + case "message", "Message": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected String to be of type string, got %T instead", value) + } + sv.Message = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/doc.go new file mode 100644 index 0000000000..dc1a8b62f0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/doc.go @@ -0,0 +1,9 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +// Package signin provides the API client, operations, and parameter types for AWS +// Sign-In Service. +// +// AWS Sign-In manages authentication for AWS services. This service provides +// secure authentication flows for accessing AWS resources from the console and +// developer tools. +package signin diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/endpoints.go new file mode 100644 index 0000000000..db2e6a62a3 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/endpoints.go @@ -0,0 +1,624 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package signin + +import ( + "context" + "errors" + "fmt" + "github.com/aws/aws-sdk-go-v2/aws" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" + "github.com/aws/aws-sdk-go-v2/internal/endpoints" + "github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn" + internalendpoints "github.com/aws/aws-sdk-go-v2/service/signin/internal/endpoints" + smithyauth "github.com/aws/smithy-go/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" + "github.com/aws/smithy-go/endpoints/private/rulesfn" + "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" + "github.com/aws/smithy-go/tracing" + smithyhttp "github.com/aws/smithy-go/transport/http" + "net/http" + "net/url" + "os" + "strings" +) + +// EndpointResolverOptions is the service endpoint resolver options +type EndpointResolverOptions = internalendpoints.Options + +// EndpointResolver interface for resolving service endpoints. +type EndpointResolver interface { + ResolveEndpoint(region string, options EndpointResolverOptions) (aws.Endpoint, error) +} + +var _ EndpointResolver = &internalendpoints.Resolver{} + +// NewDefaultEndpointResolver constructs a new service endpoint resolver +func NewDefaultEndpointResolver() *internalendpoints.Resolver { + return internalendpoints.New() +} + +// EndpointResolverFunc is a helper utility that wraps a function so it satisfies +// the EndpointResolver interface. This is useful when you want to add additional +// endpoint resolving logic, or stub out specific endpoints with custom values. +type EndpointResolverFunc func(region string, options EndpointResolverOptions) (aws.Endpoint, error) + +func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { + return fn(region, options) +} + +// EndpointResolverFromURL returns an EndpointResolver configured using the +// provided endpoint url. By default, the resolved endpoint resolver uses the +// client region as signing region, and the endpoint source is set to +// EndpointSourceCustom.You can provide functional options to configure endpoint +// values for the resolved endpoint. +func EndpointResolverFromURL(url string, optFns ...func(*aws.Endpoint)) EndpointResolver { + e := aws.Endpoint{URL: url, Source: aws.EndpointSourceCustom} + for _, fn := range optFns { + fn(&e) + } + + return EndpointResolverFunc( + func(region string, options EndpointResolverOptions) (aws.Endpoint, error) { + if len(e.SigningRegion) == 0 { + e.SigningRegion = region + } + return e, nil + }, + ) +} + +type ResolveEndpoint struct { + Resolver EndpointResolver + Options EndpointResolverOptions +} + +func (*ResolveEndpoint) ID() string { + return "ResolveEndpoint" +} + +func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) { + return next.HandleSerialize(ctx, in) + } + + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.Resolver == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + eo := m.Options + eo.Logger = middleware.GetLogger(ctx) + + var endpoint aws.Endpoint + endpoint, err = m.Resolver.ResolveEndpoint(awsmiddleware.GetRegion(ctx), eo) + if err != nil { + nf := (&aws.EndpointNotFoundError{}) + if errors.As(err, &nf) { + ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, false) + return next.HandleSerialize(ctx, in) + } + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + req.URL, err = url.Parse(endpoint.URL) + if err != nil { + return out, metadata, fmt.Errorf("failed to parse endpoint URL: %w", err) + } + + if len(awsmiddleware.GetSigningName(ctx)) == 0 { + signingName := endpoint.SigningName + if len(signingName) == 0 { + signingName = "signin" + } + ctx = awsmiddleware.SetSigningName(ctx, signingName) + } + ctx = awsmiddleware.SetEndpointSource(ctx, endpoint.Source) + ctx = smithyhttp.SetHostnameImmutable(ctx, endpoint.HostnameImmutable) + ctx = awsmiddleware.SetSigningRegion(ctx, endpoint.SigningRegion) + ctx = awsmiddleware.SetPartitionID(ctx, endpoint.PartitionID) + return next.HandleSerialize(ctx, in) +} +func addResolveEndpointMiddleware(stack *middleware.Stack, o Options) error { + return stack.Serialize.Insert(&ResolveEndpoint{ + Resolver: o.EndpointResolver, + Options: o.EndpointOptions, + }, "OperationSerializer", middleware.Before) +} + +func removeResolveEndpointMiddleware(stack *middleware.Stack) error { + _, err := stack.Serialize.Remove((&ResolveEndpoint{}).ID()) + return err +} + +type wrappedEndpointResolver struct { + awsResolver aws.EndpointResolverWithOptions +} + +func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { + return w.awsResolver.ResolveEndpoint(ServiceID, region, options) +} + +type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error) + +func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, options ...interface{}) (aws.Endpoint, error) { + return a(service, region) +} + +var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil) + +// withEndpointResolver returns an aws.EndpointResolverWithOptions that first delegates endpoint resolution to the awsResolver. +// If awsResolver returns aws.EndpointNotFoundError error, the v1 resolver middleware will swallow the error, +// and set an appropriate context flag such that fallback will occur when EndpointResolverV2 is invoked +// via its middleware. +// +// If another error (besides aws.EndpointNotFoundError) is returned, then that error will be propagated. +func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions) EndpointResolver { + var resolver aws.EndpointResolverWithOptions + + if awsResolverWithOptions != nil { + resolver = awsResolverWithOptions + } else if awsResolver != nil { + resolver = awsEndpointResolverAdaptor(awsResolver.ResolveEndpoint) + } + + return &wrappedEndpointResolver{ + awsResolver: resolver, + } +} + +func finalizeClientEndpointResolverOptions(options *Options) { + options.EndpointOptions.LogDeprecated = options.ClientLogMode.IsDeprecatedUsage() + + if len(options.EndpointOptions.ResolvedRegion) == 0 { + const fipsInfix = "-fips-" + const fipsPrefix = "fips-" + const fipsSuffix = "-fips" + + if strings.Contains(options.Region, fipsInfix) || + strings.Contains(options.Region, fipsPrefix) || + strings.Contains(options.Region, fipsSuffix) { + options.EndpointOptions.ResolvedRegion = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll( + options.Region, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "") + options.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled + } + } + +} + +func resolveEndpointResolverV2(options *Options) { + if options.EndpointResolverV2 == nil { + options.EndpointResolverV2 = NewDefaultEndpointResolverV2() + } +} + +func resolveBaseEndpoint(cfg aws.Config, o *Options) { + if cfg.BaseEndpoint != nil { + o.BaseEndpoint = cfg.BaseEndpoint + } + + _, g := os.LookupEnv("AWS_ENDPOINT_URL") + _, s := os.LookupEnv("AWS_ENDPOINT_URL_SIGNIN") + + if g && !s { + return + } + + value, found, err := internalConfig.ResolveServiceBaseEndpoint(context.Background(), "Signin", cfg.ConfigSources) + if found && err == nil { + o.BaseEndpoint = &value + } +} + +func bindRegion(region string) (*string, error) { + if region == "" { + return nil, nil + } + if !rulesfn.IsValidHostLabel(region, true) { + return nil, fmt.Errorf("invalid input region %s", region) + } + + return aws.String(endpoints.MapFIPSRegion(region)), nil +} + +// EndpointParameters provides the parameters that influence how endpoints are +// resolved. +type EndpointParameters struct { + // When true, use the dual-stack endpoint. If the configured endpoint does not + // support dual-stack, dispatching the request MAY return an error. + // + // Defaults to + // false if no value is provided. + // + // AWS::UseDualStack + UseDualStack *bool + + // When true, send this request to the FIPS-compliant regional endpoint. If the + // configured endpoint does not have a FIPS compliant endpoint, dispatching the + // request will return an error. + // + // Defaults to false if no value is + // provided. + // + // AWS::UseFIPS + UseFIPS *bool + + // Override the endpoint used to send this request + // + // Parameter is + // required. + // + // SDK::Endpoint + Endpoint *string + + // The AWS region used to dispatch the request. + // + // Parameter is + // required. + // + // AWS::Region + Region *string +} + +// ValidateRequired validates required parameters are set. +func (p EndpointParameters) ValidateRequired() error { + if p.UseDualStack == nil { + return fmt.Errorf("parameter UseDualStack is required") + } + + if p.UseFIPS == nil { + return fmt.Errorf("parameter UseFIPS is required") + } + + return nil +} + +// WithDefaults returns a shallow copy of EndpointParameterswith default values +// applied to members where applicable. +func (p EndpointParameters) WithDefaults() EndpointParameters { + if p.UseDualStack == nil { + p.UseDualStack = ptr.Bool(false) + } + + if p.UseFIPS == nil { + p.UseFIPS = ptr.Bool(false) + } + return p +} + +type stringSlice []string + +func (s stringSlice) Get(i int) *string { + if i < 0 || i >= len(s) { + return nil + } + + v := s[i] + return &v +} + +// EndpointResolverV2 provides the interface for resolving service endpoints. +type EndpointResolverV2 interface { + // ResolveEndpoint attempts to resolve the endpoint with the provided options, + // returning the endpoint if found. Otherwise an error is returned. + ResolveEndpoint(ctx context.Context, params EndpointParameters) ( + smithyendpoints.Endpoint, error, + ) +} + +// resolver provides the implementation for resolving endpoints. +type resolver struct{} + +func NewDefaultEndpointResolverV2() EndpointResolverV2 { + return &resolver{} +} + +// ResolveEndpoint attempts to resolve the endpoint with the provided options, +// returning the endpoint if found. Otherwise an error is returned. +func (r *resolver) ResolveEndpoint( + ctx context.Context, params EndpointParameters, +) ( + endpoint smithyendpoints.Endpoint, err error, +) { + params = params.WithDefaults() + if err = params.ValidateRequired(); err != nil { + return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err) + } + _UseDualStack := *params.UseDualStack + _ = _UseDualStack + _UseFIPS := *params.UseFIPS + _ = _UseFIPS + + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if _UseFIPS == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and custom endpoint are not supported") + } + if _UseDualStack == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and custom endpoint are not supported") + } + uriString := _Endpoint + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + if exprVal := params.Region; exprVal != nil { + _Region := *exprVal + _ = _Region + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _PartitionResult := *exprVal + _ = _PartitionResult + if _PartitionResult.Name == "aws" { + if _UseFIPS == false { + if _UseDualStack == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Region) + out.WriteString(".signin.aws.amazon.com") + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + } + } + if _PartitionResult.Name == "aws-cn" { + if _UseFIPS == false { + if _UseDualStack == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Region) + out.WriteString(".signin.amazonaws.cn") + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + } + } + if _PartitionResult.Name == "aws-us-gov" { + if _UseFIPS == false { + if _UseDualStack == false { + uriString := func() string { + var out strings.Builder + out.WriteString("https://") + out.WriteString(_Region) + out.WriteString(".signin.amazonaws-us-gov.com") + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + } + } + if _UseFIPS == true { + if _UseDualStack == true { + if true == _PartitionResult.SupportsFIPS { + if true == _PartitionResult.SupportsDualStack { + uriString := func() string { + var out strings.Builder + out.WriteString("https://signin-fips.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_PartitionResult.DualStackDnsSuffix) + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both") + } + } + if _UseFIPS == true { + if _UseDualStack == false { + if _PartitionResult.SupportsFIPS == true { + uriString := func() string { + var out strings.Builder + out.WriteString("https://signin-fips.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_PartitionResult.DnsSuffix) + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS is enabled but this partition does not support FIPS") + } + } + if _UseFIPS == false { + if _UseDualStack == true { + if true == _PartitionResult.SupportsDualStack { + uriString := func() string { + var out strings.Builder + out.WriteString("https://signin.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_PartitionResult.DualStackDnsSuffix) + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "DualStack is enabled but this partition does not support DualStack") + } + } + uriString := func() string { + var out strings.Builder + out.WriteString("https://signin.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_PartitionResult.DnsSuffix) + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Missing Region") +} + +type endpointParamsBinder interface { + bindEndpointParams(*EndpointParameters) +} + +func bindEndpointParams(ctx context.Context, input interface{}, options Options) (*EndpointParameters, error) { + params := &EndpointParameters{} + + params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled) + params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled) + params.Endpoint = options.BaseEndpoint + region, err := bindRegion(options.Region) + if err != nil { + return nil, err + } + params.Region = region + + if b, ok := input.(endpointParamsBinder); ok { + b.bindEndpointParams(params) + } + + return params, nil +} + +type resolveEndpointV2Middleware struct { + options Options +} + +func (*resolveEndpointV2Middleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + _, span := tracing.StartSpan(ctx, "ResolveEndpoint") + defer span.End() + + if awsmiddleware.GetRequiresLegacyEndpoints(ctx) { + return next.HandleFinalize(ctx, in) + } + + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.options.EndpointResolverV2 == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params, err := bindEndpointParams(ctx, getOperationInput(ctx), m.options) + if err != nil { + return out, metadata, fmt.Errorf("failed to bind endpoint params, %w", err) + } + endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration", + func() (smithyendpoints.Endpoint, error) { + return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params) + }) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + span.SetProperty("client.call.resolved_endpoint", endpt.URI.String()) + + if endpt.URI.RawPath == "" && req.URL.RawPath != "" { + endpt.URI.RawPath = endpt.URI.Path + } + req.URL.Scheme = endpt.URI.Scheme + req.URL.Host = endpt.URI.Host + req.URL.Path = smithyhttp.JoinPath(endpt.URI.Path, req.URL.Path) + req.URL.RawPath = smithyhttp.JoinPath(endpt.URI.RawPath, req.URL.RawPath) + for k := range endpt.Headers { + req.Header.Set(k, endpt.Headers.Get(k)) + } + + rscheme := getResolvedAuthScheme(ctx) + if rscheme == nil { + return out, metadata, fmt.Errorf("no resolved auth scheme") + } + + opts, _ := smithyauth.GetAuthOptions(&endpt.Properties) + for _, o := range opts { + rscheme.SignerProperties.SetAll(&o.SignerProperties) + } + + span.End() + return next.HandleFinalize(ctx, in) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/generated.json new file mode 100644 index 0000000000..8014c56167 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/generated.json @@ -0,0 +1,34 @@ +{ + "dependencies": { + "github.com/aws/aws-sdk-go-v2": "v1.4.0", + "github.com/aws/aws-sdk-go-v2/internal/configsources": "v0.0.0-00010101000000-000000000000", + "github.com/aws/aws-sdk-go-v2/internal/endpoints/v2": "v2.0.0-00010101000000-000000000000", + "github.com/aws/smithy-go": "v1.4.0" + }, + "files": [ + "api_client.go", + "api_client_test.go", + "api_op_CreateOAuth2Token.go", + "auth.go", + "deserializers.go", + "doc.go", + "endpoints.go", + "endpoints_config_test.go", + "endpoints_test.go", + "generated.json", + "internal/endpoints/endpoints.go", + "internal/endpoints/endpoints_test.go", + "options.go", + "protocol_test.go", + "serializers.go", + "snapshot_test.go", + "sra_operation_order_test.go", + "types/enums.go", + "types/errors.go", + "types/types.go", + "validators.go" + ], + "go": "1.23", + "module": "github.com/aws/aws-sdk-go-v2/service/signin", + "unstable": false +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/go_module_metadata.go new file mode 100644 index 0000000000..4b1b814d13 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/go_module_metadata.go @@ -0,0 +1,6 @@ +// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. + +package signin + +// goModuleVersion is the tagged release for this module +const goModuleVersion = "1.0.2" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/internal/endpoints/endpoints.go new file mode 100644 index 0000000000..cfb2efea8a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/internal/endpoints/endpoints.go @@ -0,0 +1,333 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package endpoints + +import ( + "github.com/aws/aws-sdk-go-v2/aws" + endpoints "github.com/aws/aws-sdk-go-v2/internal/endpoints/v2" + "github.com/aws/smithy-go/logging" + "regexp" +) + +// Options is the endpoint resolver configuration options +type Options struct { + // Logger is a logging implementation that log events should be sent to. + Logger logging.Logger + + // LogDeprecated indicates that deprecated endpoints should be logged to the + // provided logger. + LogDeprecated bool + + // ResolvedRegion is used to override the region to be resolved, rather then the + // using the value passed to the ResolveEndpoint method. This value is used by the + // SDK to translate regions like fips-us-east-1 or us-east-1-fips to an alternative + // name. You must not set this value directly in your application. + ResolvedRegion string + + // DisableHTTPS informs the resolver to return an endpoint that does not use the + // HTTPS scheme. + DisableHTTPS bool + + // UseDualStackEndpoint specifies the resolver must resolve a dual-stack endpoint. + UseDualStackEndpoint aws.DualStackEndpointState + + // UseFIPSEndpoint specifies the resolver must resolve a FIPS endpoint. + UseFIPSEndpoint aws.FIPSEndpointState +} + +func (o Options) GetResolvedRegion() string { + return o.ResolvedRegion +} + +func (o Options) GetDisableHTTPS() bool { + return o.DisableHTTPS +} + +func (o Options) GetUseDualStackEndpoint() aws.DualStackEndpointState { + return o.UseDualStackEndpoint +} + +func (o Options) GetUseFIPSEndpoint() aws.FIPSEndpointState { + return o.UseFIPSEndpoint +} + +func transformToSharedOptions(options Options) endpoints.Options { + return endpoints.Options{ + Logger: options.Logger, + LogDeprecated: options.LogDeprecated, + ResolvedRegion: options.ResolvedRegion, + DisableHTTPS: options.DisableHTTPS, + UseDualStackEndpoint: options.UseDualStackEndpoint, + UseFIPSEndpoint: options.UseFIPSEndpoint, + } +} + +// Resolver Signin endpoint resolver +type Resolver struct { + partitions endpoints.Partitions +} + +// ResolveEndpoint resolves the service endpoint for the given region and options +func (r *Resolver) ResolveEndpoint(region string, options Options) (endpoint aws.Endpoint, err error) { + if len(region) == 0 { + return endpoint, &aws.MissingRegionError{} + } + + opt := transformToSharedOptions(options) + return r.partitions.ResolveEndpoint(region, opt) +} + +// New returns a new Resolver +func New() *Resolver { + return &Resolver{ + partitions: defaultPartitions, + } +} + +var partitionRegexp = struct { + Aws *regexp.Regexp + AwsCn *regexp.Regexp + AwsEusc *regexp.Regexp + AwsIso *regexp.Regexp + AwsIsoB *regexp.Regexp + AwsIsoE *regexp.Regexp + AwsIsoF *regexp.Regexp + AwsUsGov *regexp.Regexp +}{ + + Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il|mx)\\-\\w+\\-\\d+$"), + AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"), + AwsEusc: regexp.MustCompile("^eusc\\-(de)\\-\\w+\\-\\d+$"), + AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"), + AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"), + AwsIsoE: regexp.MustCompile("^eu\\-isoe\\-\\w+\\-\\d+$"), + AwsIsoF: regexp.MustCompile("^us\\-isof\\-\\w+\\-\\d+$"), + AwsUsGov: regexp.MustCompile("^us\\-gov\\-\\w+\\-\\d+$"), +} + +var defaultPartitions = endpoints.Partitions{ + { + ID: "aws", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.DualStackVariant, + }: { + Hostname: "signin.{region}.api.aws", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "signin-fips.{region}.amazonaws.com", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, + }: { + Hostname: "signin-fips.{region}.api.aws", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "signin.{region}.amazonaws.com", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + RegionRegex: partitionRegexp.Aws, + IsRegionalized: true, + }, + { + ID: "aws-cn", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.DualStackVariant, + }: { + Hostname: "signin.{region}.api.amazonwebservices.com.cn", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "signin-fips.{region}.amazonaws.com.cn", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, + }: { + Hostname: "signin-fips.{region}.api.amazonwebservices.com.cn", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "signin.{region}.amazonaws.com.cn", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + RegionRegex: partitionRegexp.AwsCn, + IsRegionalized: true, + }, + { + ID: "aws-eusc", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.DualStackVariant, + }: { + Hostname: "signin.{region}.api.amazonwebservices.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "signin-fips.{region}.amazonaws.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, + }: { + Hostname: "signin-fips.{region}.api.amazonwebservices.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "signin.{region}.amazonaws.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + RegionRegex: partitionRegexp.AwsEusc, + IsRegionalized: true, + }, + { + ID: "aws-iso", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "signin-fips.{region}.c2s.ic.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "signin.{region}.c2s.ic.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + RegionRegex: partitionRegexp.AwsIso, + IsRegionalized: true, + }, + { + ID: "aws-iso-b", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "signin-fips.{region}.sc2s.sgov.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "signin.{region}.sc2s.sgov.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + RegionRegex: partitionRegexp.AwsIsoB, + IsRegionalized: true, + }, + { + ID: "aws-iso-e", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "signin-fips.{region}.cloud.adc-e.uk", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "signin.{region}.cloud.adc-e.uk", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + RegionRegex: partitionRegexp.AwsIsoE, + IsRegionalized: true, + }, + { + ID: "aws-iso-f", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "signin-fips.{region}.csp.hci.ic.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "signin.{region}.csp.hci.ic.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + RegionRegex: partitionRegexp.AwsIsoF, + IsRegionalized: true, + }, + { + ID: "aws-us-gov", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.DualStackVariant, + }: { + Hostname: "signin.{region}.api.aws", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "signin-fips.{region}.amazonaws.com", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, + }: { + Hostname: "signin-fips.{region}.api.aws", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "signin.{region}.amazonaws.com", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + RegionRegex: partitionRegexp.AwsUsGov, + IsRegionalized: true, + }, +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/options.go new file mode 100644 index 0000000000..3262aa5822 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/options.go @@ -0,0 +1,239 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package signin + +import ( + "context" + "github.com/aws/aws-sdk-go-v2/aws" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" + smithyauth "github.com/aws/smithy-go/auth" + "github.com/aws/smithy-go/logging" + "github.com/aws/smithy-go/metrics" + "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/tracing" + smithyhttp "github.com/aws/smithy-go/transport/http" + "net/http" +) + +type HTTPClient interface { + Do(*http.Request) (*http.Response, error) +} + +type Options struct { + // Set of options to modify how an operation is invoked. These apply to all + // operations invoked for this client. Use functional options on operation call to + // modify this list for per operation behavior. + APIOptions []func(*middleware.Stack) error + + // The optional application specific identifier appended to the User-Agent header. + AppID string + + // This endpoint will be given as input to an EndpointResolverV2. It is used for + // providing a custom base endpoint that is subject to modifications by the + // processing EndpointResolverV2. + BaseEndpoint *string + + // Configures the events that will be sent to the configured logger. + ClientLogMode aws.ClientLogMode + + // The credentials object to use when signing requests. + Credentials aws.CredentialsProvider + + // The configuration DefaultsMode that the SDK should use when constructing the + // clients initial default settings. + DefaultsMode aws.DefaultsMode + + // The endpoint options to be used when attempting to resolve an endpoint. + EndpointOptions EndpointResolverOptions + + // The service endpoint resolver. + // + // Deprecated: Deprecated: EndpointResolver and WithEndpointResolver. Providing a + // value for this field will likely prevent you from using any endpoint-related + // service features released after the introduction of EndpointResolverV2 and + // BaseEndpoint. + // + // To migrate an EndpointResolver implementation that uses a custom endpoint, set + // the client option BaseEndpoint instead. + EndpointResolver EndpointResolver + + // Resolves the endpoint used for a particular service operation. This should be + // used over the deprecated EndpointResolver. + EndpointResolverV2 EndpointResolverV2 + + // Signature Version 4 (SigV4) Signer + HTTPSignerV4 HTTPSignerV4 + + // The logger writer interface to write logging messages to. + Logger logging.Logger + + // The client meter provider. + MeterProvider metrics.MeterProvider + + // The region to send requests to. (Required) + Region string + + // RetryMaxAttempts specifies the maximum number attempts an API client will call + // an operation that fails with a retryable error. A value of 0 is ignored, and + // will not be used to configure the API client created default retryer, or modify + // per operation call's retry max attempts. + // + // If specified in an operation call's functional options with a value that is + // different than the constructed client's Options, the Client's Retryer will be + // wrapped to use the operation's specific RetryMaxAttempts value. + RetryMaxAttempts int + + // RetryMode specifies the retry mode the API client will be created with, if + // Retryer option is not also specified. + // + // When creating a new API Clients this member will only be used if the Retryer + // Options member is nil. This value will be ignored if Retryer is not nil. + // + // Currently does not support per operation call overrides, may in the future. + RetryMode aws.RetryMode + + // Retryer guides how HTTP requests should be retried in case of recoverable + // failures. When nil the API client will use a default retryer. The kind of + // default retry created by the API client can be changed with the RetryMode + // option. + Retryer aws.Retryer + + // The RuntimeEnvironment configuration, only populated if the DefaultsMode is set + // to DefaultsModeAuto and is initialized using config.LoadDefaultConfig . You + // should not populate this structure programmatically, or rely on the values here + // within your applications. + RuntimeEnvironment aws.RuntimeEnvironment + + // The client tracer provider. + TracerProvider tracing.TracerProvider + + // The initial DefaultsMode used when the client options were constructed. If the + // DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved + // value was at that point in time. + // + // Currently does not support per operation call overrides, may in the future. + resolvedDefaultsMode aws.DefaultsMode + + // The HTTP client to invoke API calls with. Defaults to client's default HTTP + // implementation if nil. + HTTPClient HTTPClient + + // Client registry of operation interceptors. + Interceptors smithyhttp.InterceptorRegistry + + // The auth scheme resolver which determines how to authenticate for each + // operation. + AuthSchemeResolver AuthSchemeResolver + + // The list of auth schemes supported by the client. + AuthSchemes []smithyhttp.AuthScheme + + // Priority list of preferred auth scheme names (e.g. sigv4a). + AuthSchemePreference []string +} + +// Copy creates a clone where the APIOptions list is deep copied. +func (o Options) Copy() Options { + to := o + to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) + copy(to.APIOptions, o.APIOptions) + to.Interceptors = o.Interceptors.Copy() + + return to +} + +func (o Options) GetIdentityResolver(schemeID string) smithyauth.IdentityResolver { + if schemeID == "aws.auth#sigv4" { + return getSigV4IdentityResolver(o) + } + if schemeID == "smithy.api#noAuth" { + return &smithyauth.AnonymousIdentityResolver{} + } + return nil +} + +// WithAPIOptions returns a functional option for setting the Client's APIOptions +// option. +func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { + return func(o *Options) { + o.APIOptions = append(o.APIOptions, optFns...) + } +} + +// Deprecated: EndpointResolver and WithEndpointResolver. Providing a value for +// this field will likely prevent you from using any endpoint-related service +// features released after the introduction of EndpointResolverV2 and BaseEndpoint. +// +// To migrate an EndpointResolver implementation that uses a custom endpoint, set +// the client option BaseEndpoint instead. +func WithEndpointResolver(v EndpointResolver) func(*Options) { + return func(o *Options) { + o.EndpointResolver = v + } +} + +// WithEndpointResolverV2 returns a functional option for setting the Client's +// EndpointResolverV2 option. +func WithEndpointResolverV2(v EndpointResolverV2) func(*Options) { + return func(o *Options) { + o.EndpointResolverV2 = v + } +} + +func getSigV4IdentityResolver(o Options) smithyauth.IdentityResolver { + if o.Credentials != nil { + return &internalauthsmithy.CredentialsProviderAdapter{Provider: o.Credentials} + } + return nil +} + +// WithSigV4SigningName applies an override to the authentication workflow to +// use the given signing name for SigV4-authenticated operations. +// +// This is an advanced setting. The value here is FINAL, taking precedence over +// the resolved signing name from both auth scheme resolution and endpoint +// resolution. +func WithSigV4SigningName(name string) func(*Options) { + fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, + ) { + return next.HandleInitialize(awsmiddleware.SetSigningName(ctx, name), in) + } + return func(o *Options) { + o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { + return s.Initialize.Add( + middleware.InitializeMiddlewareFunc("withSigV4SigningName", fn), + middleware.Before, + ) + }) + } +} + +// WithSigV4SigningRegion applies an override to the authentication workflow to +// use the given signing region for SigV4-authenticated operations. +// +// This is an advanced setting. The value here is FINAL, taking precedence over +// the resolved signing region from both auth scheme resolution and endpoint +// resolution. +func WithSigV4SigningRegion(region string) func(*Options) { + fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, + ) { + return next.HandleInitialize(awsmiddleware.SetSigningRegion(ctx, region), in) + } + return func(o *Options) { + o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { + return s.Initialize.Add( + middleware.InitializeMiddlewareFunc("withSigV4SigningRegion", fn), + middleware.Before, + ) + }) + } +} + +func ignoreAnonymousAuth(options *Options) { + if aws.IsCredentialsProvider(options.Credentials, (*aws.AnonymousCredentials)(nil)) { + options.Credentials = nil + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/serializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/serializers.go new file mode 100644 index 0000000000..958240275e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/serializers.go @@ -0,0 +1,135 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package signin + +import ( + "bytes" + "context" + "fmt" + "github.com/aws/aws-sdk-go-v2/service/signin/types" + smithy "github.com/aws/smithy-go" + "github.com/aws/smithy-go/encoding/httpbinding" + smithyjson "github.com/aws/smithy-go/encoding/json" + "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/tracing" + smithyhttp "github.com/aws/smithy-go/transport/http" +) + +type awsRestjson1_serializeOpCreateOAuth2Token struct { +} + +func (*awsRestjson1_serializeOpCreateOAuth2Token) ID() string { + return "OperationSerializer" +} + +func (m *awsRestjson1_serializeOpCreateOAuth2Token) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + _, span := tracing.StartSpan(ctx, "OperationSerializer") + endTimer := startMetricTimer(ctx, "client.call.serialization_duration") + defer endTimer() + defer span.End() + request, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} + } + + input, ok := in.Parameters.(*CreateOAuth2TokenInput) + _ = input + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} + } + + opPath, opQuery := httpbinding.SplitURI("/v1/token") + request.URL.Path = smithyhttp.JoinPath(request.URL.Path, opPath) + request.URL.RawQuery = smithyhttp.JoinRawQuery(request.URL.RawQuery, opQuery) + request.Method = "POST" + var restEncoder *httpbinding.Encoder + if request.URL.RawPath == "" { + restEncoder, err = httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + } else { + request.URL.RawPath = smithyhttp.JoinPath(request.URL.RawPath, opPath) + restEncoder, err = httpbinding.NewEncoderWithRawPath(request.URL.Path, request.URL.RawPath, request.URL.RawQuery, request.Header) + } + + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if !restEncoder.HasHeader("Content-Type") { + ctx = smithyhttp.SetIsContentTypeDefaultValue(ctx, true) + restEncoder.SetHeader("Content-Type").String("application/json") + } + + if input.TokenInput != nil { + jsonEncoder := smithyjson.NewEncoder() + if err := awsRestjson1_serializeDocumentCreateOAuth2TokenRequestBody(input.TokenInput, jsonEncoder.Value); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + payload := bytes.NewReader(jsonEncoder.Bytes()) + if request, err = request.SetStream(payload); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + } else { + jsonEncoder := smithyjson.NewEncoder() + jsonEncoder.Value.Object().Close() + payload := bytes.NewReader(jsonEncoder.Bytes()) + if request, err = request.SetStream(payload); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + } + + if request.Request, err = restEncoder.Encode(request.Request); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + in.Request = request + + endTimer() + span.End() + return next.HandleSerialize(ctx, in) +} +func awsRestjson1_serializeOpHttpBindingsCreateOAuth2TokenInput(v *CreateOAuth2TokenInput, encoder *httpbinding.Encoder) error { + if v == nil { + return fmt.Errorf("unsupported serialization of nil %T", v) + } + + return nil +} + +func awsRestjson1_serializeDocumentCreateOAuth2TokenRequestBody(v *types.CreateOAuth2TokenRequestBody, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.ClientId != nil { + ok := object.Key("clientId") + ok.String(*v.ClientId) + } + + if v.Code != nil { + ok := object.Key("code") + ok.String(*v.Code) + } + + if v.CodeVerifier != nil { + ok := object.Key("codeVerifier") + ok.String(*v.CodeVerifier) + } + + if v.GrantType != nil { + ok := object.Key("grantType") + ok.String(*v.GrantType) + } + + if v.RedirectUri != nil { + ok := object.Key("redirectUri") + ok.String(*v.RedirectUri) + } + + if v.RefreshToken != nil { + ok := object.Key("refreshToken") + ok.String(*v.RefreshToken) + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/enums.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/enums.go new file mode 100644 index 0000000000..ecfabb81f7 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/enums.go @@ -0,0 +1,37 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package types + +type OAuth2ErrorCode string + +// Enum values for OAuth2ErrorCode +const ( + // Token has expired and needs to be refreshed + OAuth2ErrorCodeTokenExpired OAuth2ErrorCode = "TOKEN_EXPIRED" + // User credentials have been changed + OAuth2ErrorCodeUserCredentialsChanged OAuth2ErrorCode = "USER_CREDENTIALS_CHANGED" + // Insufficient permissions to perform this operation + OAuth2ErrorCodeInsufficientPermissions OAuth2ErrorCode = "INSUFFICIENT_PERMISSIONS" + // Authorization code has expired + OAuth2ErrorCodeAuthcodeExpired OAuth2ErrorCode = "AUTHCODE_EXPIRED" + // Internal server error occurred + OAuth2ErrorCodeServerError OAuth2ErrorCode = "server_error" + // The request is missing a required parameter, includes an invalid parameter + // value, or is otherwise malformed + OAuth2ErrorCodeInvalidRequest OAuth2ErrorCode = "INVALID_REQUEST" +) + +// Values returns all known values for OAuth2ErrorCode. Note that this can be +// expanded in the future, and so it is only as up to date as the client. +// +// The ordering of this slice is not guaranteed to be stable across updates. +func (OAuth2ErrorCode) Values() []OAuth2ErrorCode { + return []OAuth2ErrorCode{ + "TOKEN_EXPIRED", + "USER_CREDENTIALS_CHANGED", + "INSUFFICIENT_PERMISSIONS", + "AUTHCODE_EXPIRED", + "server_error", + "INVALID_REQUEST", + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/errors.go new file mode 100644 index 0000000000..ca4928a86c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/errors.go @@ -0,0 +1,151 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package types + +import ( + "fmt" + smithy "github.com/aws/smithy-go" +) + +// Error thrown for access denied scenarios with flexible HTTP status mapping +// +// Runtime HTTP Status Code Mapping: +// +// - HTTP 401 (Unauthorized): TOKEN_EXPIRED, AUTHCODE_EXPIRED +// - HTTP 403 (Forbidden): USER_CREDENTIALS_CHANGED, INSUFFICIENT_PERMISSIONS +// +// The specific HTTP status code is determined at runtime based on the error enum +// value. Consumers should use the error field to determine the specific access +// denial reason. +type AccessDeniedException struct { + Message *string + + ErrorCodeOverride *string + + Error_ OAuth2ErrorCode + + noSmithyDocumentSerde +} + +func (e *AccessDeniedException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *AccessDeniedException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *AccessDeniedException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "AccessDeniedException" + } + return *e.ErrorCodeOverride +} +func (e *AccessDeniedException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } + +// Error thrown when an internal server error occurs +// +// HTTP Status Code: 500 Internal Server Error +// +// Used for unexpected server-side errors that prevent request processing. +type InternalServerException struct { + Message *string + + ErrorCodeOverride *string + + Error_ OAuth2ErrorCode + + noSmithyDocumentSerde +} + +func (e *InternalServerException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *InternalServerException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *InternalServerException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "InternalServerException" + } + return *e.ErrorCodeOverride +} +func (e *InternalServerException) ErrorFault() smithy.ErrorFault { return smithy.FaultServer } + +// Error thrown when rate limit is exceeded +// +// HTTP Status Code: 429 Too Many Requests +// +// Possible OAuth2ErrorCode values: +// +// - INVALID_REQUEST: Rate limiting, too many requests, abuse prevention +// +// Possible causes: +// +// - Too many token requests from the same client +// - Rate limiting based on client_id or IP address +// - Abuse prevention mechanisms triggered +// - Service protection against excessive token generation +type TooManyRequestsError struct { + Message *string + + ErrorCodeOverride *string + + Error_ OAuth2ErrorCode + + noSmithyDocumentSerde +} + +func (e *TooManyRequestsError) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *TooManyRequestsError) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *TooManyRequestsError) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "TooManyRequestsError" + } + return *e.ErrorCodeOverride +} +func (e *TooManyRequestsError) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } + +// Error thrown when request validation fails +// +// HTTP Status Code: 400 Bad Request +// +// Used for request validation errors such as malformed parameters, missing +// required fields, or invalid parameter values. +type ValidationException struct { + Message *string + + ErrorCodeOverride *string + + Error_ OAuth2ErrorCode + + noSmithyDocumentSerde +} + +func (e *ValidationException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *ValidationException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *ValidationException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "ValidationException" + } + return *e.ErrorCodeOverride +} +func (e *ValidationException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/types.go new file mode 100644 index 0000000000..98afa20bfc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/types/types.go @@ -0,0 +1,115 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package types + +import ( + smithydocument "github.com/aws/smithy-go/document" +) + +// AWS credentials structure containing temporary access credentials +// +// The scoped-down, 15 minute duration AWS credentials. Scoping down will be based +// on CLI policy (CLI team needs to create it). Similar to cloud shell +// implementation. +type AccessToken struct { + + // AWS access key ID for temporary credentials + // + // This member is required. + AccessKeyId *string + + // AWS secret access key for temporary credentials + // + // This member is required. + SecretAccessKey *string + + // AWS session token for temporary credentials + // + // This member is required. + SessionToken *string + + noSmithyDocumentSerde +} + +// Request body payload for CreateOAuth2Token operation +// +// The operation type is determined by the grant_type parameter: +// +// - grant_type=authorization_code: Requires code, redirect_uri, code_verifier +// - grant_type=refresh_token: Requires refresh_token +type CreateOAuth2TokenRequestBody struct { + + // The client identifier (ARN) used during Sign-In onboarding Required for both + // authorization code and refresh token flows + // + // This member is required. + ClientId *string + + // OAuth 2.0 grant type - determines which flow is used Must be + // "authorization_code" or "refresh_token" + // + // This member is required. + GrantType *string + + // The authorization code received from /v1/authorize Required only when + // grant_type=authorization_code + Code *string + + // PKCE code verifier to prove possession of the original code challenge Required + // only when grant_type=authorization_code + CodeVerifier *string + + // The redirect URI that must match the original authorization request Required + // only when grant_type=authorization_code + RedirectUri *string + + // The refresh token returned from auth_code redemption Required only when + // grant_type=refresh_token + RefreshToken *string + + noSmithyDocumentSerde +} + +// Response body payload for CreateOAuth2Token operation +// +// The response content depends on the grant_type from the request: +// +// - grant_type=authorization_code: Returns all fields including refresh_token +// and id_token +// - grant_type=refresh_token: Returns access_token, token_type, expires_in, +// refresh_token (no id_token) +type CreateOAuth2TokenResponseBody struct { + + // Scoped-down AWS credentials (15 minute duration) Present for both authorization + // code redemption and token refresh + // + // This member is required. + AccessToken *AccessToken + + // Time to expiry in seconds (maximum 900) Present for both authorization code + // redemption and token refresh + // + // This member is required. + ExpiresIn *int32 + + // Encrypted refresh token with cnf.jkt (SHA-256 thumbprint of presented jwk) + // Always present in responses (required for both flows) + // + // This member is required. + RefreshToken *string + + // Token type indicating this is AWS SigV4 credentials Value is "aws_sigv4" for + // both flows + // + // This member is required. + TokenType *string + + // ID token containing user identity information Present only in authorization + // code redemption response (grant_type=authorization_code) Not included in token + // refresh responses + IdToken *string + + noSmithyDocumentSerde +} + +type noSmithyDocumentSerde = smithydocument.NoSerde diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/signin/validators.go b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/validators.go new file mode 100644 index 0000000000..f07252341a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/signin/validators.go @@ -0,0 +1,72 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package signin + +import ( + "context" + "fmt" + "github.com/aws/aws-sdk-go-v2/service/signin/types" + smithy "github.com/aws/smithy-go" + "github.com/aws/smithy-go/middleware" +) + +type validateOpCreateOAuth2Token struct { +} + +func (*validateOpCreateOAuth2Token) ID() string { + return "OperationInputValidation" +} + +func (m *validateOpCreateOAuth2Token) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + input, ok := in.Parameters.(*CreateOAuth2TokenInput) + if !ok { + return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) + } + if err := validateOpCreateOAuth2TokenInput(input); err != nil { + return out, metadata, err + } + return next.HandleInitialize(ctx, in) +} + +func addOpCreateOAuth2TokenValidationMiddleware(stack *middleware.Stack) error { + return stack.Initialize.Add(&validateOpCreateOAuth2Token{}, middleware.After) +} + +func validateCreateOAuth2TokenRequestBody(v *types.CreateOAuth2TokenRequestBody) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "CreateOAuth2TokenRequestBody"} + if v.ClientId == nil { + invalidParams.Add(smithy.NewErrParamRequired("ClientId")) + } + if v.GrantType == nil { + invalidParams.Add(smithy.NewErrParamRequired("GrantType")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + +func validateOpCreateOAuth2TokenInput(v *CreateOAuth2TokenInput) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "CreateOAuth2TokenInput"} + if v.TokenInput == nil { + invalidParams.Add(smithy.NewErrParamRequired("TokenInput")) + } else if v.TokenInput != nil { + if err := validateCreateOAuth2TokenRequestBody(v.TokenInput); err != nil { + invalidParams.AddNested("TokenInput", err.(smithy.InvalidParamsError)) + } + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/CHANGELOG.md index 928ffc3901..4c047bfd3d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/CHANGELOG.md @@ -1,3 +1,109 @@ +# v1.30.5 (2025-11-25) + +* **Bug Fix**: Add error check for endpoint param binding during auth scheme resolution to fix panic reported in #3234 + +# v1.30.4 (2025-11-19.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.30.3 (2025-11-12) + +* **Bug Fix**: Further reduce allocation overhead when the metrics system isn't in-use. +* **Bug Fix**: Reduce allocation overhead when the client doesn't have any HTTP interceptors configured. +* **Bug Fix**: Remove blank trace spans towards the beginning of the request that added no additional information. This conveys a slight reduction in overall allocations. + +# v1.30.2 (2025-11-11) + +* **Bug Fix**: Return validation error if input region is not a valid host label. + +# v1.30.1 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.30.0 (2025-10-30) + +* **Feature**: Update endpoint ruleset parameters casing +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.29.8 (2025-10-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.29.7 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.29.6 (2025-09-29) + +* No change notes available for this release. + +# v1.29.5 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.29.4 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.29.3 (2025-09-10) + +* No change notes available for this release. + +# v1.29.2 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.29.1 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.29.0 (2025-08-28) + +* **Feature**: Remove incorrect endpoint tests + +# v1.28.3 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.28.2 (2025-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.28.1 (2025-08-20) + +* **Bug Fix**: Remove unused deserialization code. + +# v1.28.0 (2025-08-11) + +* **Feature**: Add support for configuring per-service Options via callback on global config. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.27.0 (2025-08-04) + +* **Feature**: Support configurable auth scheme preferences in service clients via AWS_AUTH_SCHEME_PREFERENCE in the environment, auth_scheme_preference in the config file, and through in-code settings on LoadDefaultConfig and client constructor methods. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.26.1 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.26.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.25.6 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.25.5 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + # v1.25.4 (2025-06-10) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_client.go index 9f10e65ad7..8e5a2e77f8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_client.go @@ -65,7 +65,12 @@ func timeOperationMetric[T any]( ctx context.Context, metric string, fn func() (T, error), opts ...metrics.RecordMetricOption, ) (T, error) { - instr := getOperationMetrics(ctx).histogramFor(metric) + mm := getOperationMetrics(ctx) + if mm == nil { // not using the metrics system + return fn() + } + + instr := mm.histogramFor(metric) opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) start := time.Now() @@ -78,7 +83,12 @@ func timeOperationMetric[T any]( } func startMetricTimer(ctx context.Context, metric string, opts ...metrics.RecordMetricOption) func() { - instr := getOperationMetrics(ctx).histogramFor(metric) + mm := getOperationMetrics(ctx) + if mm == nil { // not using the metrics system + return func() {} + } + + instr := mm.histogramFor(metric) opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) var ended bool @@ -106,6 +116,12 @@ func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption { type operationMetricsKey struct{} func withOperationMetrics(parent context.Context, mp metrics.MeterProvider) (context.Context, error) { + if _, ok := mp.(metrics.NopMeterProvider); ok { + // not using the metrics system - setting up the metrics context is a memory-intensive operation + // so we should skip it in this case + return parent, nil + } + meter := mp.Meter("github.com/aws/aws-sdk-go-v2/service/sso") om := &operationMetrics{} @@ -153,7 +169,10 @@ func operationMetricTimer(m metrics.Meter, name, desc string) (metrics.Float64Hi } func getOperationMetrics(ctx context.Context) *operationMetrics { - return ctx.Value(operationMetricsKey{}).(*operationMetrics) + if v := ctx.Value(operationMetricsKey{}); v != nil { + return v.(*operationMetrics) + } + return nil } func operationTracer(p tracing.TracerProvider) tracing.Tracer { @@ -419,24 +438,33 @@ func setResolvedDefaultsMode(o *Options) { // NewFromConfig returns a new client from the provided config. func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, + Region: cfg.Region, + DefaultsMode: cfg.DefaultsMode, + RuntimeEnvironment: cfg.RuntimeEnvironment, + HTTPClient: cfg.HTTPClient, + Credentials: cfg.Credentials, + APIOptions: cfg.APIOptions, + Logger: cfg.Logger, + ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, + AuthSchemePreference: cfg.AuthSchemePreference, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) resolveAWSRetryMode(cfg, &opts) resolveAWSEndpointResolver(cfg, &opts) + resolveInterceptors(cfg, &opts) resolveUseDualStackEndpoint(cfg, &opts) resolveUseFIPSEndpoint(cfg, &opts) resolveBaseEndpoint(cfg, &opts) - return New(opts, optFns...) + return New(opts, func(o *Options) { + for _, opt := range cfg.ServiceOptions { + opt(ServiceID, o) + } + for _, opt := range optFns { + opt(o) + } + }) } func resolveHTTPClient(o *Options) { @@ -550,6 +578,10 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } +func resolveInterceptors(cfg aws.Config, o *Options) { + o.Interceptors = cfg.Interceptors.Copy() +} + func addClientUserAgent(stack *middleware.Stack, options Options) error { ua, err := getOrAddRequestUserAgent(stack) if err != nil { @@ -856,88 +888,62 @@ func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { }, "ResolveEndpointV2", middleware.After) } -type spanInitializeStart struct { -} - -func (*spanInitializeStart) ID() string { - return "spanInitializeStart" -} - -func (m *spanInitializeStart) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - middleware.InitializeOutput, middleware.Metadata, error, -) { - ctx, _ = tracing.StartSpan(ctx, "Initialize") - - return next.HandleInitialize(ctx, in) -} - -type spanInitializeEnd struct { -} - -func (*spanInitializeEnd) ID() string { - return "spanInitializeEnd" -} - -func (m *spanInitializeEnd) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - middleware.InitializeOutput, middleware.Metadata, error, -) { - ctx, span := tracing.PopSpan(ctx) - span.End() - - return next.HandleInitialize(ctx, in) -} - -type spanBuildRequestStart struct { -} - -func (*spanBuildRequestStart) ID() string { - return "spanBuildRequestStart" -} - -func (m *spanBuildRequestStart) HandleSerialize( - ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, -) ( - middleware.SerializeOutput, middleware.Metadata, error, -) { - ctx, _ = tracing.StartSpan(ctx, "BuildRequest") - - return next.HandleSerialize(ctx, in) -} - -type spanBuildRequestEnd struct { -} - -func (*spanBuildRequestEnd) ID() string { - return "spanBuildRequestEnd" -} - -func (m *spanBuildRequestEnd) HandleBuild( - ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler, -) ( - middleware.BuildOutput, middleware.Metadata, error, -) { - ctx, span := tracing.PopSpan(ctx) - span.End() - - return next.HandleBuild(ctx, in) -} - -func addSpanInitializeStart(stack *middleware.Stack) error { - return stack.Initialize.Add(&spanInitializeStart{}, middleware.Before) -} - -func addSpanInitializeEnd(stack *middleware.Stack) error { - return stack.Initialize.Add(&spanInitializeEnd{}, middleware.After) -} - -func addSpanBuildRequestStart(stack *middleware.Stack) error { - return stack.Serialize.Add(&spanBuildRequestStart{}, middleware.Before) -} +func addInterceptBeforeRetryLoop(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptBeforeRetryLoop{ + Interceptors: opts.Interceptors.BeforeRetryLoop, + }, "Retry", middleware.Before) +} + +func addInterceptAttempt(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptAttempt{ + BeforeAttempt: opts.Interceptors.BeforeAttempt, + AfterAttempt: opts.Interceptors.AfterAttempt, + }, "Retry", middleware.After) +} + +func addInterceptors(stack *middleware.Stack, opts Options) error { + // middlewares are expensive, don't add all of these interceptor ones unless the caller + // actually has at least one interceptor configured + // + // at the moment it's all-or-nothing because some of the middlewares here are responsible for + // setting fields in the interceptor context for future ones + if len(opts.Interceptors.BeforeExecution) == 0 && + len(opts.Interceptors.BeforeSerialization) == 0 && len(opts.Interceptors.AfterSerialization) == 0 && + len(opts.Interceptors.BeforeRetryLoop) == 0 && + len(opts.Interceptors.BeforeAttempt) == 0 && + len(opts.Interceptors.BeforeSigning) == 0 && len(opts.Interceptors.AfterSigning) == 0 && + len(opts.Interceptors.BeforeTransmit) == 0 && len(opts.Interceptors.AfterTransmit) == 0 && + len(opts.Interceptors.BeforeDeserialization) == 0 && len(opts.Interceptors.AfterDeserialization) == 0 && + len(opts.Interceptors.AfterAttempt) == 0 && len(opts.Interceptors.AfterExecution) == 0 { + return nil + } -func addSpanBuildRequestEnd(stack *middleware.Stack) error { - return stack.Build.Add(&spanBuildRequestEnd{}, middleware.After) + return errors.Join( + stack.Initialize.Add(&smithyhttp.InterceptExecution{ + BeforeExecution: opts.Interceptors.BeforeExecution, + AfterExecution: opts.Interceptors.AfterExecution, + }, middleware.Before), + stack.Serialize.Insert(&smithyhttp.InterceptBeforeSerialization{ + Interceptors: opts.Interceptors.BeforeSerialization, + }, "OperationSerializer", middleware.Before), + stack.Serialize.Insert(&smithyhttp.InterceptAfterSerialization{ + Interceptors: opts.Interceptors.AfterSerialization, + }, "OperationSerializer", middleware.After), + stack.Finalize.Insert(&smithyhttp.InterceptBeforeSigning{ + Interceptors: opts.Interceptors.BeforeSigning, + }, "Signing", middleware.Before), + stack.Finalize.Insert(&smithyhttp.InterceptAfterSigning{ + Interceptors: opts.Interceptors.AfterSigning, + }, "Signing", middleware.After), + stack.Deserialize.Add(&smithyhttp.InterceptTransmit{ + BeforeTransmit: opts.Interceptors.BeforeTransmit, + AfterTransmit: opts.Interceptors.AfterTransmit, + }, middleware.After), + stack.Deserialize.Insert(&smithyhttp.InterceptBeforeDeserialization{ + Interceptors: opts.Interceptors.BeforeDeserialization, + }, "OperationDeserializer", middleware.After), // (deserialize stack is called in reverse) + stack.Deserialize.Insert(&smithyhttp.InterceptAfterDeserialization{ + Interceptors: opts.Interceptors.AfterDeserialization, + }, "OperationDeserializer", middleware.Before), + ) } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_GetRoleCredentials.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_GetRoleCredentials.go index b8031eeea3..c0b961fcf1 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_GetRoleCredentials.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_GetRoleCredentials.go @@ -147,16 +147,13 @@ func (c *Client) addOperationGetRoleCredentialsMiddlewares(stack *middleware.Sta if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccountRoles.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccountRoles.go index 4294e4d3c9..f5ca09ac7d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccountRoles.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccountRoles.go @@ -152,16 +152,13 @@ func (c *Client) addOperationListAccountRolesMiddlewares(stack *middleware.Stack if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccounts.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccounts.go index 1db72a995e..54511d34a6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccounts.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccounts.go @@ -151,16 +151,13 @@ func (c *Client) addOperationListAccountsMiddlewares(stack *middleware.Stack, op if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_Logout.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_Logout.go index 2ca66ca509..a21116e96c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_Logout.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_Logout.go @@ -146,16 +146,13 @@ func (c *Client) addOperationLogoutMiddlewares(stack *middleware.Stack, options if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/auth.go index 366963b49f..c658615fde 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/auth.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/auth.go @@ -12,10 +12,13 @@ import ( "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/tracing" smithyhttp "github.com/aws/smithy-go/transport/http" + "slices" + "strings" ) -func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) { +func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) error { params.Region = options.Region + return nil } type setLegacyContextSigningOptionsMiddleware struct { @@ -92,14 +95,16 @@ type AuthResolverParameters struct { Region string } -func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) *AuthResolverParameters { +func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) (*AuthResolverParameters, error) { params := &AuthResolverParameters{ Operation: operation, } - bindAuthParamsRegion(ctx, params, input, options) + if err := bindAuthParamsRegion(ctx, params, input, options); err != nil { + return nil, err + } - return params + return params, nil } // AuthSchemeResolver returns a set of possible authentication options for an @@ -174,7 +179,10 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid _, span := tracing.StartSpan(ctx, "ResolveAuthScheme") defer span.End() - params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options) + params, err := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options) + if err != nil { + return out, metadata, fmt.Errorf("bind auth scheme params: %w", err) + } options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params) if err != nil { return out, metadata, fmt.Errorf("resolve auth scheme: %w", err) @@ -193,7 +201,8 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid } func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { - for _, option := range options { + sorted := sortAuthOptions(options, m.options.AuthSchemePreference) + for _, option := range sorted { if option.SchemeID == smithyauth.SchemeIDAnonymous { return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true } @@ -212,6 +221,29 @@ func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) return nil, false } +func sortAuthOptions(options []*smithyauth.Option, preferred []string) []*smithyauth.Option { + byPriority := make([]*smithyauth.Option, 0, len(options)) + for _, prefName := range preferred { + for _, option := range options { + optName := option.SchemeID + if parts := strings.Split(option.SchemeID, "#"); len(parts) == 2 { + optName = parts[1] + } + if prefName == optName { + byPriority = append(byPriority, option) + } + } + } + for _, option := range options { + if !slices.ContainsFunc(byPriority, func(o *smithyauth.Option) bool { + return o.SchemeID == option.SchemeID + }) { + byPriority = append(byPriority, option) + } + } + return byPriority +} + type resolvedAuthSchemeKey struct{} type resolvedAuthScheme struct { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/deserializers.go index ec23c36f5b..a889f3c7a7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/deserializers.go @@ -13,23 +13,13 @@ import ( smithyio "github.com/aws/smithy-go/io" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" - smithytime "github.com/aws/smithy-go/time" "github.com/aws/smithy-go/tracing" smithyhttp "github.com/aws/smithy-go/transport/http" "io" "io/ioutil" "strings" - "time" ) -func deserializeS3Expires(v string) (*time.Time, error) { - t, err := smithytime.ParseHTTPDate(v) - if err != nil { - return nil, nil - } - return &t, nil -} - type awsRestjson1_deserializeOpGetRoleCredentials struct { } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/endpoints.go index 53c6bc7561..551f05974e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/endpoints.go @@ -14,6 +14,7 @@ import ( internalendpoints "github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints" smithyauth "github.com/aws/smithy-go/auth" smithyendpoints "github.com/aws/smithy-go/endpoints" + "github.com/aws/smithy-go/endpoints/private/rulesfn" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" "github.com/aws/smithy-go/tracing" @@ -217,11 +218,15 @@ func resolveBaseEndpoint(cfg aws.Config, o *Options) { } } -func bindRegion(region string) *string { +func bindRegion(region string) (*string, error) { if region == "" { - return nil + return nil, nil + } + if !rulesfn.IsValidHostLabel(region, true) { + return nil, fmt.Errorf("invalid input region %s", region) } - return aws.String(endpoints.MapFIPSRegion(region)) + + return aws.String(endpoints.MapFIPSRegion(region)), nil } // EndpointParameters provides the parameters that influence how endpoints are @@ -328,7 +333,9 @@ func (r *resolver) ResolveEndpoint( return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err) } _UseDualStack := *params.UseDualStack + _ = _UseDualStack _UseFIPS := *params.UseFIPS + _ = _UseFIPS if exprVal := params.Endpoint; exprVal != nil { _Endpoint := *exprVal @@ -385,8 +392,8 @@ func (r *resolver) ResolveEndpoint( } } if _UseFIPS == true { - if true == _PartitionResult.SupportsFIPS { - if "aws-us-gov" == _PartitionResult.Name { + if _PartitionResult.SupportsFIPS == true { + if _PartitionResult.Name == "aws-us-gov" { uriString := func() string { var out strings.Builder out.WriteString("https://portal.sso.") @@ -477,10 +484,15 @@ type endpointParamsBinder interface { bindEndpointParams(*EndpointParameters) } -func bindEndpointParams(ctx context.Context, input interface{}, options Options) *EndpointParameters { +func bindEndpointParams(ctx context.Context, input interface{}, options Options) (*EndpointParameters, error) { params := &EndpointParameters{} - params.Region = bindRegion(options.Region) + region, err := bindRegion(options.Region) + if err != nil { + return nil, err + } + params.Region = region + params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled) params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled) params.Endpoint = options.BaseEndpoint @@ -489,7 +501,7 @@ func bindEndpointParams(ctx context.Context, input interface{}, options Options) b.bindEndpointParams(params) } - return params + return params, nil } type resolveEndpointV2Middleware struct { @@ -519,7 +531,10 @@ func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in mid return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") } - params := bindEndpointParams(ctx, getOperationInput(ctx), m.options) + params, err := bindEndpointParams(ctx, getOperationInput(ctx), m.options) + if err != nil { + return out, metadata, fmt.Errorf("failed to bind endpoint params, %w", err) + } endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration", func() (smithyendpoints.Endpoint, error) { return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/generated.json index 1a88fe4df8..1499c0a959 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/generated.json @@ -30,7 +30,7 @@ "types/types.go", "validators.go" ], - "go": "1.22", + "go": "1.23", "module": "github.com/aws/aws-sdk-go-v2/service/sso", "unstable": false } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/go_module_metadata.go index 5bd6f00784..29242d0e06 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/go_module_metadata.go @@ -3,4 +3,4 @@ package sso // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.25.4" +const goModuleVersion = "1.30.5" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints/endpoints.go index 04416606be..bbac359645 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints/endpoints.go @@ -237,6 +237,9 @@ var defaultPartitions = endpoints.Partitions{ Region: "ap-southeast-5", }, }, + endpoints.EndpointKey{ + Region: "ap-southeast-7", + }: endpoints.Endpoint{}, endpoints.EndpointKey{ Region: "ca-central-1", }: endpoints.Endpoint{ @@ -341,6 +344,9 @@ var defaultPartitions = endpoints.Partitions{ Region: "me-south-1", }, }, + endpoints.EndpointKey{ + Region: "mx-central-1", + }: endpoints.Endpoint{}, endpoints.EndpointKey{ Region: "sa-east-1", }: endpoints.Endpoint{ @@ -439,6 +445,13 @@ var defaultPartitions = endpoints.Partitions{ { ID: "aws-eusc", Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.DualStackVariant, + }: { + Hostname: "portal.sso.{region}.api.amazonwebservices.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, { Variant: endpoints.FIPSVariant, }: { @@ -446,6 +459,13 @@ var defaultPartitions = endpoints.Partitions{ Protocols: []string{"https"}, SignatureVersions: []string{"v4"}, }, + { + Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, + }: { + Hostname: "portal.sso-fips.{region}.api.amazonwebservices.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, { Variant: 0, }: { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/options.go index aa744f1594..277550af47 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sso/options.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sso/options.go @@ -119,12 +119,18 @@ type Options struct { // implementation if nil. HTTPClient HTTPClient + // Client registry of operation interceptors. + Interceptors smithyhttp.InterceptorRegistry + // The auth scheme resolver which determines how to authenticate for each // operation. AuthSchemeResolver AuthSchemeResolver // The list of auth schemes supported by the client. AuthSchemes []smithyhttp.AuthScheme + + // Priority list of preferred auth scheme names (e.g. sigv4a). + AuthSchemePreference []string } // Copy creates a clone where the APIOptions list is deep copied. @@ -132,6 +138,7 @@ func (o Options) Copy() Options { to := o to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) copy(to.APIOptions, o.APIOptions) + to.Interceptors = o.Interceptors.Copy() return to } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/CHANGELOG.md index e0d0da2b62..bc047472e9 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/CHANGELOG.md @@ -1,3 +1,113 @@ +# v1.35.10 (2025-11-25) + +* **Bug Fix**: Add error check for endpoint param binding during auth scheme resolution to fix panic reported in #3234 + +# v1.35.9 (2025-11-21) + +* No change notes available for this release. + +# v1.35.8 (2025-11-19.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.35.7 (2025-11-12) + +* **Bug Fix**: Further reduce allocation overhead when the metrics system isn't in-use. +* **Bug Fix**: Reduce allocation overhead when the client doesn't have any HTTP interceptors configured. +* **Bug Fix**: Remove blank trace spans towards the beginning of the request that added no additional information. This conveys a slight reduction in overall allocations. + +# v1.35.6 (2025-11-11) + +* **Bug Fix**: Return validation error if input region is not a valid host label. + +# v1.35.5 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.35.4 (2025-10-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.35.3 (2025-10-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.35.2 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.35.1 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.35.0 (2025-09-23) + +* **Feature**: This release includes exception definition and documentation updates. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.34.5 (2025-09-22) + +* No change notes available for this release. + +# v1.34.4 (2025-09-10) + +* No change notes available for this release. + +# v1.34.3 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.34.2 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.34.1 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.34.0 (2025-08-26) + +* **Feature**: Remove incorrect endpoint tests + +# v1.33.2 (2025-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.33.1 (2025-08-20) + +* **Bug Fix**: Remove unused deserialization code. + +# v1.33.0 (2025-08-11) + +* **Feature**: Add support for configuring per-service Options via callback on global config. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.32.0 (2025-08-04) + +* **Feature**: Support configurable auth scheme preferences in service clients via AWS_AUTH_SCHEME_PREFERENCE in the environment, auth_scheme_preference in the config file, and through in-code settings on LoadDefaultConfig and client constructor methods. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.1 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.31.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.30.4 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.30.3 (2025-06-17) + +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + # v1.30.2 (2025-06-10) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_client.go index 57440b1fa8..8e8508fa34 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_client.go @@ -65,7 +65,12 @@ func timeOperationMetric[T any]( ctx context.Context, metric string, fn func() (T, error), opts ...metrics.RecordMetricOption, ) (T, error) { - instr := getOperationMetrics(ctx).histogramFor(metric) + mm := getOperationMetrics(ctx) + if mm == nil { // not using the metrics system + return fn() + } + + instr := mm.histogramFor(metric) opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) start := time.Now() @@ -78,7 +83,12 @@ func timeOperationMetric[T any]( } func startMetricTimer(ctx context.Context, metric string, opts ...metrics.RecordMetricOption) func() { - instr := getOperationMetrics(ctx).histogramFor(metric) + mm := getOperationMetrics(ctx) + if mm == nil { // not using the metrics system + return func() {} + } + + instr := mm.histogramFor(metric) opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) var ended bool @@ -106,6 +116,12 @@ func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption { type operationMetricsKey struct{} func withOperationMetrics(parent context.Context, mp metrics.MeterProvider) (context.Context, error) { + if _, ok := mp.(metrics.NopMeterProvider); ok { + // not using the metrics system - setting up the metrics context is a memory-intensive operation + // so we should skip it in this case + return parent, nil + } + meter := mp.Meter("github.com/aws/aws-sdk-go-v2/service/ssooidc") om := &operationMetrics{} @@ -153,7 +169,10 @@ func operationMetricTimer(m metrics.Meter, name, desc string) (metrics.Float64Hi } func getOperationMetrics(ctx context.Context) *operationMetrics { - return ctx.Value(operationMetricsKey{}).(*operationMetrics) + if v := ctx.Value(operationMetricsKey{}); v != nil { + return v.(*operationMetrics) + } + return nil } func operationTracer(p tracing.TracerProvider) tracing.Tracer { @@ -419,24 +438,33 @@ func setResolvedDefaultsMode(o *Options) { // NewFromConfig returns a new client from the provided config. func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, + Region: cfg.Region, + DefaultsMode: cfg.DefaultsMode, + RuntimeEnvironment: cfg.RuntimeEnvironment, + HTTPClient: cfg.HTTPClient, + Credentials: cfg.Credentials, + APIOptions: cfg.APIOptions, + Logger: cfg.Logger, + ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, + AuthSchemePreference: cfg.AuthSchemePreference, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) resolveAWSRetryMode(cfg, &opts) resolveAWSEndpointResolver(cfg, &opts) + resolveInterceptors(cfg, &opts) resolveUseDualStackEndpoint(cfg, &opts) resolveUseFIPSEndpoint(cfg, &opts) resolveBaseEndpoint(cfg, &opts) - return New(opts, optFns...) + return New(opts, func(o *Options) { + for _, opt := range cfg.ServiceOptions { + opt(ServiceID, o) + } + for _, opt := range optFns { + opt(o) + } + }) } func resolveHTTPClient(o *Options) { @@ -550,6 +578,10 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } +func resolveInterceptors(cfg aws.Config, o *Options) { + o.Interceptors = cfg.Interceptors.Copy() +} + func addClientUserAgent(stack *middleware.Stack, options Options) error { ua, err := getOrAddRequestUserAgent(stack) if err != nil { @@ -856,88 +888,62 @@ func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { }, "ResolveEndpointV2", middleware.After) } -type spanInitializeStart struct { -} - -func (*spanInitializeStart) ID() string { - return "spanInitializeStart" -} - -func (m *spanInitializeStart) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - middleware.InitializeOutput, middleware.Metadata, error, -) { - ctx, _ = tracing.StartSpan(ctx, "Initialize") - - return next.HandleInitialize(ctx, in) -} - -type spanInitializeEnd struct { -} - -func (*spanInitializeEnd) ID() string { - return "spanInitializeEnd" -} - -func (m *spanInitializeEnd) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - middleware.InitializeOutput, middleware.Metadata, error, -) { - ctx, span := tracing.PopSpan(ctx) - span.End() - - return next.HandleInitialize(ctx, in) -} - -type spanBuildRequestStart struct { -} - -func (*spanBuildRequestStart) ID() string { - return "spanBuildRequestStart" -} - -func (m *spanBuildRequestStart) HandleSerialize( - ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, -) ( - middleware.SerializeOutput, middleware.Metadata, error, -) { - ctx, _ = tracing.StartSpan(ctx, "BuildRequest") - - return next.HandleSerialize(ctx, in) -} - -type spanBuildRequestEnd struct { -} - -func (*spanBuildRequestEnd) ID() string { - return "spanBuildRequestEnd" -} - -func (m *spanBuildRequestEnd) HandleBuild( - ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler, -) ( - middleware.BuildOutput, middleware.Metadata, error, -) { - ctx, span := tracing.PopSpan(ctx) - span.End() - - return next.HandleBuild(ctx, in) -} - -func addSpanInitializeStart(stack *middleware.Stack) error { - return stack.Initialize.Add(&spanInitializeStart{}, middleware.Before) -} - -func addSpanInitializeEnd(stack *middleware.Stack) error { - return stack.Initialize.Add(&spanInitializeEnd{}, middleware.After) -} - -func addSpanBuildRequestStart(stack *middleware.Stack) error { - return stack.Serialize.Add(&spanBuildRequestStart{}, middleware.Before) -} +func addInterceptBeforeRetryLoop(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptBeforeRetryLoop{ + Interceptors: opts.Interceptors.BeforeRetryLoop, + }, "Retry", middleware.Before) +} + +func addInterceptAttempt(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptAttempt{ + BeforeAttempt: opts.Interceptors.BeforeAttempt, + AfterAttempt: opts.Interceptors.AfterAttempt, + }, "Retry", middleware.After) +} + +func addInterceptors(stack *middleware.Stack, opts Options) error { + // middlewares are expensive, don't add all of these interceptor ones unless the caller + // actually has at least one interceptor configured + // + // at the moment it's all-or-nothing because some of the middlewares here are responsible for + // setting fields in the interceptor context for future ones + if len(opts.Interceptors.BeforeExecution) == 0 && + len(opts.Interceptors.BeforeSerialization) == 0 && len(opts.Interceptors.AfterSerialization) == 0 && + len(opts.Interceptors.BeforeRetryLoop) == 0 && + len(opts.Interceptors.BeforeAttempt) == 0 && + len(opts.Interceptors.BeforeSigning) == 0 && len(opts.Interceptors.AfterSigning) == 0 && + len(opts.Interceptors.BeforeTransmit) == 0 && len(opts.Interceptors.AfterTransmit) == 0 && + len(opts.Interceptors.BeforeDeserialization) == 0 && len(opts.Interceptors.AfterDeserialization) == 0 && + len(opts.Interceptors.AfterAttempt) == 0 && len(opts.Interceptors.AfterExecution) == 0 { + return nil + } -func addSpanBuildRequestEnd(stack *middleware.Stack) error { - return stack.Build.Add(&spanBuildRequestEnd{}, middleware.After) + return errors.Join( + stack.Initialize.Add(&smithyhttp.InterceptExecution{ + BeforeExecution: opts.Interceptors.BeforeExecution, + AfterExecution: opts.Interceptors.AfterExecution, + }, middleware.Before), + stack.Serialize.Insert(&smithyhttp.InterceptBeforeSerialization{ + Interceptors: opts.Interceptors.BeforeSerialization, + }, "OperationSerializer", middleware.Before), + stack.Serialize.Insert(&smithyhttp.InterceptAfterSerialization{ + Interceptors: opts.Interceptors.AfterSerialization, + }, "OperationSerializer", middleware.After), + stack.Finalize.Insert(&smithyhttp.InterceptBeforeSigning{ + Interceptors: opts.Interceptors.BeforeSigning, + }, "Signing", middleware.Before), + stack.Finalize.Insert(&smithyhttp.InterceptAfterSigning{ + Interceptors: opts.Interceptors.AfterSigning, + }, "Signing", middleware.After), + stack.Deserialize.Add(&smithyhttp.InterceptTransmit{ + BeforeTransmit: opts.Interceptors.BeforeTransmit, + AfterTransmit: opts.Interceptors.AfterTransmit, + }, middleware.After), + stack.Deserialize.Insert(&smithyhttp.InterceptBeforeDeserialization{ + Interceptors: opts.Interceptors.BeforeDeserialization, + }, "OperationDeserializer", middleware.After), // (deserialize stack is called in reverse) + stack.Deserialize.Insert(&smithyhttp.InterceptAfterDeserialization{ + Interceptors: opts.Interceptors.AfterDeserialization, + }, "OperationDeserializer", middleware.Before), + ) } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateToken.go index 493878338e..3f622dbcb9 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateToken.go @@ -85,10 +85,9 @@ type CreateTokenInput struct { // [IAM Identity Center OIDC API Reference]: https://docs.aws.amazon.com/singlesignon/latest/OIDCAPIReference/Welcome.html RefreshToken *string - // The list of scopes for which authorization is requested. The access token that - // is issued is limited to the scopes that are granted. If this value is not - // specified, IAM Identity Center authorizes all scopes that are configured for the - // client during the call to RegisterClient. + // The list of scopes for which authorization is requested. This parameter has no + // effect; the access token will always include all scopes configured during client + // registration. Scope []string noSmithyDocumentSerde @@ -218,16 +217,13 @@ func (c *Client) addOperationCreateTokenMiddlewares(stack *middleware.Stack, opt if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateTokenWithIAM.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateTokenWithIAM.go index 09f3647e8d..24cb2fac8d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateTokenWithIAM.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateTokenWithIAM.go @@ -11,10 +11,19 @@ import ( smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Creates and returns access and refresh tokens for clients and applications that -// are authenticated using IAM entities. The access token can be used to fetch -// short-lived credentials for the assigned Amazon Web Services accounts or to -// access application APIs using bearer authentication. +// Creates and returns access and refresh tokens for authorized client +// applications that are authenticated using any IAM entity, such as a service role +// or user. These tokens might contain defined scopes that specify permissions such +// as read:profile or write:data . Through downscoping, you can use the scopes +// parameter to request tokens with reduced permissions compared to the original +// client application's permissions or, if applicable, the refresh token's scopes. +// The access token can be used to fetch short-lived credentials for the assigned +// Amazon Web Services accounts or to access application APIs using bearer +// authentication. +// +// This API is used with Signature Version 4. For more information, see [Amazon Web Services Signature Version 4 for API Requests]. +// +// [Amazon Web Services Signature Version 4 for API Requests]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html func (c *Client) CreateTokenWithIAM(ctx context.Context, params *CreateTokenWithIAMInput, optFns ...func(*Options)) (*CreateTokenWithIAMOutput, error) { if params == nil { params = &CreateTokenWithIAMInput{} @@ -124,9 +133,8 @@ type CreateTokenWithIAMOutput struct { // to a user. AccessToken *string - // A structure containing information from the idToken . Only the identityContext - // is in it, which is a value extracted from the idToken . This provides direct - // access to identity information without requiring JWT parsing. + // A structure containing information from IAM Identity Center managed user and + // group information. AwsAdditionalDetails *types.AwsAdditionalDetails // Indicates the time in seconds when an access token will expire. @@ -256,16 +264,13 @@ func (c *Client) addOperationCreateTokenWithIAMMiddlewares(stack *middleware.Sta if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_RegisterClient.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_RegisterClient.go index 1e2d3828f5..14472ee3be 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_RegisterClient.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_RegisterClient.go @@ -188,16 +188,13 @@ func (c *Client) addOperationRegisterClientMiddlewares(stack *middleware.Stack, if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go index de0108f1f0..92a6854a77 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go @@ -170,16 +170,13 @@ func (c *Client) addOperationStartDeviceAuthorizationMiddlewares(stack *middlewa if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/auth.go index e4b87f5bc4..5f253df305 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/auth.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/auth.go @@ -12,10 +12,13 @@ import ( "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/tracing" smithyhttp "github.com/aws/smithy-go/transport/http" + "slices" + "strings" ) -func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) { +func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) error { params.Region = options.Region + return nil } type setLegacyContextSigningOptionsMiddleware struct { @@ -92,14 +95,16 @@ type AuthResolverParameters struct { Region string } -func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) *AuthResolverParameters { +func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) (*AuthResolverParameters, error) { params := &AuthResolverParameters{ Operation: operation, } - bindAuthParamsRegion(ctx, params, input, options) + if err := bindAuthParamsRegion(ctx, params, input, options); err != nil { + return nil, err + } - return params + return params, nil } // AuthSchemeResolver returns a set of possible authentication options for an @@ -168,7 +173,10 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid _, span := tracing.StartSpan(ctx, "ResolveAuthScheme") defer span.End() - params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options) + params, err := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options) + if err != nil { + return out, metadata, fmt.Errorf("bind auth scheme params: %w", err) + } options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params) if err != nil { return out, metadata, fmt.Errorf("resolve auth scheme: %w", err) @@ -187,7 +195,8 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid } func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { - for _, option := range options { + sorted := sortAuthOptions(options, m.options.AuthSchemePreference) + for _, option := range sorted { if option.SchemeID == smithyauth.SchemeIDAnonymous { return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true } @@ -206,6 +215,29 @@ func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) return nil, false } +func sortAuthOptions(options []*smithyauth.Option, preferred []string) []*smithyauth.Option { + byPriority := make([]*smithyauth.Option, 0, len(options)) + for _, prefName := range preferred { + for _, option := range options { + optName := option.SchemeID + if parts := strings.Split(option.SchemeID, "#"); len(parts) == 2 { + optName = parts[1] + } + if prefName == optName { + byPriority = append(byPriority, option) + } + } + } + for _, option := range options { + if !slices.ContainsFunc(byPriority, func(o *smithyauth.Option) bool { + return o.SchemeID == option.SchemeID + }) { + byPriority = append(byPriority, option) + } + } + return byPriority +} + type resolvedAuthSchemeKey struct{} type resolvedAuthScheme struct { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/deserializers.go index 93f3653d53..fb9a0df519 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/deserializers.go @@ -13,22 +13,12 @@ import ( smithyio "github.com/aws/smithy-go/io" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" - smithytime "github.com/aws/smithy-go/time" "github.com/aws/smithy-go/tracing" smithyhttp "github.com/aws/smithy-go/transport/http" "io" "strings" - "time" ) -func deserializeS3Expires(v string) (*time.Time, error) { - t, err := smithytime.ParseHTTPDate(v) - if err != nil { - return nil, nil - } - return &t, nil -} - type awsRestjson1_deserializeOpCreateToken struct { } @@ -621,6 +611,9 @@ func awsRestjson1_deserializeOpErrorRegisterClient(response *smithyhttp.Response case strings.EqualFold("InvalidScopeException", errorCode): return awsRestjson1_deserializeErrorInvalidScopeException(response, errorBody) + case strings.EqualFold("SlowDownException", errorCode): + return awsRestjson1_deserializeErrorSlowDownException(response, errorBody) + case strings.EqualFold("UnsupportedGrantTypeException", errorCode): return awsRestjson1_deserializeErrorUnsupportedGrantTypeException(response, errorBody) @@ -1492,6 +1485,15 @@ func awsRestjson1_deserializeDocumentAccessDeniedException(v **types.AccessDenie sv.Error_description = ptr.String(jtv) } + case "reason": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected AccessDeniedExceptionReason to be of type string, got %T instead", value) + } + sv.Reason = types.AccessDeniedExceptionReason(jtv) + } + default: _, _ = key, value @@ -1924,6 +1926,15 @@ func awsRestjson1_deserializeDocumentInvalidRequestException(v **types.InvalidRe sv.Error_description = ptr.String(jtv) } + case "reason": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected InvalidRequestExceptionReason to be of type string, got %T instead", value) + } + sv.Reason = types.InvalidRequestExceptionReason(jtv) + } + default: _, _ = key, value diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/doc.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/doc.go index f3510b18c5..aa9cf731d4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/doc.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/doc.go @@ -11,7 +11,7 @@ // # API namespaces // // IAM Identity Center uses the sso and identitystore API namespaces. IAM Identity -// Center OpenID Connect uses the sso-oidc namespace. +// Center OpenID Connect uses the sso-oauth namespace. // // # Considerations for using this guide // diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/endpoints.go index 6feea0c9fe..884983eb4d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/endpoints.go @@ -14,6 +14,7 @@ import ( internalendpoints "github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints" smithyauth "github.com/aws/smithy-go/auth" smithyendpoints "github.com/aws/smithy-go/endpoints" + "github.com/aws/smithy-go/endpoints/private/rulesfn" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" "github.com/aws/smithy-go/tracing" @@ -217,11 +218,15 @@ func resolveBaseEndpoint(cfg aws.Config, o *Options) { } } -func bindRegion(region string) *string { +func bindRegion(region string) (*string, error) { if region == "" { - return nil + return nil, nil + } + if !rulesfn.IsValidHostLabel(region, true) { + return nil, fmt.Errorf("invalid input region %s", region) } - return aws.String(endpoints.MapFIPSRegion(region)) + + return aws.String(endpoints.MapFIPSRegion(region)), nil } // EndpointParameters provides the parameters that influence how endpoints are @@ -328,7 +333,9 @@ func (r *resolver) ResolveEndpoint( return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err) } _UseDualStack := *params.UseDualStack + _ = _UseDualStack _UseFIPS := *params.UseFIPS + _ = _UseFIPS if exprVal := params.Endpoint; exprVal != nil { _Endpoint := *exprVal @@ -477,10 +484,15 @@ type endpointParamsBinder interface { bindEndpointParams(*EndpointParameters) } -func bindEndpointParams(ctx context.Context, input interface{}, options Options) *EndpointParameters { +func bindEndpointParams(ctx context.Context, input interface{}, options Options) (*EndpointParameters, error) { params := &EndpointParameters{} - params.Region = bindRegion(options.Region) + region, err := bindRegion(options.Region) + if err != nil { + return nil, err + } + params.Region = region + params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled) params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled) params.Endpoint = options.BaseEndpoint @@ -489,7 +501,7 @@ func bindEndpointParams(ctx context.Context, input interface{}, options Options) b.bindEndpointParams(params) } - return params + return params, nil } type resolveEndpointV2Middleware struct { @@ -519,7 +531,10 @@ func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in mid return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") } - params := bindEndpointParams(ctx, getOperationInput(ctx), m.options) + params, err := bindEndpointParams(ctx, getOperationInput(ctx), m.options) + if err != nil { + return out, metadata, fmt.Errorf("failed to bind endpoint params, %w", err) + } endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration", func() (smithyendpoints.Endpoint, error) { return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/generated.json index 35f180975a..ee79b48eaa 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/generated.json @@ -26,11 +26,12 @@ "serializers.go", "snapshot_test.go", "sra_operation_order_test.go", + "types/enums.go", "types/errors.go", "types/types.go", "validators.go" ], - "go": "1.22", + "go": "1.23", "module": "github.com/aws/aws-sdk-go-v2/service/ssooidc", "unstable": false } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/go_module_metadata.go index ac4fcd9b6e..d93030ff97 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/go_module_metadata.go @@ -3,4 +3,4 @@ package ssooidc // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.30.2" +const goModuleVersion = "1.35.10" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints/endpoints.go index ba7b4f9eb0..2088fc7fb2 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints/endpoints.go @@ -157,6 +157,9 @@ var defaultPartitions = endpoints.Partitions{ Region: "ap-east-1", }, }, + endpoints.EndpointKey{ + Region: "ap-east-2", + }: endpoints.Endpoint{}, endpoints.EndpointKey{ Region: "ap-northeast-1", }: endpoints.Endpoint{ @@ -237,6 +240,9 @@ var defaultPartitions = endpoints.Partitions{ Region: "ap-southeast-5", }, }, + endpoints.EndpointKey{ + Region: "ap-southeast-7", + }: endpoints.Endpoint{}, endpoints.EndpointKey{ Region: "ca-central-1", }: endpoints.Endpoint{ @@ -341,6 +347,9 @@ var defaultPartitions = endpoints.Partitions{ Region: "me-south-1", }, }, + endpoints.EndpointKey{ + Region: "mx-central-1", + }: endpoints.Endpoint{}, endpoints.EndpointKey{ Region: "sa-east-1", }: endpoints.Endpoint{ @@ -439,6 +448,13 @@ var defaultPartitions = endpoints.Partitions{ { ID: "aws-eusc", Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.DualStackVariant, + }: { + Hostname: "oidc.{region}.api.amazonwebservices.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, { Variant: endpoints.FIPSVariant, }: { @@ -446,6 +462,13 @@ var defaultPartitions = endpoints.Partitions{ Protocols: []string{"https"}, SignatureVersions: []string{"v4"}, }, + { + Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, + }: { + Hostname: "oidc-fips.{region}.api.amazonwebservices.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, { Variant: 0, }: { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/options.go index 55dd80d0e0..f35f3d5a31 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/options.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/options.go @@ -119,12 +119,18 @@ type Options struct { // implementation if nil. HTTPClient HTTPClient + // Client registry of operation interceptors. + Interceptors smithyhttp.InterceptorRegistry + // The auth scheme resolver which determines how to authenticate for each // operation. AuthSchemeResolver AuthSchemeResolver // The list of auth schemes supported by the client. AuthSchemes []smithyhttp.AuthScheme + + // Priority list of preferred auth scheme names (e.g. sigv4a). + AuthSchemePreference []string } // Copy creates a clone where the APIOptions list is deep copied. @@ -132,6 +138,7 @@ func (o Options) Copy() Options { to := o to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) copy(to.APIOptions, o.APIOptions) + to.Interceptors = o.Interceptors.Copy() return to } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/enums.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/enums.go new file mode 100644 index 0000000000..b14a3c0581 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/enums.go @@ -0,0 +1,44 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package types + +type AccessDeniedExceptionReason string + +// Enum values for AccessDeniedExceptionReason +const ( + AccessDeniedExceptionReasonKmsAccessDenied AccessDeniedExceptionReason = "KMS_AccessDeniedException" +) + +// Values returns all known values for AccessDeniedExceptionReason. Note that this +// can be expanded in the future, and so it is only as up to date as the client. +// +// The ordering of this slice is not guaranteed to be stable across updates. +func (AccessDeniedExceptionReason) Values() []AccessDeniedExceptionReason { + return []AccessDeniedExceptionReason{ + "KMS_AccessDeniedException", + } +} + +type InvalidRequestExceptionReason string + +// Enum values for InvalidRequestExceptionReason +const ( + InvalidRequestExceptionReasonKmsKeyNotFound InvalidRequestExceptionReason = "KMS_NotFoundException" + InvalidRequestExceptionReasonKmsInvalidKeyUsage InvalidRequestExceptionReason = "KMS_InvalidKeyUsageException" + InvalidRequestExceptionReasonKmsInvalidState InvalidRequestExceptionReason = "KMS_InvalidStateException" + InvalidRequestExceptionReasonKmsDisabledKey InvalidRequestExceptionReason = "KMS_DisabledException" +) + +// Values returns all known values for InvalidRequestExceptionReason. Note that +// this can be expanded in the future, and so it is only as up to date as the +// client. +// +// The ordering of this slice is not guaranteed to be stable across updates. +func (InvalidRequestExceptionReason) Values() []InvalidRequestExceptionReason { + return []InvalidRequestExceptionReason{ + "KMS_NotFoundException", + "KMS_InvalidKeyUsageException", + "KMS_InvalidStateException", + "KMS_DisabledException", + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/errors.go index 2cfe7b48fe..a1a3c7ef0d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/errors.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/errors.go @@ -14,6 +14,7 @@ type AccessDeniedException struct { ErrorCodeOverride *string Error_ *string + Reason AccessDeniedExceptionReason Error_description *string noSmithyDocumentSerde @@ -255,6 +256,7 @@ type InvalidRequestException struct { ErrorCodeOverride *string Error_ *string + Reason InvalidRequestExceptionReason Error_description *string noSmithyDocumentSerde diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/types.go index 2e8f3ea031..de15e8f051 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/types.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/types.go @@ -6,14 +6,17 @@ import ( smithydocument "github.com/aws/smithy-go/document" ) -// This structure contains Amazon Web Services-specific parameter extensions for -// the token endpoint responses and includes the identity context. +// This structure contains Amazon Web Services-specific parameter extensions and +// the [identity context]. +// +// [identity context]: https://docs.aws.amazon.com/singlesignon/latest/userguide/trustedidentitypropagation-overview.html type AwsAdditionalDetails struct { - // STS context assertion that carries a user identifier to the Amazon Web Services - // service that it calls and can be used to obtain an identity-enhanced IAM role - // session. This value corresponds to the sts:identity_context claim in the ID - // token. + // The trusted context assertion is signed and encrypted by STS. It provides + // access to sts:identity_context claim in the idToken without JWT parsing + // + // Identity context comprises information that Amazon Web Services services use to + // make authorization decisions when they receive requests. IdentityContext *string noSmithyDocumentSerde diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md index 1492199249..166c58455b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md @@ -1,3 +1,115 @@ +# v1.41.2 (2025-11-25) + +* **Bug Fix**: Add error check for endpoint param binding during auth scheme resolution to fix panic reported in #3234 + +# v1.41.1 (2025-11-19.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.41.0 (2025-11-19) + +* **Feature**: IAM now supports outbound identity federation via the STS GetWebIdentityToken API, enabling AWS workloads to securely authenticate with external services using short-lived JSON Web Tokens. + +# v1.40.2 (2025-11-12) + +* **Bug Fix**: Further reduce allocation overhead when the metrics system isn't in-use. +* **Bug Fix**: Reduce allocation overhead when the client doesn't have any HTTP interceptors configured. +* **Bug Fix**: Remove blank trace spans towards the beginning of the request that added no additional information. This conveys a slight reduction in overall allocations. + +# v1.40.1 (2025-11-11) + +* **Bug Fix**: Return validation error if input region is not a valid host label. + +# v1.40.0 (2025-11-10) + +* **Feature**: Added GetDelegatedAccessToken API, which is not available for general use at this time. + +# v1.39.1 (2025-11-04) + +* **Dependency Update**: Updated to the latest SDK module versions +* **Dependency Update**: Upgrade to smithy-go v1.23.2 which should convey some passive reduction of overall allocations, especially when not using the metrics system. + +# v1.39.0 (2025-10-30) + +* **Feature**: Update endpoint ruleset parameters casing +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.9 (2025-10-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.8 (2025-10-22) + +* No change notes available for this release. + +# v1.38.7 (2025-10-16) + +* **Dependency Update**: Bump minimum Go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.6 (2025-09-26) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.5 (2025-09-23) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.4 (2025-09-10) + +* No change notes available for this release. + +# v1.38.3 (2025-09-08) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.2 (2025-08-29) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.1 (2025-08-27) + +* **Dependency Update**: Update to smithy-go v1.23.0. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.38.0 (2025-08-21) + +* **Feature**: Remove incorrect endpoint tests +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.37.1 (2025-08-20) + +* **Bug Fix**: Remove unused deserialization code. + +# v1.37.0 (2025-08-11) + +* **Feature**: Add support for configuring per-service Options via callback on global config. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.36.0 (2025-08-04) + +* **Feature**: Support configurable auth scheme preferences in service clients via AWS_AUTH_SCHEME_PREFERENCE in the environment, auth_scheme_preference in the config file, and through in-code settings on LoadDefaultConfig and client constructor methods. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.35.1 (2025-07-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.35.0 (2025-07-28) + +* **Feature**: Add support for HTTP interceptors. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.34.1 (2025-07-19) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.34.0 (2025-06-17) + +* **Feature**: The AWS Security Token Service APIs AssumeRoleWithSAML and AssumeRoleWithWebIdentity can now be invoked without pre-configured AWS credentials in the SDK configuration. +* **Dependency Update**: Update to smithy-go v1.22.4. +* **Dependency Update**: Updated to the latest SDK module versions + # v1.33.21 (2025-06-10) * **Dependency Update**: Updated to the latest SDK module versions diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go index fca363d2f9..70228d0dfa 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go @@ -68,7 +68,12 @@ func timeOperationMetric[T any]( ctx context.Context, metric string, fn func() (T, error), opts ...metrics.RecordMetricOption, ) (T, error) { - instr := getOperationMetrics(ctx).histogramFor(metric) + mm := getOperationMetrics(ctx) + if mm == nil { // not using the metrics system + return fn() + } + + instr := mm.histogramFor(metric) opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) start := time.Now() @@ -81,7 +86,12 @@ func timeOperationMetric[T any]( } func startMetricTimer(ctx context.Context, metric string, opts ...metrics.RecordMetricOption) func() { - instr := getOperationMetrics(ctx).histogramFor(metric) + mm := getOperationMetrics(ctx) + if mm == nil { // not using the metrics system + return func() {} + } + + instr := mm.histogramFor(metric) opts = append([]metrics.RecordMetricOption{withOperationMetadata(ctx)}, opts...) var ended bool @@ -109,6 +119,12 @@ func withOperationMetadata(ctx context.Context) metrics.RecordMetricOption { type operationMetricsKey struct{} func withOperationMetrics(parent context.Context, mp metrics.MeterProvider) (context.Context, error) { + if _, ok := mp.(metrics.NopMeterProvider); ok { + // not using the metrics system - setting up the metrics context is a memory-intensive operation + // so we should skip it in this case + return parent, nil + } + meter := mp.Meter("github.com/aws/aws-sdk-go-v2/service/sts") om := &operationMetrics{} @@ -156,7 +172,10 @@ func operationMetricTimer(m metrics.Meter, name, desc string) (metrics.Float64Hi } func getOperationMetrics(ctx context.Context) *operationMetrics { - return ctx.Value(operationMetricsKey{}).(*operationMetrics) + if v := ctx.Value(operationMetricsKey{}); v != nil { + return v.(*operationMetrics) + } + return nil } func operationTracer(p tracing.TracerProvider) tracing.Tracer { @@ -423,24 +442,33 @@ func setResolvedDefaultsMode(o *Options) { // NewFromConfig returns a new client from the provided config. func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { opts := Options{ - Region: cfg.Region, - DefaultsMode: cfg.DefaultsMode, - RuntimeEnvironment: cfg.RuntimeEnvironment, - HTTPClient: cfg.HTTPClient, - Credentials: cfg.Credentials, - APIOptions: cfg.APIOptions, - Logger: cfg.Logger, - ClientLogMode: cfg.ClientLogMode, - AppID: cfg.AppID, + Region: cfg.Region, + DefaultsMode: cfg.DefaultsMode, + RuntimeEnvironment: cfg.RuntimeEnvironment, + HTTPClient: cfg.HTTPClient, + Credentials: cfg.Credentials, + APIOptions: cfg.APIOptions, + Logger: cfg.Logger, + ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, + AuthSchemePreference: cfg.AuthSchemePreference, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) resolveAWSRetryMode(cfg, &opts) resolveAWSEndpointResolver(cfg, &opts) + resolveInterceptors(cfg, &opts) resolveUseDualStackEndpoint(cfg, &opts) resolveUseFIPSEndpoint(cfg, &opts) resolveBaseEndpoint(cfg, &opts) - return New(opts, optFns...) + return New(opts, func(o *Options) { + for _, opt := range cfg.ServiceOptions { + opt(ServiceID, o) + } + for _, opt := range optFns { + opt(o) + } + }) } func resolveHTTPClient(o *Options) { @@ -554,6 +582,10 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } +func resolveInterceptors(cfg aws.Config, o *Options) { + o.Interceptors = cfg.Interceptors.Copy() +} + func addClientUserAgent(stack *middleware.Stack, options Options) error { ua, err := getOrAddRequestUserAgent(stack) if err != nil { @@ -1008,88 +1040,62 @@ func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { }, "ResolveEndpointV2", middleware.After) } -type spanInitializeStart struct { -} - -func (*spanInitializeStart) ID() string { - return "spanInitializeStart" -} - -func (m *spanInitializeStart) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - middleware.InitializeOutput, middleware.Metadata, error, -) { - ctx, _ = tracing.StartSpan(ctx, "Initialize") - - return next.HandleInitialize(ctx, in) -} - -type spanInitializeEnd struct { -} - -func (*spanInitializeEnd) ID() string { - return "spanInitializeEnd" -} - -func (m *spanInitializeEnd) HandleInitialize( - ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, -) ( - middleware.InitializeOutput, middleware.Metadata, error, -) { - ctx, span := tracing.PopSpan(ctx) - span.End() - - return next.HandleInitialize(ctx, in) -} - -type spanBuildRequestStart struct { -} - -func (*spanBuildRequestStart) ID() string { - return "spanBuildRequestStart" -} - -func (m *spanBuildRequestStart) HandleSerialize( - ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, -) ( - middleware.SerializeOutput, middleware.Metadata, error, -) { - ctx, _ = tracing.StartSpan(ctx, "BuildRequest") - - return next.HandleSerialize(ctx, in) -} - -type spanBuildRequestEnd struct { -} - -func (*spanBuildRequestEnd) ID() string { - return "spanBuildRequestEnd" -} - -func (m *spanBuildRequestEnd) HandleBuild( - ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler, -) ( - middleware.BuildOutput, middleware.Metadata, error, -) { - ctx, span := tracing.PopSpan(ctx) - span.End() - - return next.HandleBuild(ctx, in) -} - -func addSpanInitializeStart(stack *middleware.Stack) error { - return stack.Initialize.Add(&spanInitializeStart{}, middleware.Before) -} - -func addSpanInitializeEnd(stack *middleware.Stack) error { - return stack.Initialize.Add(&spanInitializeEnd{}, middleware.After) -} - -func addSpanBuildRequestStart(stack *middleware.Stack) error { - return stack.Serialize.Add(&spanBuildRequestStart{}, middleware.Before) -} +func addInterceptBeforeRetryLoop(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptBeforeRetryLoop{ + Interceptors: opts.Interceptors.BeforeRetryLoop, + }, "Retry", middleware.Before) +} + +func addInterceptAttempt(stack *middleware.Stack, opts Options) error { + return stack.Finalize.Insert(&smithyhttp.InterceptAttempt{ + BeforeAttempt: opts.Interceptors.BeforeAttempt, + AfterAttempt: opts.Interceptors.AfterAttempt, + }, "Retry", middleware.After) +} + +func addInterceptors(stack *middleware.Stack, opts Options) error { + // middlewares are expensive, don't add all of these interceptor ones unless the caller + // actually has at least one interceptor configured + // + // at the moment it's all-or-nothing because some of the middlewares here are responsible for + // setting fields in the interceptor context for future ones + if len(opts.Interceptors.BeforeExecution) == 0 && + len(opts.Interceptors.BeforeSerialization) == 0 && len(opts.Interceptors.AfterSerialization) == 0 && + len(opts.Interceptors.BeforeRetryLoop) == 0 && + len(opts.Interceptors.BeforeAttempt) == 0 && + len(opts.Interceptors.BeforeSigning) == 0 && len(opts.Interceptors.AfterSigning) == 0 && + len(opts.Interceptors.BeforeTransmit) == 0 && len(opts.Interceptors.AfterTransmit) == 0 && + len(opts.Interceptors.BeforeDeserialization) == 0 && len(opts.Interceptors.AfterDeserialization) == 0 && + len(opts.Interceptors.AfterAttempt) == 0 && len(opts.Interceptors.AfterExecution) == 0 { + return nil + } -func addSpanBuildRequestEnd(stack *middleware.Stack) error { - return stack.Build.Add(&spanBuildRequestEnd{}, middleware.After) + return errors.Join( + stack.Initialize.Add(&smithyhttp.InterceptExecution{ + BeforeExecution: opts.Interceptors.BeforeExecution, + AfterExecution: opts.Interceptors.AfterExecution, + }, middleware.Before), + stack.Serialize.Insert(&smithyhttp.InterceptBeforeSerialization{ + Interceptors: opts.Interceptors.BeforeSerialization, + }, "OperationSerializer", middleware.Before), + stack.Serialize.Insert(&smithyhttp.InterceptAfterSerialization{ + Interceptors: opts.Interceptors.AfterSerialization, + }, "OperationSerializer", middleware.After), + stack.Finalize.Insert(&smithyhttp.InterceptBeforeSigning{ + Interceptors: opts.Interceptors.BeforeSigning, + }, "Signing", middleware.Before), + stack.Finalize.Insert(&smithyhttp.InterceptAfterSigning{ + Interceptors: opts.Interceptors.AfterSigning, + }, "Signing", middleware.After), + stack.Deserialize.Add(&smithyhttp.InterceptTransmit{ + BeforeTransmit: opts.Interceptors.BeforeTransmit, + AfterTransmit: opts.Interceptors.AfterTransmit, + }, middleware.After), + stack.Deserialize.Insert(&smithyhttp.InterceptBeforeDeserialization{ + Interceptors: opts.Interceptors.BeforeDeserialization, + }, "OperationDeserializer", middleware.After), // (deserialize stack is called in reverse) + stack.Deserialize.Insert(&smithyhttp.InterceptAfterDeserialization{ + Interceptors: opts.Interceptors.AfterDeserialization, + }, "OperationDeserializer", middleware.Before), + ) } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go index 524e36eb61..0ddd3623ae 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go @@ -147,7 +147,7 @@ type AssumeRoleInput struct { // // The regex used to validate this parameter is a string of characters consisting // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: =,.@- + // include underscores or any of the following characters: +=,.@- // // [CloudTrail logs]: https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration.html#cloudtrail-integration_signin-tempcreds // [sts:RoleSessionName]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#ck_rolesessionname @@ -196,7 +196,7 @@ type AssumeRoleInput struct { // // The regex used to validate this parameter is a string of characters consisting // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: =,.@:/- + // include underscores or any of the following characters: +=,.@:\/- // // [How to Use an External ID When Granting Access to Your Amazon Web Services Resources to a Third Party]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html ExternalId *string @@ -279,7 +279,7 @@ type AssumeRoleInput struct { // // The regex used to validate this parameter is a string of characters consisting // of upper- and lower-case alphanumeric characters with no spaces. You can also - // include underscores or any of the following characters: =,.@- + // include underscores or any of the following characters: +=/:,.@- SerialNumber *string // The source identity specified by the principal that is calling the AssumeRole @@ -502,16 +502,13 @@ func (c *Client) addOperationAssumeRoleMiddlewares(stack *middleware.Stack, opti if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { - return err - } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go index 400f809e30..15f1dd91d2 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go @@ -23,6 +23,9 @@ import ( // these temporary security credentials to sign calls to Amazon Web Services // services. // +// AssumeRoleWithSAML will not work on IAM Identity Center managed roles. These +// roles' names start with AWSReservedSSO_ . +// // # Session Duration // // By default, the temporary security credentials created by AssumeRoleWithSAML @@ -434,16 +437,13 @@ func (c *Client) addOperationAssumeRoleWithSAMLMiddlewares(stack *middleware.Sta if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { - return err - } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go index e5708cbd1d..7006eb3b7f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go @@ -75,7 +75,7 @@ import ( // // (Optional) You can configure your IdP to pass attributes into your web identity // token as session tags. Each session tag consists of a key name and an associated -// value. For more information about session tags, see [Passing Session Tags in STS]in the IAM User Guide. +// value. For more information about session tags, see [Passing session tags using AssumeRoleWithWebIdentity]in the IAM User Guide. // // You can pass up to 50 session tags. The plaintext session tag keys can’t exceed // 128 characters and the values can’t exceed 256 characters. For these and @@ -123,6 +123,7 @@ import ( // providers to get and use temporary security credentials. // // [Amazon Web Services SDK for iOS Developer Guide]: http://aws.amazon.com/sdkforios/ +// [Passing session tags using AssumeRoleWithWebIdentity]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_adding-assume-role-idp // [Amazon Web Services SDK for Android Developer Guide]: http://aws.amazon.com/sdkforandroid/ // [IAM and STS Character Limits]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length // [session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session @@ -135,7 +136,6 @@ import ( // [Using IAM Roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html // [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session // [Amazon Cognito federated identities]: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html -// [Passing Session Tags in STS]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html // [Chaining Roles with Session Tags]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining // [Update the maximum session duration for a role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_update-role-settings.html#id_roles_update-session-duration // [Using Web Identity Federation API Operations for Mobile Apps]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual.html @@ -454,16 +454,13 @@ func (c *Client) addOperationAssumeRoleWithWebIdentityMiddlewares(stack *middlew if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go index a0f7a46713..009c405583 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go @@ -12,7 +12,9 @@ import ( ) // Returns a set of short term credentials you can use to perform privileged tasks -// on a member account in your organization. +// on a member account in your organization. You must use credentials from an +// Organizations management account or a delegated administrator account for IAM to +// call AssumeRoot . You cannot use root user credentials to make this call. // // Before you can launch a privileged session, you must have centralized root // access in your organization. For steps to enable this feature, see [Centralize root access for member accounts]in the IAM @@ -24,8 +26,16 @@ import ( // You can track AssumeRoot in CloudTrail logs to determine what actions were // performed in a session. For more information, see [Track privileged tasks in CloudTrail]in the IAM User Guide. // +// When granting access to privileged tasks you should only grant the necessary +// permissions required to perform that task. For more information, see [Security best practices in IAM]. In +// addition, you can use [service control policies](SCPs) to manage and limit permissions in your +// organization. See [General examples]in the Organizations User Guide for more information on SCPs. +// // [Endpoints]: https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html#sts-endpoints +// [Security best practices in IAM]: https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html // [Track privileged tasks in CloudTrail]: https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-track-privileged-tasks.html +// [General examples]: https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples_general.html +// [service control policies]: https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html // [Centralize root access for member accounts]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-enable-root-access.html func (c *Client) AssumeRoot(ctx context.Context, params *AssumeRootInput, optFns ...func(*Options)) (*AssumeRootOutput, error) { if params == nil { @@ -50,8 +60,10 @@ type AssumeRootInput struct { TargetPrincipal *string // The identity based policy that scopes the session to the privileged tasks that - // can be performed. You can use one of following Amazon Web Services managed - // policies to scope root session actions. + // can be performed. You must + // + // use one of following Amazon Web Services managed policies to scope root session + // actions: // // [IAMAuditRootUserCredentials] // @@ -199,16 +211,13 @@ func (c *Client) addOperationAssumeRootMiddlewares(stack *middleware.Stack, opti if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { - return err - } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go index 9e7cb17d36..b00b0c4096 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go @@ -171,16 +171,13 @@ func (c *Client) addOperationDecodeAuthorizationMessageMiddlewares(stack *middle if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go index 28c05f13bf..887bb081f3 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go @@ -162,16 +162,13 @@ func (c *Client) addOperationGetAccessKeyInfoMiddlewares(stack *middleware.Stack if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go index de137b7dc4..2c8d886701 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go @@ -150,16 +150,13 @@ func (c *Client) addOperationGetCallerIdentityMiddlewares(stack *middleware.Stac if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go new file mode 100644 index 0000000000..092ec13e3a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetDelegatedAccessToken.go @@ -0,0 +1,172 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package sts + +import ( + "context" + "fmt" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + "github.com/aws/aws-sdk-go-v2/service/sts/types" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" +) + +// Exchanges a trade-in token for temporary Amazon Web Services credentials with +// the permissions associated with the assumed principal. This operation allows you +// to obtain credentials for a specific principal based on a trade-in token, +// enabling delegation of access to Amazon Web Services resources. +func (c *Client) GetDelegatedAccessToken(ctx context.Context, params *GetDelegatedAccessTokenInput, optFns ...func(*Options)) (*GetDelegatedAccessTokenOutput, error) { + if params == nil { + params = &GetDelegatedAccessTokenInput{} + } + + result, metadata, err := c.invokeOperation(ctx, "GetDelegatedAccessToken", params, optFns, c.addOperationGetDelegatedAccessTokenMiddlewares) + if err != nil { + return nil, err + } + + out := result.(*GetDelegatedAccessTokenOutput) + out.ResultMetadata = metadata + return out, nil +} + +type GetDelegatedAccessTokenInput struct { + + // The token to exchange for temporary Amazon Web Services credentials. This token + // must be valid and unexpired at the time of the request. + // + // This member is required. + TradeInToken *string + + noSmithyDocumentSerde +} + +type GetDelegatedAccessTokenOutput struct { + + // The Amazon Resource Name (ARN) of the principal that was assumed when obtaining + // the delegated access token. This ARN identifies the IAM entity whose permissions + // are granted by the temporary credentials. + AssumedPrincipal *string + + // Amazon Web Services credentials for API authentication. + Credentials *types.Credentials + + // The percentage of the maximum policy size that is used by the session policy. + // The policy size is calculated as the sum of all the session policies and + // permission boundaries attached to the session. If the packed size exceeds 100%, + // the request fails. + PackedPolicySize *int32 + + // Metadata pertaining to the operation's result. + ResultMetadata middleware.Metadata + + noSmithyDocumentSerde +} + +func (c *Client) addOperationGetDelegatedAccessTokenMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } + err = stack.Serialize.Add(&awsAwsquery_serializeOpGetDelegatedAccessToken{}, middleware.After) + if err != nil { + return err + } + err = stack.Deserialize.Add(&awsAwsquery_deserializeOpGetDelegatedAccessToken{}, middleware.After) + if err != nil { + return err + } + if err := addProtocolFinalizerMiddlewares(stack, options, "GetDelegatedAccessToken"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } + if err = addSetLoggerMiddleware(stack, options); err != nil { + return err + } + if err = addClientRequestID(stack); err != nil { + return err + } + if err = addComputeContentLength(stack); err != nil { + return err + } + if err = addResolveEndpointMiddleware(stack, options); err != nil { + return err + } + if err = addComputePayloadSHA256(stack); err != nil { + return err + } + if err = addRetry(stack, options); err != nil { + return err + } + if err = addRawResponseToMetadata(stack); err != nil { + return err + } + if err = addRecordResponseTiming(stack); err != nil { + return err + } + if err = addSpanRetryLoop(stack, options); err != nil { + return err + } + if err = addClientUserAgent(stack, options); err != nil { + return err + } + if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } + if err = addTimeOffsetBuild(stack, c); err != nil { + return err + } + if err = addUserAgentRetryMode(stack, options); err != nil { + return err + } + if err = addCredentialSource(stack, options); err != nil { + return err + } + if err = addOpGetDelegatedAccessTokenValidationMiddleware(stack); err != nil { + return err + } + if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetDelegatedAccessToken(options.Region), middleware.Before); err != nil { + return err + } + if err = addRecursionDetection(stack); err != nil { + return err + } + if err = addRequestIDRetrieverMiddleware(stack); err != nil { + return err + } + if err = addResponseErrorMiddleware(stack); err != nil { + return err + } + if err = addRequestResponseLogging(stack, options); err != nil { + return err + } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptors(stack, options); err != nil { + return err + } + return nil +} + +func newServiceMetadataMiddleware_opGetDelegatedAccessToken(region string) *awsmiddleware.RegisterServiceMetadata { + return &awsmiddleware.RegisterServiceMetadata{ + Region: region, + ServiceID: ServiceID, + OperationName: "GetDelegatedAccessToken", + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go index 67c041b30e..e0fc9a5484 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go @@ -375,16 +375,13 @@ func (c *Client) addOperationGetFederationTokenMiddlewares(stack *middleware.Sta if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go index 903d151ce2..2f931f4446 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go @@ -221,16 +221,13 @@ func (c *Client) addOperationGetSessionTokenMiddlewares(stack *middleware.Stack, if err = addDisableHTTPSMiddleware(stack, options); err != nil { return err } - if err = addSpanInitializeStart(stack); err != nil { + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { return err } - if err = addSpanInitializeEnd(stack); err != nil { + if err = addInterceptAttempt(stack, options); err != nil { return err } - if err = addSpanBuildRequestStart(stack); err != nil { - return err - } - if err = addSpanBuildRequestEnd(stack); err != nil { + if err = addInterceptors(stack, options); err != nil { return err } return nil diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go new file mode 100644 index 0000000000..306ee43b1e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetWebIdentityToken.go @@ -0,0 +1,195 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package sts + +import ( + "context" + "fmt" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + "github.com/aws/aws-sdk-go-v2/service/sts/types" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" + "time" +) + +// Returns a signed JSON Web Token (JWT) that represents the calling Amazon Web +// Services identity. The returned JWT can be used to authenticate with external +// services that support OIDC discovery. The token is signed by Amazon Web Services +// STS and can be publicly verified using the verification keys published at the +// issuer's JWKS endpoint. +func (c *Client) GetWebIdentityToken(ctx context.Context, params *GetWebIdentityTokenInput, optFns ...func(*Options)) (*GetWebIdentityTokenOutput, error) { + if params == nil { + params = &GetWebIdentityTokenInput{} + } + + result, metadata, err := c.invokeOperation(ctx, "GetWebIdentityToken", params, optFns, c.addOperationGetWebIdentityTokenMiddlewares) + if err != nil { + return nil, err + } + + out := result.(*GetWebIdentityTokenOutput) + out.ResultMetadata = metadata + return out, nil +} + +type GetWebIdentityTokenInput struct { + + // The intended recipient of the web identity token. This value populates the aud + // claim in the JWT and should identify the service or application that will + // validate and use the token. The external service should verify this claim to + // ensure the token was intended for their use. + // + // This member is required. + Audience []string + + // The cryptographic algorithm to use for signing the JSON Web Token (JWT). Valid + // values are RS256 (RSA with SHA-256) and ES384 (ECDSA using P-384 curve with + // SHA-384). + // + // This member is required. + SigningAlgorithm *string + + // The duration, in seconds, for which the JSON Web Token (JWT) will remain valid. + // The value can range from 60 seconds (1 minute) to 3600 seconds (1 hour). If not + // specified, the default duration is 300 seconds (5 minutes). The token is + // designed to be short-lived and should be used for proof of identity, then + // exchanged for credentials or short-lived tokens in the external service. + DurationSeconds *int32 + + // An optional list of tags to include in the JSON Web Token (JWT). These tags are + // added as custom claims to the JWT and can be used by the downstream service for + // authorization decisions. + Tags []types.Tag + + noSmithyDocumentSerde +} + +type GetWebIdentityTokenOutput struct { + + // The date and time when the web identity token expires, in UTC. The expiration + // is determined by adding the DurationSeconds value to the time the token was + // issued. After this time, the token should no longer be considered valid. + Expiration *time.Time + + // A signed JSON Web Token (JWT) that represents the caller's Amazon Web Services + // identity. The token contains standard JWT claims such as subject, audience, + // expiration time, and additional identity attributes added by STS as custom + // claims. You can also add your own custom claims to the token by passing tags as + // request parameters to the GetWebIdentityToken API. The token is signed using + // the specified signing algorithm and can be verified using the verification keys + // available at the issuer's JWKS endpoint. + WebIdentityToken *string + + // Metadata pertaining to the operation's result. + ResultMetadata middleware.Metadata + + noSmithyDocumentSerde +} + +func (c *Client) addOperationGetWebIdentityTokenMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } + err = stack.Serialize.Add(&awsAwsquery_serializeOpGetWebIdentityToken{}, middleware.After) + if err != nil { + return err + } + err = stack.Deserialize.Add(&awsAwsquery_deserializeOpGetWebIdentityToken{}, middleware.After) + if err != nil { + return err + } + if err := addProtocolFinalizerMiddlewares(stack, options, "GetWebIdentityToken"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } + if err = addSetLoggerMiddleware(stack, options); err != nil { + return err + } + if err = addClientRequestID(stack); err != nil { + return err + } + if err = addComputeContentLength(stack); err != nil { + return err + } + if err = addResolveEndpointMiddleware(stack, options); err != nil { + return err + } + if err = addComputePayloadSHA256(stack); err != nil { + return err + } + if err = addRetry(stack, options); err != nil { + return err + } + if err = addRawResponseToMetadata(stack); err != nil { + return err + } + if err = addRecordResponseTiming(stack); err != nil { + return err + } + if err = addSpanRetryLoop(stack, options); err != nil { + return err + } + if err = addClientUserAgent(stack, options); err != nil { + return err + } + if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } + if err = addTimeOffsetBuild(stack, c); err != nil { + return err + } + if err = addUserAgentRetryMode(stack, options); err != nil { + return err + } + if err = addCredentialSource(stack, options); err != nil { + return err + } + if err = addOpGetWebIdentityTokenValidationMiddleware(stack); err != nil { + return err + } + if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetWebIdentityToken(options.Region), middleware.Before); err != nil { + return err + } + if err = addRecursionDetection(stack); err != nil { + return err + } + if err = addRequestIDRetrieverMiddleware(stack); err != nil { + return err + } + if err = addResponseErrorMiddleware(stack); err != nil { + return err + } + if err = addRequestResponseLogging(stack, options); err != nil { + return err + } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + if err = addInterceptBeforeRetryLoop(stack, options); err != nil { + return err + } + if err = addInterceptAttempt(stack, options); err != nil { + return err + } + if err = addInterceptors(stack, options); err != nil { + return err + } + return nil +} + +func newServiceMetadataMiddleware_opGetWebIdentityToken(region string) *awsmiddleware.RegisterServiceMetadata { + return &awsmiddleware.RegisterServiceMetadata{ + Region: region, + ServiceID: ServiceID, + OperationName: "GetWebIdentityToken", + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/auth.go index a90b2b7362..4db5a51f93 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/auth.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/auth.go @@ -12,10 +12,13 @@ import ( "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/tracing" smithyhttp "github.com/aws/smithy-go/transport/http" + "slices" + "strings" ) -func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) { +func bindAuthParamsRegion(_ interface{}, params *AuthResolverParameters, _ interface{}, options Options) error { params.Region = options.Region + return nil } type setLegacyContextSigningOptionsMiddleware struct { @@ -92,14 +95,16 @@ type AuthResolverParameters struct { Region string } -func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) *AuthResolverParameters { +func bindAuthResolverParams(ctx context.Context, operation string, input interface{}, options Options) (*AuthResolverParameters, error) { params := &AuthResolverParameters{ Operation: operation, } - bindAuthParamsRegion(ctx, params, input, options) + if err := bindAuthParamsRegion(ctx, params, input, options); err != nil { + return nil, err + } - return params + return params, nil } // AuthSchemeResolver returns a set of possible authentication options for an @@ -162,7 +167,10 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid _, span := tracing.StartSpan(ctx, "ResolveAuthScheme") defer span.End() - params := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options) + params, err := bindAuthResolverParams(ctx, m.operation, getOperationInput(ctx), m.options) + if err != nil { + return out, metadata, fmt.Errorf("bind auth scheme params: %w", err) + } options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params) if err != nil { return out, metadata, fmt.Errorf("resolve auth scheme: %w", err) @@ -181,7 +189,8 @@ func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in mid } func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { - for _, option := range options { + sorted := sortAuthOptions(options, m.options.AuthSchemePreference) + for _, option := range sorted { if option.SchemeID == smithyauth.SchemeIDAnonymous { return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true } @@ -200,6 +209,29 @@ func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) return nil, false } +func sortAuthOptions(options []*smithyauth.Option, preferred []string) []*smithyauth.Option { + byPriority := make([]*smithyauth.Option, 0, len(options)) + for _, prefName := range preferred { + for _, option := range options { + optName := option.SchemeID + if parts := strings.Split(option.SchemeID, "#"); len(parts) == 2 { + optName = parts[1] + } + if prefName == optName { + byPriority = append(byPriority, option) + } + } + } + for _, option := range options { + if !slices.ContainsFunc(byPriority, func(o *smithyauth.Option) bool { + return o.SchemeID == option.SchemeID + }) { + byPriority = append(byPriority, option) + } + } + return byPriority +} + type resolvedAuthSchemeKey struct{} type resolvedAuthScheme struct { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go index 59349890f6..8c1ce35161 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go @@ -21,17 +21,8 @@ import ( "io" "strconv" "strings" - "time" ) -func deserializeS3Expires(v string) (*time.Time, error) { - t, err := smithytime.ParseHTTPDate(v) - if err != nil { - return nil, nil - } - return &t, nil -} - type awsAwsquery_deserializeOpAssumeRole struct { } @@ -855,6 +846,124 @@ func awsAwsquery_deserializeOpErrorGetCallerIdentity(response *smithyhttp.Respon } } +type awsAwsquery_deserializeOpGetDelegatedAccessToken struct { +} + +func (*awsAwsquery_deserializeOpGetDelegatedAccessToken) ID() string { + return "OperationDeserializer" +} + +func (m *awsAwsquery_deserializeOpGetDelegatedAccessToken) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( + out middleware.DeserializeOutput, metadata middleware.Metadata, err error, +) { + out, metadata, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, metadata, err + } + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + response, ok := out.RawResponse.(*smithyhttp.Response) + if !ok { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} + } + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsAwsquery_deserializeOpErrorGetDelegatedAccessToken(response, &metadata) + } + output := &GetDelegatedAccessTokenOutput{} + out.Result = output + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + body := io.TeeReader(response.Body, ringBuffer) + rootDecoder := xml.NewDecoder(body) + t, err := smithyxml.FetchRootElement(rootDecoder) + if err == io.EOF { + return out, metadata, nil + } + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return out, metadata, &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) + t, err = decoder.GetElement("GetDelegatedAccessTokenResult") + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return out, metadata, err + } + + decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) + err = awsAwsquery_deserializeOpDocumentGetDelegatedAccessTokenOutput(&output, decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return out, metadata, err + } + + return out, metadata, err +} + +func awsAwsquery_deserializeOpErrorGetDelegatedAccessToken(response *smithyhttp.Response, metadata *middleware.Metadata) error { + var errorBuffer bytes.Buffer + if _, err := io.Copy(&errorBuffer, response.Body); err != nil { + return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} + } + errorBody := bytes.NewReader(errorBuffer.Bytes()) + + errorCode := "UnknownError" + errorMessage := errorCode + + errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) + if err != nil { + return err + } + if reqID := errorComponents.RequestID; len(reqID) != 0 { + awsmiddleware.SetRequestIDMetadata(metadata, reqID) + } + if len(errorComponents.Code) != 0 { + errorCode = errorComponents.Code + } + if len(errorComponents.Message) != 0 { + errorMessage = errorComponents.Message + } + errorBody.Seek(0, io.SeekStart) + switch { + case strings.EqualFold("ExpiredTradeInTokenException", errorCode): + return awsAwsquery_deserializeErrorExpiredTradeInTokenException(response, errorBody) + + case strings.EqualFold("PackedPolicyTooLarge", errorCode): + return awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response, errorBody) + + case strings.EqualFold("RegionDisabledException", errorCode): + return awsAwsquery_deserializeErrorRegionDisabledException(response, errorBody) + + default: + genericError := &smithy.GenericAPIError{ + Code: errorCode, + Message: errorMessage, + } + return genericError + + } +} + type awsAwsquery_deserializeOpGetFederationToken struct { } @@ -1085,6 +1194,124 @@ func awsAwsquery_deserializeOpErrorGetSessionToken(response *smithyhttp.Response } } +type awsAwsquery_deserializeOpGetWebIdentityToken struct { +} + +func (*awsAwsquery_deserializeOpGetWebIdentityToken) ID() string { + return "OperationDeserializer" +} + +func (m *awsAwsquery_deserializeOpGetWebIdentityToken) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( + out middleware.DeserializeOutput, metadata middleware.Metadata, err error, +) { + out, metadata, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, metadata, err + } + + _, span := tracing.StartSpan(ctx, "OperationDeserializer") + endTimer := startMetricTimer(ctx, "client.call.deserialization_duration") + defer endTimer() + defer span.End() + response, ok := out.RawResponse.(*smithyhttp.Response) + if !ok { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} + } + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsAwsquery_deserializeOpErrorGetWebIdentityToken(response, &metadata) + } + output := &GetWebIdentityTokenOutput{} + out.Result = output + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + body := io.TeeReader(response.Body, ringBuffer) + rootDecoder := xml.NewDecoder(body) + t, err := smithyxml.FetchRootElement(rootDecoder) + if err == io.EOF { + return out, metadata, nil + } + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return out, metadata, &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) + t, err = decoder.GetElement("GetWebIdentityTokenResult") + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return out, metadata, err + } + + decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) + err = awsAwsquery_deserializeOpDocumentGetWebIdentityTokenOutput(&output, decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return out, metadata, err + } + + return out, metadata, err +} + +func awsAwsquery_deserializeOpErrorGetWebIdentityToken(response *smithyhttp.Response, metadata *middleware.Metadata) error { + var errorBuffer bytes.Buffer + if _, err := io.Copy(&errorBuffer, response.Body); err != nil { + return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} + } + errorBody := bytes.NewReader(errorBuffer.Bytes()) + + errorCode := "UnknownError" + errorMessage := errorCode + + errorComponents, err := awsxml.GetErrorResponseComponents(errorBody, false) + if err != nil { + return err + } + if reqID := errorComponents.RequestID; len(reqID) != 0 { + awsmiddleware.SetRequestIDMetadata(metadata, reqID) + } + if len(errorComponents.Code) != 0 { + errorCode = errorComponents.Code + } + if len(errorComponents.Message) != 0 { + errorMessage = errorComponents.Message + } + errorBody.Seek(0, io.SeekStart) + switch { + case strings.EqualFold("JWTPayloadSizeExceededException", errorCode): + return awsAwsquery_deserializeErrorJWTPayloadSizeExceededException(response, errorBody) + + case strings.EqualFold("OutboundWebIdentityFederationDisabledException", errorCode): + return awsAwsquery_deserializeErrorOutboundWebIdentityFederationDisabledException(response, errorBody) + + case strings.EqualFold("SessionDurationEscalationException", errorCode): + return awsAwsquery_deserializeErrorSessionDurationEscalationException(response, errorBody) + + default: + genericError := &smithy.GenericAPIError{ + Code: errorCode, + Message: errorMessage, + } + return genericError + + } +} + func awsAwsquery_deserializeErrorExpiredTokenException(response *smithyhttp.Response, errorBody *bytes.Reader) error { output := &types.ExpiredTokenException{} var buff [1024]byte @@ -1129,8 +1356,8 @@ func awsAwsquery_deserializeErrorExpiredTokenException(response *smithyhttp.Resp return output } -func awsAwsquery_deserializeErrorIDPCommunicationErrorException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.IDPCommunicationErrorException{} +func awsAwsquery_deserializeErrorExpiredTradeInTokenException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.ExpiredTradeInTokenException{} var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) body := io.TeeReader(errorBody, ringBuffer) @@ -1160,7 +1387,7 @@ func awsAwsquery_deserializeErrorIDPCommunicationErrorException(response *smithy } decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentIDPCommunicationErrorException(&output, decoder) + err = awsAwsquery_deserializeDocumentExpiredTradeInTokenException(&output, decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1173,8 +1400,8 @@ func awsAwsquery_deserializeErrorIDPCommunicationErrorException(response *smithy return output } -func awsAwsquery_deserializeErrorIDPRejectedClaimException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.IDPRejectedClaimException{} +func awsAwsquery_deserializeErrorIDPCommunicationErrorException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.IDPCommunicationErrorException{} var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) body := io.TeeReader(errorBody, ringBuffer) @@ -1204,7 +1431,7 @@ func awsAwsquery_deserializeErrorIDPRejectedClaimException(response *smithyhttp. } decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentIDPRejectedClaimException(&output, decoder) + err = awsAwsquery_deserializeDocumentIDPCommunicationErrorException(&output, decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1217,8 +1444,8 @@ func awsAwsquery_deserializeErrorIDPRejectedClaimException(response *smithyhttp. return output } -func awsAwsquery_deserializeErrorInvalidAuthorizationMessageException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.InvalidAuthorizationMessageException{} +func awsAwsquery_deserializeErrorIDPRejectedClaimException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.IDPRejectedClaimException{} var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) body := io.TeeReader(errorBody, ringBuffer) @@ -1248,7 +1475,7 @@ func awsAwsquery_deserializeErrorInvalidAuthorizationMessageException(response * } decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentInvalidAuthorizationMessageException(&output, decoder) + err = awsAwsquery_deserializeDocumentIDPRejectedClaimException(&output, decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1261,8 +1488,8 @@ func awsAwsquery_deserializeErrorInvalidAuthorizationMessageException(response * return output } -func awsAwsquery_deserializeErrorInvalidIdentityTokenException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.InvalidIdentityTokenException{} +func awsAwsquery_deserializeErrorInvalidAuthorizationMessageException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.InvalidAuthorizationMessageException{} var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) body := io.TeeReader(errorBody, ringBuffer) @@ -1292,7 +1519,7 @@ func awsAwsquery_deserializeErrorInvalidIdentityTokenException(response *smithyh } decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentInvalidIdentityTokenException(&output, decoder) + err = awsAwsquery_deserializeDocumentInvalidAuthorizationMessageException(&output, decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1305,8 +1532,8 @@ func awsAwsquery_deserializeErrorInvalidIdentityTokenException(response *smithyh return output } -func awsAwsquery_deserializeErrorMalformedPolicyDocumentException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.MalformedPolicyDocumentException{} +func awsAwsquery_deserializeErrorInvalidIdentityTokenException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.InvalidIdentityTokenException{} var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) body := io.TeeReader(errorBody, ringBuffer) @@ -1336,7 +1563,7 @@ func awsAwsquery_deserializeErrorMalformedPolicyDocumentException(response *smit } decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentMalformedPolicyDocumentException(&output, decoder) + err = awsAwsquery_deserializeDocumentInvalidIdentityTokenException(&output, decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1349,8 +1576,8 @@ func awsAwsquery_deserializeErrorMalformedPolicyDocumentException(response *smit return output } -func awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.PackedPolicyTooLargeException{} +func awsAwsquery_deserializeErrorJWTPayloadSizeExceededException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.JWTPayloadSizeExceededException{} var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) body := io.TeeReader(errorBody, ringBuffer) @@ -1380,7 +1607,7 @@ func awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response *smithyh } decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentPackedPolicyTooLargeException(&output, decoder) + err = awsAwsquery_deserializeDocumentJWTPayloadSizeExceededException(&output, decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1393,8 +1620,8 @@ func awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response *smithyh return output } -func awsAwsquery_deserializeErrorRegionDisabledException(response *smithyhttp.Response, errorBody *bytes.Reader) error { - output := &types.RegionDisabledException{} +func awsAwsquery_deserializeErrorMalformedPolicyDocumentException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.MalformedPolicyDocumentException{} var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) body := io.TeeReader(errorBody, ringBuffer) @@ -1424,7 +1651,7 @@ func awsAwsquery_deserializeErrorRegionDisabledException(response *smithyhttp.Re } decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) - err = awsAwsquery_deserializeDocumentRegionDisabledException(&output, decoder) + err = awsAwsquery_deserializeDocumentMalformedPolicyDocumentException(&output, decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1437,10 +1664,186 @@ func awsAwsquery_deserializeErrorRegionDisabledException(response *smithyhttp.Re return output } -func awsAwsquery_deserializeDocumentAssumedRoleUser(v **types.AssumedRoleUser, decoder smithyxml.NodeDecoder) error { - if v == nil { - return fmt.Errorf("unexpected nil of type %T", v) - } +func awsAwsquery_deserializeErrorOutboundWebIdentityFederationDisabledException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.OutboundWebIdentityFederationDisabledException{} + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + body := io.TeeReader(errorBody, ringBuffer) + rootDecoder := xml.NewDecoder(body) + t, err := smithyxml.FetchRootElement(rootDecoder) + if err == io.EOF { + return output + } + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) + t, err = decoder.GetElement("Error") + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) + err = awsAwsquery_deserializeDocumentOutboundWebIdentityFederationDisabledException(&output, decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + return output +} + +func awsAwsquery_deserializeErrorPackedPolicyTooLargeException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.PackedPolicyTooLargeException{} + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + body := io.TeeReader(errorBody, ringBuffer) + rootDecoder := xml.NewDecoder(body) + t, err := smithyxml.FetchRootElement(rootDecoder) + if err == io.EOF { + return output + } + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) + t, err = decoder.GetElement("Error") + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) + err = awsAwsquery_deserializeDocumentPackedPolicyTooLargeException(&output, decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + return output +} + +func awsAwsquery_deserializeErrorRegionDisabledException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.RegionDisabledException{} + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + body := io.TeeReader(errorBody, ringBuffer) + rootDecoder := xml.NewDecoder(body) + t, err := smithyxml.FetchRootElement(rootDecoder) + if err == io.EOF { + return output + } + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) + t, err = decoder.GetElement("Error") + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) + err = awsAwsquery_deserializeDocumentRegionDisabledException(&output, decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + return output +} + +func awsAwsquery_deserializeErrorSessionDurationEscalationException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + output := &types.SessionDurationEscalationException{} + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + body := io.TeeReader(errorBody, ringBuffer) + rootDecoder := xml.NewDecoder(body) + t, err := smithyxml.FetchRootElement(rootDecoder) + if err == io.EOF { + return output + } + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder := smithyxml.WrapNodeDecoder(rootDecoder, t) + t, err = decoder.GetElement("Error") + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + decoder = smithyxml.WrapNodeDecoder(decoder.Decoder, t) + err = awsAwsquery_deserializeDocumentSessionDurationEscalationException(&output, decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + return &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + } + + return output +} + +func awsAwsquery_deserializeDocumentAssumedRoleUser(v **types.AssumedRoleUser, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } var sv *types.AssumedRoleUser if *v == nil { sv = &types.AssumedRoleUser{} @@ -1640,6 +2043,55 @@ func awsAwsquery_deserializeDocumentExpiredTokenException(v **types.ExpiredToken return nil } +func awsAwsquery_deserializeDocumentExpiredTradeInTokenException(v **types.ExpiredTradeInTokenException, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + var sv *types.ExpiredTradeInTokenException + if *v == nil { + sv = &types.ExpiredTradeInTokenException{} + } else { + sv = *v + } + + for { + t, done, err := decoder.Token() + if err != nil { + return err + } + if done { + break + } + originalDecoder := decoder + decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) + switch { + case strings.EqualFold("message", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + sv.Message = ptr.String(xtv) + } + + default: + // Do nothing and ignore the unexpected tag element + err = decoder.Decoder.Skip() + if err != nil { + return err + } + + } + decoder = originalDecoder + } + *v = sv + return nil +} + func awsAwsquery_deserializeDocumentFederatedUser(v **types.FederatedUser, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -1898,6 +2350,55 @@ func awsAwsquery_deserializeDocumentInvalidIdentityTokenException(v **types.Inva return nil } +func awsAwsquery_deserializeDocumentJWTPayloadSizeExceededException(v **types.JWTPayloadSizeExceededException, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + var sv *types.JWTPayloadSizeExceededException + if *v == nil { + sv = &types.JWTPayloadSizeExceededException{} + } else { + sv = *v + } + + for { + t, done, err := decoder.Token() + if err != nil { + return err + } + if done { + break + } + originalDecoder := decoder + decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) + switch { + case strings.EqualFold("message", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + sv.Message = ptr.String(xtv) + } + + default: + // Do nothing and ignore the unexpected tag element + err = decoder.Decoder.Skip() + if err != nil { + return err + } + + } + decoder = originalDecoder + } + *v = sv + return nil +} + func awsAwsquery_deserializeDocumentMalformedPolicyDocumentException(v **types.MalformedPolicyDocumentException, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -1947,6 +2448,55 @@ func awsAwsquery_deserializeDocumentMalformedPolicyDocumentException(v **types.M return nil } +func awsAwsquery_deserializeDocumentOutboundWebIdentityFederationDisabledException(v **types.OutboundWebIdentityFederationDisabledException, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + var sv *types.OutboundWebIdentityFederationDisabledException + if *v == nil { + sv = &types.OutboundWebIdentityFederationDisabledException{} + } else { + sv = *v + } + + for { + t, done, err := decoder.Token() + if err != nil { + return err + } + if done { + break + } + originalDecoder := decoder + decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) + switch { + case strings.EqualFold("message", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + sv.Message = ptr.String(xtv) + } + + default: + // Do nothing and ignore the unexpected tag element + err = decoder.Decoder.Skip() + if err != nil { + return err + } + + } + decoder = originalDecoder + } + *v = sv + return nil +} + func awsAwsquery_deserializeDocumentPackedPolicyTooLargeException(v **types.PackedPolicyTooLargeException, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -2045,6 +2595,55 @@ func awsAwsquery_deserializeDocumentRegionDisabledException(v **types.RegionDisa return nil } +func awsAwsquery_deserializeDocumentSessionDurationEscalationException(v **types.SessionDurationEscalationException, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + var sv *types.SessionDurationEscalationException + if *v == nil { + sv = &types.SessionDurationEscalationException{} + } else { + sv = *v + } + + for { + t, done, err := decoder.Token() + if err != nil { + return err + } + if done { + break + } + originalDecoder := decoder + decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) + switch { + case strings.EqualFold("message", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + sv.Message = ptr.String(xtv) + } + + default: + // Do nothing and ignore the unexpected tag element + err = decoder.Decoder.Skip() + if err != nil { + return err + } + + } + decoder = originalDecoder + } + *v = sv + return nil +} + func awsAwsquery_deserializeOpDocumentAssumeRoleOutput(v **AssumeRoleOutput, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -2611,6 +3210,78 @@ func awsAwsquery_deserializeOpDocumentGetCallerIdentityOutput(v **GetCallerIdent return nil } +func awsAwsquery_deserializeOpDocumentGetDelegatedAccessTokenOutput(v **GetDelegatedAccessTokenOutput, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + var sv *GetDelegatedAccessTokenOutput + if *v == nil { + sv = &GetDelegatedAccessTokenOutput{} + } else { + sv = *v + } + + for { + t, done, err := decoder.Token() + if err != nil { + return err + } + if done { + break + } + originalDecoder := decoder + decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) + switch { + case strings.EqualFold("AssumedPrincipal", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + sv.AssumedPrincipal = ptr.String(xtv) + } + + case strings.EqualFold("Credentials", t.Name.Local): + nodeDecoder := smithyxml.WrapNodeDecoder(decoder.Decoder, t) + if err := awsAwsquery_deserializeDocumentCredentials(&sv.Credentials, nodeDecoder); err != nil { + return err + } + + case strings.EqualFold("PackedPolicySize", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + i64, err := strconv.ParseInt(xtv, 10, 64) + if err != nil { + return err + } + sv.PackedPolicySize = ptr.Int32(int32(i64)) + } + + default: + // Do nothing and ignore the unexpected tag element + err = decoder.Decoder.Skip() + if err != nil { + return err + } + + } + decoder = originalDecoder + } + *v = sv + return nil +} + func awsAwsquery_deserializeOpDocumentGetFederationTokenOutput(v **GetFederationTokenOutput, decoder smithyxml.NodeDecoder) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -2717,3 +3388,69 @@ func awsAwsquery_deserializeOpDocumentGetSessionTokenOutput(v **GetSessionTokenO *v = sv return nil } + +func awsAwsquery_deserializeOpDocumentGetWebIdentityTokenOutput(v **GetWebIdentityTokenOutput, decoder smithyxml.NodeDecoder) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + var sv *GetWebIdentityTokenOutput + if *v == nil { + sv = &GetWebIdentityTokenOutput{} + } else { + sv = *v + } + + for { + t, done, err := decoder.Token() + if err != nil { + return err + } + if done { + break + } + originalDecoder := decoder + decoder = smithyxml.WrapNodeDecoder(originalDecoder.Decoder, t) + switch { + case strings.EqualFold("Expiration", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + t, err := smithytime.ParseDateTime(xtv) + if err != nil { + return err + } + sv.Expiration = ptr.Time(t) + } + + case strings.EqualFold("WebIdentityToken", t.Name.Local): + val, err := decoder.Value() + if err != nil { + return err + } + if val == nil { + break + } + { + xtv := string(val) + sv.WebIdentityToken = ptr.String(xtv) + } + + default: + // Do nothing and ignore the unexpected tag element + err = decoder.Decoder.Skip() + if err != nil { + return err + } + + } + decoder = originalDecoder + } + *v = sv + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/endpoints.go index dca2ce3599..c8f9526c78 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/endpoints.go @@ -15,6 +15,7 @@ import ( smithy "github.com/aws/smithy-go" smithyauth "github.com/aws/smithy-go/auth" smithyendpoints "github.com/aws/smithy-go/endpoints" + "github.com/aws/smithy-go/endpoints/private/rulesfn" "github.com/aws/smithy-go/middleware" "github.com/aws/smithy-go/ptr" "github.com/aws/smithy-go/tracing" @@ -218,11 +219,15 @@ func resolveBaseEndpoint(cfg aws.Config, o *Options) { } } -func bindRegion(region string) *string { +func bindRegion(region string) (*string, error) { if region == "" { - return nil + return nil, nil + } + if !rulesfn.IsValidHostLabel(region, true) { + return nil, fmt.Errorf("invalid input region %s", region) } - return aws.String(endpoints.MapFIPSRegion(region)) + + return aws.String(endpoints.MapFIPSRegion(region)), nil } // EndpointParameters provides the parameters that influence how endpoints are @@ -346,8 +351,11 @@ func (r *resolver) ResolveEndpoint( return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err) } _UseDualStack := *params.UseDualStack + _ = _UseDualStack _UseFIPS := *params.UseFIPS + _ = _UseFIPS _UseGlobalEndpoint := *params.UseGlobalEndpoint + _ = _UseGlobalEndpoint if _UseGlobalEndpoint == true { if !(params.Endpoint != nil) { @@ -1057,10 +1065,15 @@ type endpointParamsBinder interface { bindEndpointParams(*EndpointParameters) } -func bindEndpointParams(ctx context.Context, input interface{}, options Options) *EndpointParameters { +func bindEndpointParams(ctx context.Context, input interface{}, options Options) (*EndpointParameters, error) { params := &EndpointParameters{} - params.Region = bindRegion(options.Region) + region, err := bindRegion(options.Region) + if err != nil { + return nil, err + } + params.Region = region + params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled) params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled) params.Endpoint = options.BaseEndpoint @@ -1069,7 +1082,7 @@ func bindEndpointParams(ctx context.Context, input interface{}, options Options) b.bindEndpointParams(params) } - return params + return params, nil } type resolveEndpointV2Middleware struct { @@ -1099,7 +1112,10 @@ func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in mid return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") } - params := bindEndpointParams(ctx, getOperationInput(ctx), m.options) + params, err := bindEndpointParams(ctx, getOperationInput(ctx), m.options) + if err != nil { + return out, metadata, fmt.Errorf("failed to bind endpoint params, %w", err) + } endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration", func() (smithyendpoints.Endpoint, error) { return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params) diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json index 86bb3b79be..e61823ea01 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json @@ -17,8 +17,10 @@ "api_op_DecodeAuthorizationMessage.go", "api_op_GetAccessKeyInfo.go", "api_op_GetCallerIdentity.go", + "api_op_GetDelegatedAccessToken.go", "api_op_GetFederationToken.go", "api_op_GetSessionToken.go", + "api_op_GetWebIdentityToken.go", "auth.go", "deserializers.go", "doc.go", @@ -37,7 +39,7 @@ "types/types.go", "validators.go" ], - "go": "1.22", + "go": "1.23", "module": "github.com/aws/aws-sdk-go-v2/service/sts", "unstable": false } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go index 0b59c0fa3d..86a1e11737 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go @@ -3,4 +3,4 @@ package sts // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.33.21" +const goModuleVersion = "1.41.2" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints/endpoints.go index 3dfa51e5f4..b2b933c566 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints/endpoints.go @@ -180,6 +180,9 @@ var defaultPartitions = endpoints.Partitions{ endpoints.EndpointKey{ Region: "ap-southeast-5", }: endpoints.Endpoint{}, + endpoints.EndpointKey{ + Region: "ap-southeast-6", + }: endpoints.Endpoint{}, endpoints.EndpointKey{ Region: "ap-southeast-7", }: endpoints.Endpoint{}, @@ -356,6 +359,13 @@ var defaultPartitions = endpoints.Partitions{ { ID: "aws-eusc", Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.DualStackVariant, + }: { + Hostname: "sts.{region}.api.amazonwebservices.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, { Variant: endpoints.FIPSVariant, }: { @@ -363,6 +373,13 @@ var defaultPartitions = endpoints.Partitions{ Protocols: []string{"https"}, SignatureVersions: []string{"v4"}, }, + { + Variant: endpoints.FIPSVariant | endpoints.DualStackVariant, + }: { + Hostname: "sts-fips.{region}.api.amazonwebservices.eu", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, { Variant: 0, }: { @@ -427,6 +444,9 @@ var defaultPartitions = endpoints.Partitions{ endpoints.EndpointKey{ Region: "us-isob-east-1", }: endpoints.Endpoint{}, + endpoints.EndpointKey{ + Region: "us-isob-west-1", + }: endpoints.Endpoint{}, }, }, { diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go index e1398f3bb8..f60b7d3381 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go @@ -119,12 +119,18 @@ type Options struct { // implementation if nil. HTTPClient HTTPClient + // Client registry of operation interceptors. + Interceptors smithyhttp.InterceptorRegistry + // The auth scheme resolver which determines how to authenticate for each // operation. AuthSchemeResolver AuthSchemeResolver // The list of auth schemes supported by the client. AuthSchemes []smithyhttp.AuthScheme + + // Priority list of preferred auth scheme names (e.g. sigv4a). + AuthSchemePreference []string } // Copy creates a clone where the APIOptions list is deep copied. @@ -132,6 +138,7 @@ func (o Options) Copy() Options { to := o to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) copy(to.APIOptions, o.APIOptions) + to.Interceptors = o.Interceptors.Copy() return to } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/serializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/serializers.go index 96b222136b..5e22738782 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/serializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/serializers.go @@ -502,6 +502,76 @@ func (m *awsAwsquery_serializeOpGetCallerIdentity) HandleSerialize(ctx context.C return next.HandleSerialize(ctx, in) } +type awsAwsquery_serializeOpGetDelegatedAccessToken struct { +} + +func (*awsAwsquery_serializeOpGetDelegatedAccessToken) ID() string { + return "OperationSerializer" +} + +func (m *awsAwsquery_serializeOpGetDelegatedAccessToken) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + _, span := tracing.StartSpan(ctx, "OperationSerializer") + endTimer := startMetricTimer(ctx, "client.call.serialization_duration") + defer endTimer() + defer span.End() + request, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} + } + + input, ok := in.Parameters.(*GetDelegatedAccessTokenInput) + _ = input + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} + } + + operationPath := "/" + if len(request.Request.URL.Path) == 0 { + request.Request.URL.Path = operationPath + } else { + request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) + if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { + request.Request.URL.Path += "/" + } + } + request.Request.Method = "POST" + httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") + + bodyWriter := bytes.NewBuffer(nil) + bodyEncoder := query.NewEncoder(bodyWriter) + body := bodyEncoder.Object() + body.Key("Action").String("GetDelegatedAccessToken") + body.Key("Version").String("2011-06-15") + + if err := awsAwsquery_serializeOpDocumentGetDelegatedAccessTokenInput(input, bodyEncoder.Value); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + err = bodyEncoder.Encode() + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + in.Request = request + + endTimer() + span.End() + return next.HandleSerialize(ctx, in) +} + type awsAwsquery_serializeOpGetFederationToken struct { } @@ -641,6 +711,76 @@ func (m *awsAwsquery_serializeOpGetSessionToken) HandleSerialize(ctx context.Con span.End() return next.HandleSerialize(ctx, in) } + +type awsAwsquery_serializeOpGetWebIdentityToken struct { +} + +func (*awsAwsquery_serializeOpGetWebIdentityToken) ID() string { + return "OperationSerializer" +} + +func (m *awsAwsquery_serializeOpGetWebIdentityToken) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + _, span := tracing.StartSpan(ctx, "OperationSerializer") + endTimer := startMetricTimer(ctx, "client.call.serialization_duration") + defer endTimer() + defer span.End() + request, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} + } + + input, ok := in.Parameters.(*GetWebIdentityTokenInput) + _ = input + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} + } + + operationPath := "/" + if len(request.Request.URL.Path) == 0 { + request.Request.URL.Path = operationPath + } else { + request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) + if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { + request.Request.URL.Path += "/" + } + } + request.Request.Method = "POST" + httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + httpBindingEncoder.SetHeader("Content-Type").String("application/x-www-form-urlencoded") + + bodyWriter := bytes.NewBuffer(nil) + bodyEncoder := query.NewEncoder(bodyWriter) + body := bodyEncoder.Object() + body.Key("Action").String("GetWebIdentityToken") + body.Key("Version").String("2011-06-15") + + if err := awsAwsquery_serializeOpDocumentGetWebIdentityTokenInput(input, bodyEncoder.Value); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + err = bodyEncoder.Encode() + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request, err = request.SetStream(bytes.NewReader(bodyWriter.Bytes())); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + in.Request = request + + endTimer() + span.End() + return next.HandleSerialize(ctx, in) +} func awsAwsquery_serializeDocumentPolicyDescriptorListType(v []types.PolicyDescriptorType, value query.Value) error { array := value.Array("member") @@ -733,6 +873,16 @@ func awsAwsquery_serializeDocumentTagListType(v []types.Tag, value query.Value) return nil } +func awsAwsquery_serializeDocumentWebIdentityTokenAudienceListType(v []string, value query.Value) error { + array := value.Array("member") + + for i := range v { + av := array.Value() + av.String(v[i]) + } + return nil +} + func awsAwsquery_serializeOpDocumentAssumeRoleInput(v *AssumeRoleInput, value query.Value) error { object := value.Object() _ = object @@ -946,6 +1096,18 @@ func awsAwsquery_serializeOpDocumentGetCallerIdentityInput(v *GetCallerIdentityI return nil } +func awsAwsquery_serializeOpDocumentGetDelegatedAccessTokenInput(v *GetDelegatedAccessTokenInput, value query.Value) error { + object := value.Object() + _ = object + + if v.TradeInToken != nil { + objectKey := object.Key("TradeInToken") + objectKey.String(*v.TradeInToken) + } + + return nil +} + func awsAwsquery_serializeOpDocumentGetFederationTokenInput(v *GetFederationTokenInput, value query.Value) error { object := value.Object() _ = object @@ -1003,3 +1165,34 @@ func awsAwsquery_serializeOpDocumentGetSessionTokenInput(v *GetSessionTokenInput return nil } + +func awsAwsquery_serializeOpDocumentGetWebIdentityTokenInput(v *GetWebIdentityTokenInput, value query.Value) error { + object := value.Object() + _ = object + + if v.Audience != nil { + objectKey := object.Key("Audience") + if err := awsAwsquery_serializeDocumentWebIdentityTokenAudienceListType(v.Audience, objectKey); err != nil { + return err + } + } + + if v.DurationSeconds != nil { + objectKey := object.Key("DurationSeconds") + objectKey.Integer(*v.DurationSeconds) + } + + if v.SigningAlgorithm != nil { + objectKey := object.Key("SigningAlgorithm") + objectKey.String(*v.SigningAlgorithm) + } + + if v.Tags != nil { + objectKey := object.Key("Tags") + if err := awsAwsquery_serializeDocumentTagListType(v.Tags, objectKey); err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go index 041629bba2..70d99a220b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go @@ -34,6 +34,33 @@ func (e *ExpiredTokenException) ErrorCode() string { } func (e *ExpiredTokenException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } +// The trade-in token provided in the request has expired and can no longer be +// exchanged for credentials. Request a new token and retry the operation. +type ExpiredTradeInTokenException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *ExpiredTradeInTokenException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *ExpiredTradeInTokenException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *ExpiredTradeInTokenException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "ExpiredTradeInTokenException" + } + return *e.ErrorCodeOverride +} +func (e *ExpiredTradeInTokenException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } + // The request could not be fulfilled because the identity provider (IDP) that was // asked to verify the incoming identity token could not be reached. This is often // a transient error caused by network conditions. Retry the request a limited @@ -152,6 +179,34 @@ func (e *InvalidIdentityTokenException) ErrorCode() string { } func (e *InvalidIdentityTokenException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } +// The requested token payload size exceeds the maximum allowed size. Reduce the +// number of request tags included in the GetWebIdentityToken API call to reduce +// the token payload size. +type JWTPayloadSizeExceededException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *JWTPayloadSizeExceededException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *JWTPayloadSizeExceededException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *JWTPayloadSizeExceededException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "JWTPayloadSizeExceededException" + } + return *e.ErrorCodeOverride +} +func (e *JWTPayloadSizeExceededException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } + // The request was rejected because the policy document was malformed. The error // message describes the specific error. type MalformedPolicyDocumentException struct { @@ -179,6 +234,36 @@ func (e *MalformedPolicyDocumentException) ErrorCode() string { } func (e *MalformedPolicyDocumentException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } +// The outbound web identity federation feature is not enabled for this account. +// To use this feature, you must first enable it through the Amazon Web Services +// Management Console or API. +type OutboundWebIdentityFederationDisabledException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *OutboundWebIdentityFederationDisabledException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *OutboundWebIdentityFederationDisabledException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *OutboundWebIdentityFederationDisabledException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "OutboundWebIdentityFederationDisabledException" + } + return *e.ErrorCodeOverride +} +func (e *OutboundWebIdentityFederationDisabledException) ErrorFault() smithy.ErrorFault { + return smithy.FaultClient +} + // The request was rejected because the total packed size of the session policies // and session tags combined was too large. An Amazon Web Services conversion // compresses the session policy document, session policy ARNs, and session tags @@ -221,7 +306,7 @@ func (e *PackedPolicyTooLargeException) ErrorFault() smithy.ErrorFault { return // console to activate STS in that region. For more information, see [Activating and Deactivating STS in an Amazon Web Services Region]in the IAM // User Guide. // -// [Activating and Deactivating STS in an Amazon Web Services Region]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html +// [Activating and Deactivating STS in an Amazon Web Services Region]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#sts-regions-activate-deactivate type RegionDisabledException struct { Message *string @@ -246,3 +331,33 @@ func (e *RegionDisabledException) ErrorCode() string { return *e.ErrorCodeOverride } func (e *RegionDisabledException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } + +// The requested token duration would extend the session beyond its original +// expiration time. You cannot use this operation to extend the lifetime of a +// session beyond what was granted when the session was originally created. +type SessionDurationEscalationException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *SessionDurationEscalationException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *SessionDurationEscalationException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *SessionDurationEscalationException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "SessionDurationEscalationException" + } + return *e.ErrorCodeOverride +} +func (e *SessionDurationEscalationException) ErrorFault() smithy.ErrorFault { + return smithy.FaultClient +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/validators.go b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/validators.go index 1026e22118..4d37dd22a1 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/sts/validators.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/sts/validators.go @@ -130,6 +130,26 @@ func (m *validateOpGetAccessKeyInfo) HandleInitialize(ctx context.Context, in mi return next.HandleInitialize(ctx, in) } +type validateOpGetDelegatedAccessToken struct { +} + +func (*validateOpGetDelegatedAccessToken) ID() string { + return "OperationInputValidation" +} + +func (m *validateOpGetDelegatedAccessToken) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + input, ok := in.Parameters.(*GetDelegatedAccessTokenInput) + if !ok { + return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) + } + if err := validateOpGetDelegatedAccessTokenInput(input); err != nil { + return out, metadata, err + } + return next.HandleInitialize(ctx, in) +} + type validateOpGetFederationToken struct { } @@ -150,6 +170,26 @@ func (m *validateOpGetFederationToken) HandleInitialize(ctx context.Context, in return next.HandleInitialize(ctx, in) } +type validateOpGetWebIdentityToken struct { +} + +func (*validateOpGetWebIdentityToken) ID() string { + return "OperationInputValidation" +} + +func (m *validateOpGetWebIdentityToken) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + input, ok := in.Parameters.(*GetWebIdentityTokenInput) + if !ok { + return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) + } + if err := validateOpGetWebIdentityTokenInput(input); err != nil { + return out, metadata, err + } + return next.HandleInitialize(ctx, in) +} + func addOpAssumeRoleValidationMiddleware(stack *middleware.Stack) error { return stack.Initialize.Add(&validateOpAssumeRole{}, middleware.After) } @@ -174,10 +214,18 @@ func addOpGetAccessKeyInfoValidationMiddleware(stack *middleware.Stack) error { return stack.Initialize.Add(&validateOpGetAccessKeyInfo{}, middleware.After) } +func addOpGetDelegatedAccessTokenValidationMiddleware(stack *middleware.Stack) error { + return stack.Initialize.Add(&validateOpGetDelegatedAccessToken{}, middleware.After) +} + func addOpGetFederationTokenValidationMiddleware(stack *middleware.Stack) error { return stack.Initialize.Add(&validateOpGetFederationToken{}, middleware.After) } +func addOpGetWebIdentityTokenValidationMiddleware(stack *middleware.Stack) error { + return stack.Initialize.Add(&validateOpGetWebIdentityToken{}, middleware.After) +} + func validateTag(v *types.Tag) error { if v == nil { return nil @@ -326,6 +374,21 @@ func validateOpGetAccessKeyInfoInput(v *GetAccessKeyInfoInput) error { } } +func validateOpGetDelegatedAccessTokenInput(v *GetDelegatedAccessTokenInput) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "GetDelegatedAccessTokenInput"} + if v.TradeInToken == nil { + invalidParams.Add(smithy.NewErrParamRequired("TradeInToken")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + func validateOpGetFederationTokenInput(v *GetFederationTokenInput) error { if v == nil { return nil @@ -345,3 +408,26 @@ func validateOpGetFederationTokenInput(v *GetFederationTokenInput) error { return nil } } + +func validateOpGetWebIdentityTokenInput(v *GetWebIdentityTokenInput) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "GetWebIdentityTokenInput"} + if v.Audience == nil { + invalidParams.Add(smithy.NewErrParamRequired("Audience")) + } + if v.SigningAlgorithm == nil { + invalidParams.Add(smithy.NewErrParamRequired("SigningAlgorithm")) + } + if v.Tags != nil { + if err := validateTagListType(v.Tags); err != nil { + invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) + } + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} diff --git a/vendor/github.com/aws/smithy-go/CHANGELOG.md b/vendor/github.com/aws/smithy-go/CHANGELOG.md index 4df632dce8..80af245f08 100644 --- a/vendor/github.com/aws/smithy-go/CHANGELOG.md +++ b/vendor/github.com/aws/smithy-go/CHANGELOG.md @@ -1,13 +1,72 @@ -# Release (2025-02-17) +# Release (2025-12-01) ## General Highlights * **Dependency Update**: Updated to the latest SDK module versions ## Module Highlights -* `github.com/aws/smithy-go`: v1.22.3 +* `github.com/aws/smithy-go`: v1.24.0 + * **Feature**: Improve allocation footprint of the middleware stack. This should convey a ~10% reduction in allocations per SDK request. + +# Release (2025-11-03) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.23.2 + * **Bug Fix**: Adjust the initial sizes of each middleware phase to avoid some unnecessary reallocation. + * **Bug Fix**: Avoid unnecessary allocation overhead from the metrics system when not in use. + +# Release (2025-10-15) + +## General Highlights +* **Dependency Update**: Bump minimum go version to 1.23. +* **Dependency Update**: Updated to the latest SDK module versions + +# Release (2025-09-18) + +## Module Highlights +* `github.com/aws/smithy-go/aws-http-auth`: [v1.1.0](aws-http-auth/CHANGELOG.md#v110-2025-09-18) + * **Feature**: Added support for SIG4/SIGV4A querystring authentication. + +# Release (2025-08-27) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.23.0 + * **Feature**: Sort map keys in JSON Document types. + +# Release (2025-07-24) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.22.5 + * **Feature**: Add HTTP interceptors. + +# Release (2025-06-16) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.22.4 + * **Bug Fix**: Fix CBOR serd empty check for string and enum fields * **Bug Fix**: Fix HTTP metrics data race. * **Bug Fix**: Replace usages of deprecated ioutil package. +# Release (2025-02-17) + +## General Highlights +* **Dependency Update**: Updated to the latest SDK module versions + +## Module Highlights +* `github.com/aws/smithy-go`: v1.22.3 + * **Dependency Update**: Bump minimum Go version to 1.22 per our language support policy. + # Release (2025-01-21) ## General Highlights diff --git a/vendor/github.com/aws/smithy-go/Makefile b/vendor/github.com/aws/smithy-go/Makefile index a3c2cf173d..a12b124d50 100644 --- a/vendor/github.com/aws/smithy-go/Makefile +++ b/vendor/github.com/aws/smithy-go/Makefile @@ -13,6 +13,7 @@ REPOTOOLS_CMD_GENERATE_CHANGELOG = ${REPOTOOLS_MODULE}/cmd/generatechangelog@${R REPOTOOLS_CMD_CHANGELOG = ${REPOTOOLS_MODULE}/cmd/changelog@${REPOTOOLS_VERSION} REPOTOOLS_CMD_TAG_RELEASE = ${REPOTOOLS_MODULE}/cmd/tagrelease@${REPOTOOLS_VERSION} REPOTOOLS_CMD_MODULE_VERSION = ${REPOTOOLS_MODULE}/cmd/moduleversion@${REPOTOOLS_VERSION} +REPOTOOLS_CMD_EACHMODULE = ${REPOTOOLS_MODULE}/cmd/eachmodule@${REPOTOOLS_VERSION} UNIT_TEST_TAGS= BUILD_TAGS= @@ -30,6 +31,24 @@ smithy-build: smithy-clean: cd codegen && ./gradlew clean +GRADLE_RETRIES := 3 +GRADLE_SLEEP := 2 + +# We're making a call to ./gradlew to trigger downloading Gradle and +# starting the daemon. Any call works, so using `./gradlew help` +ensure-gradle-up: + @cd codegen && for i in $(shell seq 1 $(GRADLE_RETRIES)); do \ + echo "Checking if Gradle daemon is up, attempt $$i..."; \ + if ./gradlew help; then \ + echo "Gradle daemon is up!"; \ + exit 0; \ + fi; \ + echo "Failed to start Gradle, retrying in $(GRADLE_SLEEP) seconds..."; \ + sleep $(GRADLE_SLEEP); \ + done; \ + echo "Failed to start Gradle after $(GRADLE_RETRIES) attempts."; \ + exit 1 + ################## # Linting/Verify # ################## @@ -37,8 +56,11 @@ smithy-clean: verify: vet -vet: - go vet ${BUILD_TAGS} --all ./... +vet: vet-modules-. + +vet-modules-%: + go run ${REPOTOOLS_CMD_EACHMODULE} -p $(subst vet-modules-,,$@) \ + "go vet ${BUILD_TAGS} --all ./..." cover: go test ${BUILD_TAGS} -coverprofile c.out ./... @@ -48,23 +70,22 @@ cover: ################ # Unit Testing # ################ -.PHONY: unit unit-race unit-test unit-race-test +.PHONY: test unit unit-race + +test: unit-race + +unit: verify unit-modules-. -unit: verify - go vet ${BUILD_TAGS} --all ./... && \ - go test ${BUILD_TAGS} ${RUN_NONE} ./... && \ - go test -timeout=1m ${UNIT_TEST_TAGS} ./... +unit-modules-%: + go run ${REPOTOOLS_CMD_EACHMODULE} -p $(subst unit-modules-,,$@) \ + "go test -timeout=1m ${UNIT_TEST_TAGS} ./..." -unit-race: verify - go vet ${BUILD_TAGS} --all ./... && \ - go test ${BUILD_TAGS} ${RUN_NONE} ./... && \ - go test -timeout=1m ${UNIT_TEST_TAGS} -race -cpu=4 ./... +unit-race: verify unit-race-modules-. -unit-test: verify - go test -timeout=1m ${UNIT_TEST_TAGS} ./... +unit-race-modules-%: + go run ${REPOTOOLS_CMD_EACHMODULE} -p $(subst unit-race-modules-,,$@) \ + "go test -timeout=1m ${UNIT_TEST_TAGS} -race -cpu=4 ./..." -unit-race-test: verify - go test -timeout=1m ${UNIT_TEST_TAGS} -race -cpu=4 ./... ##################### # Release Process # diff --git a/vendor/github.com/aws/smithy-go/README.md b/vendor/github.com/aws/smithy-go/README.md index 08df74589a..ddce37b99e 100644 --- a/vendor/github.com/aws/smithy-go/README.md +++ b/vendor/github.com/aws/smithy-go/README.md @@ -4,19 +4,21 @@ [Smithy](https://smithy.io/) code generators for Go and the accompanying smithy-go runtime. -The smithy-go runtime requires a minimum version of Go 1.20. +The smithy-go runtime requires a minimum version of Go 1.23. **WARNING: All interfaces are subject to change.** -## Can I use the code generators? +## :no_entry_sign: DO NOT use the code generators in this repository + +**The code generators in this repository do not generate working clients at +this time.** In order to generate a usable smithy client you must provide a [protocol definition](https://github.com/aws/smithy-go/blob/main/codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/integration/ProtocolGenerator.java), such as [AWS restJson1](https://smithy.io/2.0/aws/protocols/aws-restjson1-protocol.html), in order to generate transport mechanisms and serialization/deserialization code ("serde") accordingly. -The code generator does not currently support any protocols out of the box other than the new `smithy.protocols#rpcv2Cbor`, -therefore the useability of this project on its own is currently limited. +The code generator does not currently support any protocols out of the box. Support for all [AWS protocols](https://smithy.io/2.0/aws/protocols/index.html) exists in [aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2). We are tracking the movement of those out of the SDK into smithy-go in @@ -31,6 +33,7 @@ This repository implements the following Smithy build plugins: |----|------------|-------------| | `go-codegen` | `software.amazon.smithy.go:smithy-go-codegen` | Implements Go client code generation for Smithy models. | | `go-server-codegen` | `software.amazon.smithy.go:smithy-go-codegen` | Implements Go server code generation for Smithy models. | +| `go-shape-codegen` | `software.amazon.smithy.go:smithy-go-codegen` | Implements Go shape code generation (types only) for Smithy models. | **NOTE: Build plugins are not currently published to mavenCentral. You must publish to mavenLocal to make the build plugins visible to the Smithy CLI. The artifact version is currently fixed at 0.1.0.** @@ -77,7 +80,7 @@ example created from `smithy init`: "service": "example.weather#Weather", "module": "github.com/example/weather", "generateGoMod": true, - "goDirective": "1.20" + "goDirective": "1.23" } } } @@ -87,6 +90,10 @@ example created from `smithy init`: This plugin is a work-in-progress and is currently undocumented. +## `go-shape-codegen` + +This plugin is a work-in-progress and is currently undocumented. + ## License This project is licensed under the Apache-2.0 License. diff --git a/vendor/github.com/aws/smithy-go/endpoints/endpoint.go b/vendor/github.com/aws/smithy-go/endpoints/endpoint.go index a935283974..f778272be3 100644 --- a/vendor/github.com/aws/smithy-go/endpoints/endpoint.go +++ b/vendor/github.com/aws/smithy-go/endpoints/endpoint.go @@ -9,7 +9,7 @@ import ( // Endpoint is the endpoint object returned by Endpoint resolution V2 type Endpoint struct { - // The complete URL minimally specfiying the scheme and host. + // The complete URL minimally specifying the scheme and host. // May optionally specify the port and base path component. URI url.URL diff --git a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/doc.go b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/doc.go new file mode 100644 index 0000000000..e24e190dca --- /dev/null +++ b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/doc.go @@ -0,0 +1,4 @@ +// Package rulesfn provides endpoint rule functions for evaluating endpoint +// resolution rules. + +package rulesfn diff --git a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/strings.go b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/strings.go new file mode 100644 index 0000000000..5cf4a7b02d --- /dev/null +++ b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/strings.go @@ -0,0 +1,25 @@ +package rulesfn + +// Substring returns the substring of the input provided. If the start or stop +// indexes are not valid for the input nil will be returned. If errors occur +// they will be added to the provided [ErrorCollector]. +func SubString(input string, start, stop int, reverse bool) *string { + if start < 0 || stop < 1 || start >= stop || len(input) < stop { + return nil + } + + for _, r := range input { + if r > 127 { + return nil + } + } + + if !reverse { + v := input[start:stop] + return &v + } + + rStart := len(input) - stop + rStop := len(input) - start + return SubString(input, rStart, rStop, false) +} diff --git a/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go new file mode 100644 index 0000000000..0c11541276 --- /dev/null +++ b/vendor/github.com/aws/smithy-go/endpoints/private/rulesfn/uri.go @@ -0,0 +1,130 @@ +package rulesfn + +import ( + "fmt" + "net" + "net/url" + "strings" + + smithyhttp "github.com/aws/smithy-go/transport/http" +) + +// IsValidHostLabel returns if the input is a single valid [RFC 1123] host +// label. If allowSubDomains is true, will allow validation to include nested +// host labels. Returns false if the input is not a valid host label. If errors +// occur they will be added to the provided [ErrorCollector]. +// +// [RFC 1123]: https://www.ietf.org/rfc/rfc1123.txt +func IsValidHostLabel(input string, allowSubDomains bool) bool { + var labels []string + if allowSubDomains { + labels = strings.Split(input, ".") + } else { + labels = []string{input} + } + + for _, label := range labels { + if !smithyhttp.ValidHostLabel(label) { + return false + } + } + + return true +} + +// ParseURL returns a [URL] if the provided string could be parsed. Returns nil +// if the string could not be parsed. Any parsing error will be added to the +// [ErrorCollector]. +// +// If the input URL string contains an IP6 address with a zone index. The +// returned [builtin.URL.Authority] value will contain the percent escaped (%) +// zone index separator. +func ParseURL(input string) *URL { + u, err := url.Parse(input) + if err != nil { + return nil + } + + if u.RawQuery != "" { + return nil + } + + if u.Scheme != "http" && u.Scheme != "https" { + return nil + } + + normalizedPath := u.Path + if !strings.HasPrefix(normalizedPath, "/") { + normalizedPath = "/" + normalizedPath + } + if !strings.HasSuffix(normalizedPath, "/") { + normalizedPath = normalizedPath + "/" + } + + // IP6 hosts may have zone indexes that need to be escaped to be valid in a + // URI. The Go URL parser will unescape the `%25` into `%`. This needs to + // be reverted since the returned URL will be used in string builders. + authority := strings.ReplaceAll(u.Host, "%", "%25") + + return &URL{ + Scheme: u.Scheme, + Authority: authority, + Path: u.Path, + NormalizedPath: normalizedPath, + IsIp: net.ParseIP(hostnameWithoutZone(u)) != nil, + } +} + +// URL provides the structure describing the parts of a parsed URL returned by +// [ParseURL]. +type URL struct { + Scheme string // https://www.rfc-editor.org/rfc/rfc3986#section-3.1 + Authority string // https://www.rfc-editor.org/rfc/rfc3986#section-3.2 + Path string // https://www.rfc-editor.org/rfc/rfc3986#section-3.3 + NormalizedPath string // https://www.rfc-editor.org/rfc/rfc3986#section-6.2.3 + IsIp bool +} + +// URIEncode returns an percent-encoded [RFC3986 section 2.1] version of the +// input string. +// +// [RFC3986 section 2.1]: https://www.rfc-editor.org/rfc/rfc3986#section-2.1 +func URIEncode(input string) string { + var output strings.Builder + for _, c := range []byte(input) { + if validPercentEncodedChar(c) { + output.WriteByte(c) + continue + } + + fmt.Fprintf(&output, "%%%X", c) + } + + return output.String() +} + +func validPercentEncodedChar(c byte) bool { + return (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '-' || c == '_' || c == '.' || c == '~' +} + +// hostname implements u.Hostname() but strips the ipv6 zone ID (if present) +// such that net.ParseIP can still recognize IPv6 addresses with zone IDs. +// +// FUTURE(10/2023): netip.ParseAddr handles this natively but we can't take +// that package as a dependency yet due to our min go version (1.15, netip +// starts in 1.18). When we align with go runtime deprecation policy in +// 10/2023, we can remove this. +func hostnameWithoutZone(u *url.URL) string { + full := u.Hostname() + + // this more or less mimics the internals of net/ (see unexported + // splitHostZone in that source) but throws the zone away because we don't + // need it + if i := strings.LastIndex(full, "%"); i > -1 { + return full[:i] + } + return full +} diff --git a/vendor/github.com/aws/smithy-go/go_module_metadata.go b/vendor/github.com/aws/smithy-go/go_module_metadata.go index d12d95891d..b6c4c2f51c 100644 --- a/vendor/github.com/aws/smithy-go/go_module_metadata.go +++ b/vendor/github.com/aws/smithy-go/go_module_metadata.go @@ -3,4 +3,4 @@ package smithy // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.22.3" +const goModuleVersion = "1.24.0" diff --git a/vendor/github.com/aws/smithy-go/metrics/nop.go b/vendor/github.com/aws/smithy-go/metrics/nop.go index fb374e1fb8..444126df5a 100644 --- a/vendor/github.com/aws/smithy-go/metrics/nop.go +++ b/vendor/github.com/aws/smithy-go/metrics/nop.go @@ -9,54 +9,82 @@ var _ MeterProvider = (*NopMeterProvider)(nil) // Meter returns a meter which creates no-op instruments. func (NopMeterProvider) Meter(string, ...MeterOption) Meter { - return nopMeter{} + return NopMeter{} } -type nopMeter struct{} +// NopMeter creates no-op instruments. +type NopMeter struct{} -var _ Meter = (*nopMeter)(nil) +var _ Meter = (*NopMeter)(nil) -func (nopMeter) Int64Counter(string, ...InstrumentOption) (Int64Counter, error) { - return nopInstrument[int64]{}, nil +// Int64Counter creates a no-op instrument. +func (NopMeter) Int64Counter(string, ...InstrumentOption) (Int64Counter, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Int64UpDownCounter(string, ...InstrumentOption) (Int64UpDownCounter, error) { - return nopInstrument[int64]{}, nil + +// Int64UpDownCounter creates a no-op instrument. +func (NopMeter) Int64UpDownCounter(string, ...InstrumentOption) (Int64UpDownCounter, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Int64Gauge(string, ...InstrumentOption) (Int64Gauge, error) { - return nopInstrument[int64]{}, nil + +// Int64Gauge creates a no-op instrument. +func (NopMeter) Int64Gauge(string, ...InstrumentOption) (Int64Gauge, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Int64Histogram(string, ...InstrumentOption) (Int64Histogram, error) { - return nopInstrument[int64]{}, nil + +// Int64Histogram creates a no-op instrument. +func (NopMeter) Int64Histogram(string, ...InstrumentOption) (Int64Histogram, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Int64AsyncCounter(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrument[int64]{}, nil + +// Int64AsyncCounter creates a no-op instrument. +func (NopMeter) Int64AsyncCounter(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Int64AsyncUpDownCounter(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrument[int64]{}, nil + +// Int64AsyncUpDownCounter creates a no-op instrument. +func (NopMeter) Int64AsyncUpDownCounter(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Int64AsyncGauge(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrument[int64]{}, nil + +// Int64AsyncGauge creates a no-op instrument. +func (NopMeter) Int64AsyncGauge(string, Int64Callback, ...InstrumentOption) (AsyncInstrument, error) { + return nopInstrumentInt64, nil } -func (nopMeter) Float64Counter(string, ...InstrumentOption) (Float64Counter, error) { - return nopInstrument[float64]{}, nil + +// Float64Counter creates a no-op instrument. +func (NopMeter) Float64Counter(string, ...InstrumentOption) (Float64Counter, error) { + return nopInstrumentFloat64, nil } -func (nopMeter) Float64UpDownCounter(string, ...InstrumentOption) (Float64UpDownCounter, error) { - return nopInstrument[float64]{}, nil + +// Float64UpDownCounter creates a no-op instrument. +func (NopMeter) Float64UpDownCounter(string, ...InstrumentOption) (Float64UpDownCounter, error) { + return nopInstrumentFloat64, nil } -func (nopMeter) Float64Gauge(string, ...InstrumentOption) (Float64Gauge, error) { - return nopInstrument[float64]{}, nil + +// Float64Gauge creates a no-op instrument. +func (NopMeter) Float64Gauge(string, ...InstrumentOption) (Float64Gauge, error) { + return nopInstrumentFloat64, nil } -func (nopMeter) Float64Histogram(string, ...InstrumentOption) (Float64Histogram, error) { - return nopInstrument[float64]{}, nil + +// Float64Histogram creates a no-op instrument. +func (NopMeter) Float64Histogram(string, ...InstrumentOption) (Float64Histogram, error) { + return nopInstrumentFloat64, nil } -func (nopMeter) Float64AsyncCounter(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrument[float64]{}, nil + +// Float64AsyncCounter creates a no-op instrument. +func (NopMeter) Float64AsyncCounter(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { + return nopInstrumentFloat64, nil } -func (nopMeter) Float64AsyncUpDownCounter(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrument[float64]{}, nil + +// Float64AsyncUpDownCounter creates a no-op instrument. +func (NopMeter) Float64AsyncUpDownCounter(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { + return nopInstrumentFloat64, nil } -func (nopMeter) Float64AsyncGauge(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { - return nopInstrument[float64]{}, nil + +// Float64AsyncGauge creates a no-op instrument. +func (NopMeter) Float64AsyncGauge(string, Float64Callback, ...InstrumentOption) (AsyncInstrument, error) { + return nopInstrumentFloat64, nil } type nopInstrument[N any] struct{} @@ -65,3 +93,6 @@ func (nopInstrument[N]) Add(context.Context, N, ...RecordMetricOption) {} func (nopInstrument[N]) Sample(context.Context, N, ...RecordMetricOption) {} func (nopInstrument[N]) Record(context.Context, N, ...RecordMetricOption) {} func (nopInstrument[_]) Stop() {} + +var nopInstrumentInt64 = nopInstrument[int64]{} +var nopInstrumentFloat64 = nopInstrument[float64]{} diff --git a/vendor/github.com/aws/smithy-go/middleware/ordered_group.go b/vendor/github.com/aws/smithy-go/middleware/ordered_group.go index 4b195308c5..daf90136e9 100644 --- a/vendor/github.com/aws/smithy-go/middleware/ordered_group.go +++ b/vendor/github.com/aws/smithy-go/middleware/ordered_group.go @@ -23,12 +23,14 @@ type orderedIDs struct { items map[string]ider } -const baseOrderedItems = 5 +// selected based on the general upper bound of # of middlewares in each step +// in the downstream aws-sdk-go-v2 +const baseOrderedItems = 8 -func newOrderedIDs() *orderedIDs { +func newOrderedIDs(cap int) *orderedIDs { return &orderedIDs{ - order: newRelativeOrder(), - items: make(map[string]ider, baseOrderedItems), + order: newRelativeOrder(cap), + items: make(map[string]ider, cap), } } @@ -141,9 +143,9 @@ type relativeOrder struct { order []string } -func newRelativeOrder() *relativeOrder { +func newRelativeOrder(cap int) *relativeOrder { return &relativeOrder{ - order: make([]string, 0, baseOrderedItems), + order: make([]string, 0, cap), } } diff --git a/vendor/github.com/aws/smithy-go/middleware/step_build.go b/vendor/github.com/aws/smithy-go/middleware/step_build.go index 7e1d94caee..db8c26715c 100644 --- a/vendor/github.com/aws/smithy-go/middleware/step_build.go +++ b/vendor/github.com/aws/smithy-go/middleware/step_build.go @@ -1,7 +1,9 @@ +// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. package middleware import ( "context" + "fmt" ) // BuildInput provides the input parameters for the BuildMiddleware to consume. @@ -25,14 +27,14 @@ type BuildHandler interface { } // BuildMiddleware provides the interface for middleware specific to the -// serialize step. Delegates to the next BuildHandler for further +// build step. Delegates to the next BuildHandler for further // processing. type BuildMiddleware interface { - // Unique ID for the middleware in theBuildStep. The step does not allow - // duplicate IDs. + // ID returns a unique ID for the middleware in the BuildStep. The step does not + // allow duplicate IDs. ID() string - // Invokes the middleware behavior which must delegate to the next handler + // HandleBuild invokes the middleware behavior which must delegate to the next handler // for the middleware chain to continue. The method must return a result or // error to its caller. HandleBuild(ctx context.Context, in BuildInput, next BuildHandler) ( @@ -54,7 +56,9 @@ type buildMiddlewareFunc struct { id string // Middleware function to be called. - fn func(context.Context, BuildInput, BuildHandler) (BuildOutput, Metadata, error) + fn func(context.Context, BuildInput, BuildHandler) ( + BuildOutput, Metadata, error, + ) } // ID returns the unique ID for the middleware. @@ -69,23 +73,22 @@ func (s buildMiddlewareFunc) HandleBuild(ctx context.Context, in BuildInput, nex var _ BuildMiddleware = (buildMiddlewareFunc{}) -// BuildStep provides the ordered grouping of BuildMiddleware to be invoked on -// a handler. +// BuildStep provides the ordered grouping of BuildMiddleware to be +// invoked on a handler. type BuildStep struct { - ids *orderedIDs + head *decoratedBuildHandler + tail *decoratedBuildHandler } -// NewBuildStep returns a BuildStep ready to have middleware for -// initialization added to it. +// NewBuildStep returns an BuildStep ready to have middleware for +// build added to it. func NewBuildStep() *BuildStep { - return &BuildStep{ - ids: newOrderedIDs(), - } + return &BuildStep{} } var _ Middleware = (*BuildStep)(nil) -// ID returns the unique name of the step as a middleware. +// ID returns the unique ID of the step as a middleware. func (s *BuildStep) ID() string { return "Build stack step" } @@ -97,77 +100,161 @@ func (s *BuildStep) ID() string { func (s *BuildStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( out interface{}, metadata Metadata, err error, ) { - order := s.ids.GetOrder() - - var h BuildHandler = buildWrapHandler{Next: next} - for i := len(order) - 1; i >= 0; i-- { - h = decoratedBuildHandler{ - Next: h, - With: order[i].(BuildMiddleware), - } - } - sIn := BuildInput{ Request: in, } - res, metadata, err := h.HandleBuild(ctx, sIn) + wh := &buildWrapHandler{next} + if s.head == nil { + res, metadata, err := wh.HandleBuild(ctx, sIn) + return res.Result, metadata, err + } + + s.tail.Next = wh + res, metadata, err := s.head.HandleBuild(ctx, sIn) return res.Result, metadata, err } // Get retrieves the middleware identified by id. If the middleware is not present, returns false. func (s *BuildStep) Get(id string) (BuildMiddleware, bool) { - get, ok := s.ids.Get(id) - if !ok { + found, _ := s.get(id) + if found == nil { return nil, false } - return get.(BuildMiddleware), ok + + return found.With, true } // Add injects the middleware to the relative position of the middleware group. -// Returns an error if the middleware already exists. +// +// Add never returns an error. It used to for duplicate phases but this +// behavior has since been removed as part of a performance optimization. The +// return value from Add can be ignored. func (s *BuildStep) Add(m BuildMiddleware, pos RelativePosition) error { - return s.ids.Add(m, pos) + if s.head == nil { + s.head = &decoratedBuildHandler{nil, m} + s.tail = s.head + return nil + } + + if pos == Before { + s.head = &decoratedBuildHandler{s.head, m} + } else { + tail := &decoratedBuildHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } + + return nil } -// Insert injects the middleware relative to an existing middleware id. -// Returns an error if the original middleware does not exist, or the middleware +// Insert injects the middleware relative to an existing middleware ID. +// Returns error if the original middleware does not exist, or the middleware // being added already exists. func (s *BuildStep) Insert(m BuildMiddleware, relativeTo string, pos RelativePosition) error { - return s.ids.Insert(m, relativeTo, pos) + found, prev := s.get(relativeTo) + if found == nil { + return fmt.Errorf("not found: %s", m.ID()) + } + + if pos == Before { + if prev == nil { // at the front + s.head = &decoratedBuildHandler{s.head, m} + } else { // somewhere in the middle + prev.Next = &decoratedBuildHandler{found, m} + } + } else { + if found.Next == nil { // at the end + tail := &decoratedBuildHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } else { // somewhere in the middle + found.Next = &decoratedBuildHandler{found.Next, m} + } + } + + return nil } // Swap removes the middleware by id, replacing it with the new middleware. -// Returns the middleware removed, or an error if the middleware to be removed +// Returns the middleware removed, or error if the middleware to be removed // doesn't exist. func (s *BuildStep) Swap(id string, m BuildMiddleware) (BuildMiddleware, error) { - removed, err := s.ids.Swap(id, m) - if err != nil { - return nil, err + found, _ := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", m.ID()) } - return removed.(BuildMiddleware), nil + swapped := found.With + found.With = m + return swapped, nil } // Remove removes the middleware by id. Returns error if the middleware // doesn't exist. func (s *BuildStep) Remove(id string) (BuildMiddleware, error) { - removed, err := s.ids.Remove(id) - if err != nil { - return nil, err + found, prev := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", id) } - return removed.(BuildMiddleware), nil + if s.head == s.tail { // it's the only one + s.head = nil + s.tail = nil + } else if found == s.head { // at the front + s.head = s.head.Next.(*decoratedBuildHandler) + } else if found == s.tail { // at the end + prev.Next = nil + s.tail = prev + } else { + prev.Next = found.Next // somewhere in the middle + } + + return found.With, nil } // List returns a list of the middleware in the step. func (s *BuildStep) List() []string { - return s.ids.List() + var ids []string + for h := s.head; h != nil; { + ids = append(ids, h.With.ID()) + if h.Next == nil { + break + } + + // once executed, tail.Next of the list will be set to an + // *buildWrapHandler, make sure to check for that + if hnext, ok := h.Next.(*decoratedBuildHandler); ok { + h = hnext + } else { + break + } + } + return ids } // Clear removes all middleware in the step. func (s *BuildStep) Clear() { - s.ids.Clear() + s.head = nil + s.tail = nil +} + +func (s *BuildStep) get(id string) (found, prev *decoratedBuildHandler) { + for h := s.head; h != nil; { + if h.With.ID() == id { + found = h + return + } + prev = h + if h.Next == nil { + return + } + + // once executed, tail.Next of the list will be set to an + // *buildWrapHandler + h, _ = h.Next.(*decoratedBuildHandler) + } + return } type buildWrapHandler struct { @@ -176,7 +263,7 @@ type buildWrapHandler struct { var _ BuildHandler = (*buildWrapHandler)(nil) -// Implements BuildHandler, converts types and delegates to underlying +// HandleBuild implements BuildHandler, converts types and delegates to underlying // generic handler. func (w buildWrapHandler) HandleBuild(ctx context.Context, in BuildInput) ( out BuildOutput, metadata Metadata, err error, @@ -200,12 +287,12 @@ func (h decoratedBuildHandler) HandleBuild(ctx context.Context, in BuildInput) ( return h.With.HandleBuild(ctx, in, h.Next) } -// BuildHandlerFunc provides a wrapper around a function to be used as a build middleware handler. +// BuildHandlerFunc provides a wrapper around a function to be used as buildMiddleware. type BuildHandlerFunc func(context.Context, BuildInput) (BuildOutput, Metadata, error) -// HandleBuild invokes the wrapped function with the provided arguments. -func (b BuildHandlerFunc) HandleBuild(ctx context.Context, in BuildInput) (BuildOutput, Metadata, error) { - return b(ctx, in) +// HandleBuild calls the wrapped function with the provided arguments. +func (f BuildHandlerFunc) HandleBuild(ctx context.Context, in BuildInput) (BuildOutput, Metadata, error) { + return f(ctx, in) } var _ BuildHandler = BuildHandlerFunc(nil) diff --git a/vendor/github.com/aws/smithy-go/middleware/step_deserialize.go b/vendor/github.com/aws/smithy-go/middleware/step_deserialize.go index 4486072157..1f337f2dbc 100644 --- a/vendor/github.com/aws/smithy-go/middleware/step_deserialize.go +++ b/vendor/github.com/aws/smithy-go/middleware/step_deserialize.go @@ -1,7 +1,9 @@ +// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. package middleware import ( "context" + "fmt" ) // DeserializeInput provides the input parameters for the DeserializeInput to @@ -11,10 +13,7 @@ type DeserializeInput struct { Request interface{} } -// DeserializeOutput provides the result returned by the next -// DeserializeHandler. The DeserializeMiddleware should deserialize the -// RawResponse into a Result that can be consumed by middleware higher up in -// the stack. +// DeserializeOutput provides the result returned by the next DeserializeHandler. type DeserializeOutput struct { RawResponse interface{} Result interface{} @@ -29,7 +28,7 @@ type DeserializeHandler interface { } // DeserializeMiddleware provides the interface for middleware specific to the -// serialize step. Delegates to the next DeserializeHandler for further +// deserialize step. Delegates to the next DeserializeHandler for further // processing. type DeserializeMiddleware interface { // ID returns a unique ID for the middleware in the DeserializeStep. The step does not @@ -44,8 +43,8 @@ type DeserializeMiddleware interface { ) } -// DeserializeMiddlewareFunc returns a DeserializeMiddleware with the unique ID -// provided, and the func to be invoked. +// DeserializeMiddlewareFunc returns a DeserializeMiddleware with the unique ID provided, +// and the func to be invoked. func DeserializeMiddlewareFunc(id string, fn func(context.Context, DeserializeInput, DeserializeHandler) (DeserializeOutput, Metadata, error)) DeserializeMiddleware { return deserializeMiddlewareFunc{ id: id, @@ -78,15 +77,14 @@ var _ DeserializeMiddleware = (deserializeMiddlewareFunc{}) // DeserializeStep provides the ordered grouping of DeserializeMiddleware to be // invoked on a handler. type DeserializeStep struct { - ids *orderedIDs + head *decoratedDeserializeHandler + tail *decoratedDeserializeHandler } -// NewDeserializeStep returns a DeserializeStep ready to have middleware for -// initialization added to it. +// NewDeserializeStep returns an DeserializeStep ready to have middleware for +// deserialize added to it. func NewDeserializeStep() *DeserializeStep { - return &DeserializeStep{ - ids: newOrderedIDs(), - } + return &DeserializeStep{} } var _ Middleware = (*DeserializeStep)(nil) @@ -103,77 +101,161 @@ func (s *DeserializeStep) ID() string { func (s *DeserializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( out interface{}, metadata Metadata, err error, ) { - order := s.ids.GetOrder() - - var h DeserializeHandler = deserializeWrapHandler{Next: next} - for i := len(order) - 1; i >= 0; i-- { - h = decoratedDeserializeHandler{ - Next: h, - With: order[i].(DeserializeMiddleware), - } - } - sIn := DeserializeInput{ Request: in, } - res, metadata, err := h.HandleDeserialize(ctx, sIn) + wh := &deserializeWrapHandler{next} + if s.head == nil { + res, metadata, err := wh.HandleDeserialize(ctx, sIn) + return res.Result, metadata, err + } + + s.tail.Next = wh + res, metadata, err := s.head.HandleDeserialize(ctx, sIn) return res.Result, metadata, err } // Get retrieves the middleware identified by id. If the middleware is not present, returns false. func (s *DeserializeStep) Get(id string) (DeserializeMiddleware, bool) { - get, ok := s.ids.Get(id) - if !ok { + found, _ := s.get(id) + if found == nil { return nil, false } - return get.(DeserializeMiddleware), ok + + return found.With, true } // Add injects the middleware to the relative position of the middleware group. -// Returns an error if the middleware already exists. +// +// Add never returns an error. It used to for duplicate phases but this +// behavior has since been removed as part of a performance optimization. The +// return value from Add can be ignored. func (s *DeserializeStep) Add(m DeserializeMiddleware, pos RelativePosition) error { - return s.ids.Add(m, pos) + if s.head == nil { + s.head = &decoratedDeserializeHandler{nil, m} + s.tail = s.head + return nil + } + + if pos == Before { + s.head = &decoratedDeserializeHandler{s.head, m} + } else { + tail := &decoratedDeserializeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } + + return nil } // Insert injects the middleware relative to an existing middleware ID. // Returns error if the original middleware does not exist, or the middleware // being added already exists. func (s *DeserializeStep) Insert(m DeserializeMiddleware, relativeTo string, pos RelativePosition) error { - return s.ids.Insert(m, relativeTo, pos) + found, prev := s.get(relativeTo) + if found == nil { + return fmt.Errorf("not found: %s", m.ID()) + } + + if pos == Before { + if prev == nil { // at the front + s.head = &decoratedDeserializeHandler{s.head, m} + } else { // somewhere in the middle + prev.Next = &decoratedDeserializeHandler{found, m} + } + } else { + if found.Next == nil { // at the end + tail := &decoratedDeserializeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } else { // somewhere in the middle + found.Next = &decoratedDeserializeHandler{found.Next, m} + } + } + + return nil } // Swap removes the middleware by id, replacing it with the new middleware. // Returns the middleware removed, or error if the middleware to be removed // doesn't exist. func (s *DeserializeStep) Swap(id string, m DeserializeMiddleware) (DeserializeMiddleware, error) { - removed, err := s.ids.Swap(id, m) - if err != nil { - return nil, err + found, _ := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", m.ID()) } - return removed.(DeserializeMiddleware), nil + swapped := found.With + found.With = m + return swapped, nil } // Remove removes the middleware by id. Returns error if the middleware // doesn't exist. func (s *DeserializeStep) Remove(id string) (DeserializeMiddleware, error) { - removed, err := s.ids.Remove(id) - if err != nil { - return nil, err + found, prev := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", id) + } + + if s.head == s.tail { // it's the only one + s.head = nil + s.tail = nil + } else if found == s.head { // at the front + s.head = s.head.Next.(*decoratedDeserializeHandler) + } else if found == s.tail { // at the end + prev.Next = nil + s.tail = prev + } else { + prev.Next = found.Next // somewhere in the middle } - return removed.(DeserializeMiddleware), nil + return found.With, nil } // List returns a list of the middleware in the step. func (s *DeserializeStep) List() []string { - return s.ids.List() + var ids []string + for h := s.head; h != nil; { + ids = append(ids, h.With.ID()) + if h.Next == nil { + break + } + + // once executed, tail.Next of the list will be set to an + // *deserializeWrapHandler, make sure to check for that + if hnext, ok := h.Next.(*decoratedDeserializeHandler); ok { + h = hnext + } else { + break + } + } + return ids } // Clear removes all middleware in the step. func (s *DeserializeStep) Clear() { - s.ids.Clear() + s.head = nil + s.tail = nil +} + +func (s *DeserializeStep) get(id string) (found, prev *decoratedDeserializeHandler) { + for h := s.head; h != nil; { + if h.With.ID() == id { + found = h + return + } + prev = h + if h.Next == nil { + return + } + + // once executed, tail.Next of the list will be set to an + // *deserializeWrapHandler + h, _ = h.Next.(*decoratedDeserializeHandler) + } + return } type deserializeWrapHandler struct { @@ -187,9 +269,10 @@ var _ DeserializeHandler = (*deserializeWrapHandler)(nil) func (w deserializeWrapHandler) HandleDeserialize(ctx context.Context, in DeserializeInput) ( out DeserializeOutput, metadata Metadata, err error, ) { - resp, metadata, err := w.Next.Handle(ctx, in.Request) + res, metadata, err := w.Next.Handle(ctx, in.Request) return DeserializeOutput{ - RawResponse: resp, + RawResponse: res, + Result: nil, }, metadata, err } @@ -206,12 +289,12 @@ func (h decoratedDeserializeHandler) HandleDeserialize(ctx context.Context, in D return h.With.HandleDeserialize(ctx, in, h.Next) } -// DeserializeHandlerFunc provides a wrapper around a function to be used as a deserialize middleware handler. +// DeserializeHandlerFunc provides a wrapper around a function to be used as deserializeMiddleware. type DeserializeHandlerFunc func(context.Context, DeserializeInput) (DeserializeOutput, Metadata, error) -// HandleDeserialize invokes the wrapped function with the given arguments. -func (d DeserializeHandlerFunc) HandleDeserialize(ctx context.Context, in DeserializeInput) (DeserializeOutput, Metadata, error) { - return d(ctx, in) +// HandleDeserialize calls the wrapped function with the provided arguments. +func (f DeserializeHandlerFunc) HandleDeserialize(ctx context.Context, in DeserializeInput) (DeserializeOutput, Metadata, error) { + return f(ctx, in) } var _ DeserializeHandler = DeserializeHandlerFunc(nil) diff --git a/vendor/github.com/aws/smithy-go/middleware/step_finalize.go b/vendor/github.com/aws/smithy-go/middleware/step_finalize.go index 065e3885de..1a0ad9fb88 100644 --- a/vendor/github.com/aws/smithy-go/middleware/step_finalize.go +++ b/vendor/github.com/aws/smithy-go/middleware/step_finalize.go @@ -1,6 +1,10 @@ +// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. package middleware -import "context" +import ( + "context" + "fmt" +) // FinalizeInput provides the input parameters for the FinalizeMiddleware to // consume. FinalizeMiddleware may modify the Request value before forwarding @@ -23,7 +27,7 @@ type FinalizeHandler interface { } // FinalizeMiddleware provides the interface for middleware specific to the -// serialize step. Delegates to the next FinalizeHandler for further +// finalize step. Delegates to the next FinalizeHandler for further // processing. type FinalizeMiddleware interface { // ID returns a unique ID for the middleware in the FinalizeStep. The step does not @@ -38,8 +42,8 @@ type FinalizeMiddleware interface { ) } -// FinalizeMiddlewareFunc returns a FinalizeMiddleware with the unique ID -// provided, and the func to be invoked. +// FinalizeMiddlewareFunc returns a FinalizeMiddleware with the unique ID provided, +// and the func to be invoked. func FinalizeMiddlewareFunc(id string, fn func(context.Context, FinalizeInput, FinalizeHandler) (FinalizeOutput, Metadata, error)) FinalizeMiddleware { return finalizeMiddlewareFunc{ id: id, @@ -72,20 +76,19 @@ var _ FinalizeMiddleware = (finalizeMiddlewareFunc{}) // FinalizeStep provides the ordered grouping of FinalizeMiddleware to be // invoked on a handler. type FinalizeStep struct { - ids *orderedIDs + head *decoratedFinalizeHandler + tail *decoratedFinalizeHandler } -// NewFinalizeStep returns a FinalizeStep ready to have middleware for -// initialization added to it. +// NewFinalizeStep returns an FinalizeStep ready to have middleware for +// finalize added to it. func NewFinalizeStep() *FinalizeStep { - return &FinalizeStep{ - ids: newOrderedIDs(), - } + return &FinalizeStep{} } var _ Middleware = (*FinalizeStep)(nil) -// ID returns the unique id of the step as a middleware. +// ID returns the unique ID of the step as a middleware. func (s *FinalizeStep) ID() string { return "Finalize stack step" } @@ -97,77 +100,161 @@ func (s *FinalizeStep) ID() string { func (s *FinalizeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( out interface{}, metadata Metadata, err error, ) { - order := s.ids.GetOrder() - - var h FinalizeHandler = finalizeWrapHandler{Next: next} - for i := len(order) - 1; i >= 0; i-- { - h = decoratedFinalizeHandler{ - Next: h, - With: order[i].(FinalizeMiddleware), - } - } - sIn := FinalizeInput{ Request: in, } - res, metadata, err := h.HandleFinalize(ctx, sIn) + wh := &finalizeWrapHandler{next} + if s.head == nil { + res, metadata, err := wh.HandleFinalize(ctx, sIn) + return res.Result, metadata, err + } + + s.tail.Next = wh + res, metadata, err := s.head.HandleFinalize(ctx, sIn) return res.Result, metadata, err } // Get retrieves the middleware identified by id. If the middleware is not present, returns false. func (s *FinalizeStep) Get(id string) (FinalizeMiddleware, bool) { - get, ok := s.ids.Get(id) - if !ok { + found, _ := s.get(id) + if found == nil { return nil, false } - return get.(FinalizeMiddleware), ok + + return found.With, true } // Add injects the middleware to the relative position of the middleware group. -// Returns an error if the middleware already exists. +// +// Add never returns an error. It used to for duplicate phases but this +// behavior has since been removed as part of a performance optimization. The +// return value from Add can be ignored. func (s *FinalizeStep) Add(m FinalizeMiddleware, pos RelativePosition) error { - return s.ids.Add(m, pos) + if s.head == nil { + s.head = &decoratedFinalizeHandler{nil, m} + s.tail = s.head + return nil + } + + if pos == Before { + s.head = &decoratedFinalizeHandler{s.head, m} + } else { + tail := &decoratedFinalizeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } + + return nil } // Insert injects the middleware relative to an existing middleware ID. // Returns error if the original middleware does not exist, or the middleware // being added already exists. func (s *FinalizeStep) Insert(m FinalizeMiddleware, relativeTo string, pos RelativePosition) error { - return s.ids.Insert(m, relativeTo, pos) + found, prev := s.get(relativeTo) + if found == nil { + return fmt.Errorf("not found: %s", m.ID()) + } + + if pos == Before { + if prev == nil { // at the front + s.head = &decoratedFinalizeHandler{s.head, m} + } else { // somewhere in the middle + prev.Next = &decoratedFinalizeHandler{found, m} + } + } else { + if found.Next == nil { // at the end + tail := &decoratedFinalizeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } else { // somewhere in the middle + found.Next = &decoratedFinalizeHandler{found.Next, m} + } + } + + return nil } // Swap removes the middleware by id, replacing it with the new middleware. // Returns the middleware removed, or error if the middleware to be removed // doesn't exist. func (s *FinalizeStep) Swap(id string, m FinalizeMiddleware) (FinalizeMiddleware, error) { - removed, err := s.ids.Swap(id, m) - if err != nil { - return nil, err + found, _ := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", m.ID()) } - return removed.(FinalizeMiddleware), nil + swapped := found.With + found.With = m + return swapped, nil } // Remove removes the middleware by id. Returns error if the middleware // doesn't exist. func (s *FinalizeStep) Remove(id string) (FinalizeMiddleware, error) { - removed, err := s.ids.Remove(id) - if err != nil { - return nil, err + found, prev := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", id) + } + + if s.head == s.tail { // it's the only one + s.head = nil + s.tail = nil + } else if found == s.head { // at the front + s.head = s.head.Next.(*decoratedFinalizeHandler) + } else if found == s.tail { // at the end + prev.Next = nil + s.tail = prev + } else { + prev.Next = found.Next // somewhere in the middle } - return removed.(FinalizeMiddleware), nil + return found.With, nil } // List returns a list of the middleware in the step. func (s *FinalizeStep) List() []string { - return s.ids.List() + var ids []string + for h := s.head; h != nil; { + ids = append(ids, h.With.ID()) + if h.Next == nil { + break + } + + // once executed, tail.Next of the list will be set to an + // *finalizeWrapHandler, make sure to check for that + if hnext, ok := h.Next.(*decoratedFinalizeHandler); ok { + h = hnext + } else { + break + } + } + return ids } // Clear removes all middleware in the step. func (s *FinalizeStep) Clear() { - s.ids.Clear() + s.head = nil + s.tail = nil +} + +func (s *FinalizeStep) get(id string) (found, prev *decoratedFinalizeHandler) { + for h := s.head; h != nil; { + if h.With.ID() == id { + found = h + return + } + prev = h + if h.Next == nil { + return + } + + // once executed, tail.Next of the list will be set to an + // *finalizeWrapHandler + h, _ = h.Next.(*decoratedFinalizeHandler) + } + return } type finalizeWrapHandler struct { @@ -200,10 +287,10 @@ func (h decoratedFinalizeHandler) HandleFinalize(ctx context.Context, in Finaliz return h.With.HandleFinalize(ctx, in, h.Next) } -// FinalizeHandlerFunc provides a wrapper around a function to be used as a finalize middleware handler. +// FinalizeHandlerFunc provides a wrapper around a function to be used as finalizeMiddleware. type FinalizeHandlerFunc func(context.Context, FinalizeInput) (FinalizeOutput, Metadata, error) -// HandleFinalize invokes the wrapped function with the given arguments. +// HandleFinalize calls the wrapped function with the provided arguments. func (f FinalizeHandlerFunc) HandleFinalize(ctx context.Context, in FinalizeInput) (FinalizeOutput, Metadata, error) { return f(ctx, in) } diff --git a/vendor/github.com/aws/smithy-go/middleware/step_initialize.go b/vendor/github.com/aws/smithy-go/middleware/step_initialize.go index fe359144d2..446f3b7bb9 100644 --- a/vendor/github.com/aws/smithy-go/middleware/step_initialize.go +++ b/vendor/github.com/aws/smithy-go/middleware/step_initialize.go @@ -1,10 +1,15 @@ +// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. package middleware -import "context" +import ( + "context" + "fmt" +) // InitializeInput wraps the input parameters for the InitializeMiddlewares to // consume. InitializeMiddleware may modify the parameter value before // forwarding it along to the next InitializeHandler. + type InitializeInput struct { Parameters interface{} } @@ -72,15 +77,14 @@ var _ InitializeMiddleware = (initializeMiddlewareFunc{}) // InitializeStep provides the ordered grouping of InitializeMiddleware to be // invoked on a handler. type InitializeStep struct { - ids *orderedIDs + head *decoratedInitializeHandler + tail *decoratedInitializeHandler } // NewInitializeStep returns an InitializeStep ready to have middleware for -// initialization added to it. +// initialize added to it. func NewInitializeStep() *InitializeStep { - return &InitializeStep{ - ids: newOrderedIDs(), - } + return &InitializeStep{} } var _ Middleware = (*InitializeStep)(nil) @@ -97,77 +101,161 @@ func (s *InitializeStep) ID() string { func (s *InitializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( out interface{}, metadata Metadata, err error, ) { - order := s.ids.GetOrder() - - var h InitializeHandler = initializeWrapHandler{Next: next} - for i := len(order) - 1; i >= 0; i-- { - h = decoratedInitializeHandler{ - Next: h, - With: order[i].(InitializeMiddleware), - } - } - sIn := InitializeInput{ Parameters: in, } - res, metadata, err := h.HandleInitialize(ctx, sIn) + wh := &initializeWrapHandler{next} + if s.head == nil { + res, metadata, err := wh.HandleInitialize(ctx, sIn) + return res.Result, metadata, err + } + + s.tail.Next = wh + res, metadata, err := s.head.HandleInitialize(ctx, sIn) return res.Result, metadata, err } // Get retrieves the middleware identified by id. If the middleware is not present, returns false. func (s *InitializeStep) Get(id string) (InitializeMiddleware, bool) { - get, ok := s.ids.Get(id) - if !ok { + found, _ := s.get(id) + if found == nil { return nil, false } - return get.(InitializeMiddleware), ok + + return found.With, true } // Add injects the middleware to the relative position of the middleware group. -// Returns an error if the middleware already exists. +// +// Add never returns an error. It used to for duplicate phases but this +// behavior has since been removed as part of a performance optimization. The +// return value from Add can be ignored. func (s *InitializeStep) Add(m InitializeMiddleware, pos RelativePosition) error { - return s.ids.Add(m, pos) + if s.head == nil { + s.head = &decoratedInitializeHandler{nil, m} + s.tail = s.head + return nil + } + + if pos == Before { + s.head = &decoratedInitializeHandler{s.head, m} + } else { + tail := &decoratedInitializeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } + + return nil } // Insert injects the middleware relative to an existing middleware ID. // Returns error if the original middleware does not exist, or the middleware // being added already exists. func (s *InitializeStep) Insert(m InitializeMiddleware, relativeTo string, pos RelativePosition) error { - return s.ids.Insert(m, relativeTo, pos) + found, prev := s.get(relativeTo) + if found == nil { + return fmt.Errorf("not found: %s", m.ID()) + } + + if pos == Before { + if prev == nil { // at the front + s.head = &decoratedInitializeHandler{s.head, m} + } else { // somewhere in the middle + prev.Next = &decoratedInitializeHandler{found, m} + } + } else { + if found.Next == nil { // at the end + tail := &decoratedInitializeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } else { // somewhere in the middle + found.Next = &decoratedInitializeHandler{found.Next, m} + } + } + + return nil } // Swap removes the middleware by id, replacing it with the new middleware. // Returns the middleware removed, or error if the middleware to be removed // doesn't exist. func (s *InitializeStep) Swap(id string, m InitializeMiddleware) (InitializeMiddleware, error) { - removed, err := s.ids.Swap(id, m) - if err != nil { - return nil, err + found, _ := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", m.ID()) } - return removed.(InitializeMiddleware), nil + swapped := found.With + found.With = m + return swapped, nil } // Remove removes the middleware by id. Returns error if the middleware // doesn't exist. func (s *InitializeStep) Remove(id string) (InitializeMiddleware, error) { - removed, err := s.ids.Remove(id) - if err != nil { - return nil, err + found, prev := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", id) } - return removed.(InitializeMiddleware), nil + if s.head == s.tail { // it's the only one + s.head = nil + s.tail = nil + } else if found == s.head { // at the front + s.head = s.head.Next.(*decoratedInitializeHandler) + } else if found == s.tail { // at the end + prev.Next = nil + s.tail = prev + } else { + prev.Next = found.Next // somewhere in the middle + } + + return found.With, nil } // List returns a list of the middleware in the step. func (s *InitializeStep) List() []string { - return s.ids.List() + var ids []string + for h := s.head; h != nil; { + ids = append(ids, h.With.ID()) + if h.Next == nil { + break + } + + // once executed, tail.Next of the list will be set to an + // *initializeWrapHandler, make sure to check for that + if hnext, ok := h.Next.(*decoratedInitializeHandler); ok { + h = hnext + } else { + break + } + } + return ids } // Clear removes all middleware in the step. func (s *InitializeStep) Clear() { - s.ids.Clear() + s.head = nil + s.tail = nil +} + +func (s *InitializeStep) get(id string) (found, prev *decoratedInitializeHandler) { + for h := s.head; h != nil; { + if h.With.ID() == id { + found = h + return + } + prev = h + if h.Next == nil { + return + } + + // once executed, tail.Next of the list will be set to an + // *initializeWrapHandler + h, _ = h.Next.(*decoratedInitializeHandler) + } + return } type initializeWrapHandler struct { @@ -200,12 +288,12 @@ func (h decoratedInitializeHandler) HandleInitialize(ctx context.Context, in Ini return h.With.HandleInitialize(ctx, in, h.Next) } -// InitializeHandlerFunc provides a wrapper around a function to be used as an initialize middleware handler. +// InitializeHandlerFunc provides a wrapper around a function to be used as initializeMiddleware. type InitializeHandlerFunc func(context.Context, InitializeInput) (InitializeOutput, Metadata, error) // HandleInitialize calls the wrapped function with the provided arguments. -func (i InitializeHandlerFunc) HandleInitialize(ctx context.Context, in InitializeInput) (InitializeOutput, Metadata, error) { - return i(ctx, in) +func (f InitializeHandlerFunc) HandleInitialize(ctx context.Context, in InitializeInput) (InitializeOutput, Metadata, error) { + return f(ctx, in) } var _ InitializeHandler = InitializeHandlerFunc(nil) diff --git a/vendor/github.com/aws/smithy-go/middleware/step_serialize.go b/vendor/github.com/aws/smithy-go/middleware/step_serialize.go index 114bafcede..942ebb4f3e 100644 --- a/vendor/github.com/aws/smithy-go/middleware/step_serialize.go +++ b/vendor/github.com/aws/smithy-go/middleware/step_serialize.go @@ -1,6 +1,10 @@ +// Code generated by smithy-go/middleware/generate.go DO NOT EDIT. package middleware -import "context" +import ( + "context" + "fmt" +) // SerializeInput provides the input parameters for the SerializeMiddleware to // consume. SerializeMiddleware may modify the Request value before forwarding @@ -41,8 +45,8 @@ type SerializeMiddleware interface { ) } -// SerializeMiddlewareFunc returns a SerializeMiddleware with the unique ID -// provided, and the func to be invoked. +// SerializeMiddlewareFunc returns a SerializeMiddleware with the unique ID provided, +// and the func to be invoked. func SerializeMiddlewareFunc(id string, fn func(context.Context, SerializeInput, SerializeHandler) (SerializeOutput, Metadata, error)) SerializeMiddleware { return serializeMiddlewareFunc{ id: id, @@ -75,17 +79,15 @@ var _ SerializeMiddleware = (serializeMiddlewareFunc{}) // SerializeStep provides the ordered grouping of SerializeMiddleware to be // invoked on a handler. type SerializeStep struct { + head *decoratedSerializeHandler + tail *decoratedSerializeHandler newRequest func() interface{} - ids *orderedIDs } -// NewSerializeStep returns a SerializeStep ready to have middleware for -// initialization added to it. The newRequest func parameter is used to -// initialize the transport specific request for the stack SerializeStep to -// serialize the input parameters into. +// NewSerializeStep returns an SerializeStep ready to have middleware for +// serialize added to it. func NewSerializeStep(newRequest func() interface{}) *SerializeStep { return &SerializeStep{ - ids: newOrderedIDs(), newRequest: newRequest, } } @@ -104,78 +106,162 @@ func (s *SerializeStep) ID() string { func (s *SerializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) ( out interface{}, metadata Metadata, err error, ) { - order := s.ids.GetOrder() - - var h SerializeHandler = serializeWrapHandler{Next: next} - for i := len(order) - 1; i >= 0; i-- { - h = decoratedSerializeHandler{ - Next: h, - With: order[i].(SerializeMiddleware), - } - } - sIn := SerializeInput{ Parameters: in, Request: s.newRequest(), } - res, metadata, err := h.HandleSerialize(ctx, sIn) + wh := &serializeWrapHandler{next} + if s.head == nil { + res, metadata, err := wh.HandleSerialize(ctx, sIn) + return res.Result, metadata, err + } + + s.tail.Next = wh + res, metadata, err := s.head.HandleSerialize(ctx, sIn) return res.Result, metadata, err } // Get retrieves the middleware identified by id. If the middleware is not present, returns false. func (s *SerializeStep) Get(id string) (SerializeMiddleware, bool) { - get, ok := s.ids.Get(id) - if !ok { + found, _ := s.get(id) + if found == nil { return nil, false } - return get.(SerializeMiddleware), ok + + return found.With, true } // Add injects the middleware to the relative position of the middleware group. -// Returns an error if the middleware already exists. +// +// Add never returns an error. It used to for duplicate phases but this +// behavior has since been removed as part of a performance optimization. The +// return value from Add can be ignored. func (s *SerializeStep) Add(m SerializeMiddleware, pos RelativePosition) error { - return s.ids.Add(m, pos) + if s.head == nil { + s.head = &decoratedSerializeHandler{nil, m} + s.tail = s.head + return nil + } + + if pos == Before { + s.head = &decoratedSerializeHandler{s.head, m} + } else { + tail := &decoratedSerializeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } + + return nil } // Insert injects the middleware relative to an existing middleware ID. // Returns error if the original middleware does not exist, or the middleware // being added already exists. func (s *SerializeStep) Insert(m SerializeMiddleware, relativeTo string, pos RelativePosition) error { - return s.ids.Insert(m, relativeTo, pos) + found, prev := s.get(relativeTo) + if found == nil { + return fmt.Errorf("not found: %s", m.ID()) + } + + if pos == Before { + if prev == nil { // at the front + s.head = &decoratedSerializeHandler{s.head, m} + } else { // somewhere in the middle + prev.Next = &decoratedSerializeHandler{found, m} + } + } else { + if found.Next == nil { // at the end + tail := &decoratedSerializeHandler{nil, m} + s.tail.Next = tail + s.tail = tail + } else { // somewhere in the middle + found.Next = &decoratedSerializeHandler{found.Next, m} + } + } + + return nil } // Swap removes the middleware by id, replacing it with the new middleware. // Returns the middleware removed, or error if the middleware to be removed // doesn't exist. func (s *SerializeStep) Swap(id string, m SerializeMiddleware) (SerializeMiddleware, error) { - removed, err := s.ids.Swap(id, m) - if err != nil { - return nil, err + found, _ := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", m.ID()) } - return removed.(SerializeMiddleware), nil + swapped := found.With + found.With = m + return swapped, nil } // Remove removes the middleware by id. Returns error if the middleware // doesn't exist. func (s *SerializeStep) Remove(id string) (SerializeMiddleware, error) { - removed, err := s.ids.Remove(id) - if err != nil { - return nil, err + found, prev := s.get(id) + if found == nil { + return nil, fmt.Errorf("not found: %s", id) + } + + if s.head == s.tail { // it's the only one + s.head = nil + s.tail = nil + } else if found == s.head { // at the front + s.head = s.head.Next.(*decoratedSerializeHandler) + } else if found == s.tail { // at the end + prev.Next = nil + s.tail = prev + } else { + prev.Next = found.Next // somewhere in the middle } - return removed.(SerializeMiddleware), nil + return found.With, nil } // List returns a list of the middleware in the step. func (s *SerializeStep) List() []string { - return s.ids.List() + var ids []string + for h := s.head; h != nil; { + ids = append(ids, h.With.ID()) + if h.Next == nil { + break + } + + // once executed, tail.Next of the list will be set to an + // *serializeWrapHandler, make sure to check for that + if hnext, ok := h.Next.(*decoratedSerializeHandler); ok { + h = hnext + } else { + break + } + } + return ids } // Clear removes all middleware in the step. func (s *SerializeStep) Clear() { - s.ids.Clear() + s.head = nil + s.tail = nil +} + +func (s *SerializeStep) get(id string) (found, prev *decoratedSerializeHandler) { + for h := s.head; h != nil; { + if h.With.ID() == id { + found = h + return + } + prev = h + if h.Next == nil { + return + } + + // once executed, tail.Next of the list will be set to an + // *serializeWrapHandler + h, _ = h.Next.(*decoratedSerializeHandler) + } + return } type serializeWrapHandler struct { @@ -184,7 +270,7 @@ type serializeWrapHandler struct { var _ SerializeHandler = (*serializeWrapHandler)(nil) -// Implements SerializeHandler, converts types and delegates to underlying +// HandleSerialize implements SerializeHandler, converts types and delegates to underlying // generic handler. func (w serializeWrapHandler) HandleSerialize(ctx context.Context, in SerializeInput) ( out SerializeOutput, metadata Metadata, err error, @@ -208,12 +294,12 @@ func (h decoratedSerializeHandler) HandleSerialize(ctx context.Context, in Seria return h.With.HandleSerialize(ctx, in, h.Next) } -// SerializeHandlerFunc provides a wrapper around a function to be used as a serialize middleware handler. +// SerializeHandlerFunc provides a wrapper around a function to be used as serializeMiddleware. type SerializeHandlerFunc func(context.Context, SerializeInput) (SerializeOutput, Metadata, error) // HandleSerialize calls the wrapped function with the provided arguments. -func (s SerializeHandlerFunc) HandleSerialize(ctx context.Context, in SerializeInput) (SerializeOutput, Metadata, error) { - return s(ctx, in) +func (f SerializeHandlerFunc) HandleSerialize(ctx context.Context, in SerializeInput) (SerializeOutput, Metadata, error) { + return f(ctx, in) } var _ SerializeHandler = SerializeHandlerFunc(nil) diff --git a/vendor/github.com/aws/smithy-go/modman.toml b/vendor/github.com/aws/smithy-go/modman.toml index 9d94b7cbd0..aac582fa2c 100644 --- a/vendor/github.com/aws/smithy-go/modman.toml +++ b/vendor/github.com/aws/smithy-go/modman.toml @@ -1,5 +1,4 @@ [dependencies] - "github.com/jmespath/go-jmespath" = "v0.4.0" [modules] diff --git a/vendor/github.com/aws/smithy-go/transport/http/interceptor.go b/vendor/github.com/aws/smithy-go/transport/http/interceptor.go new file mode 100644 index 0000000000..e21f2632a6 --- /dev/null +++ b/vendor/github.com/aws/smithy-go/transport/http/interceptor.go @@ -0,0 +1,321 @@ +package http + +import ( + "context" +) + +func icopy[T any](v []T) []T { + s := make([]T, len(v)) + copy(s, v) + return s +} + +// InterceptorContext is all the information available in different +// interceptors. +// +// Not all information is available in each interceptor, see each interface +// definition for more details. +type InterceptorContext struct { + Input any + Request *Request + + Output any + Response *Response +} + +// InterceptorRegistry holds a list of operation interceptors. +// +// Interceptors allow callers to insert custom behavior at well-defined points +// within a client's operation lifecycle. +// +// # Interceptor context +// +// All interceptors are invoked with a context object that contains input and +// output containers for the operation. The individual fields that are +// available will depend on what the interceptor is and, in certain +// interceptors, how far the operation was able to progress. See the +// documentation for each interface definition for more information about field +// availability. +// +// Implementations MUST NOT directly mutate the values of the fields in the +// interceptor context. They are free to mutate the existing values _pointed +// to_ by those fields, however. +// +// # Returning errors +// +// All interceptors can return errors. If an interceptor returns an error +// _before_ the client's retry loop, the operation will fail immediately. If +// one returns an error _within_ the retry loop, the error WILL be considered +// according to the client's retry policy. +// +// # Adding interceptors +// +// Idiomatically you will simply use one of the Add() receiver methods to +// register interceptors as desired. However, the list for each interface is +// exported on the registry struct and the caller is free to manipulate it +// directly, for example, to register a number of interceptors all at once, or +// to remove one that was previously registered. +// +// The base SDK client WILL NOT add any interceptors. SDK operations and +// customizations are implemented in terms of middleware. +// +// Modifications to the registry will not persist across operation calls when +// using per-operation functional options. This means you can register +// interceptors on a per-operation basis without affecting other operations. +type InterceptorRegistry struct { + BeforeExecution []BeforeExecutionInterceptor + BeforeSerialization []BeforeSerializationInterceptor + AfterSerialization []AfterSerializationInterceptor + BeforeRetryLoop []BeforeRetryLoopInterceptor + BeforeAttempt []BeforeAttemptInterceptor + BeforeSigning []BeforeSigningInterceptor + AfterSigning []AfterSigningInterceptor + BeforeTransmit []BeforeTransmitInterceptor + AfterTransmit []AfterTransmitInterceptor + BeforeDeserialization []BeforeDeserializationInterceptor + AfterDeserialization []AfterDeserializationInterceptor + AfterAttempt []AfterAttemptInterceptor + AfterExecution []AfterExecutionInterceptor +} + +// Copy returns a deep copy of the registry. This is used by SDK clients on +// each operation call in order to prevent per-op config mutation from +// persisting. +func (i *InterceptorRegistry) Copy() InterceptorRegistry { + return InterceptorRegistry{ + BeforeExecution: icopy(i.BeforeExecution), + BeforeSerialization: icopy(i.BeforeSerialization), + AfterSerialization: icopy(i.AfterSerialization), + BeforeRetryLoop: icopy(i.BeforeRetryLoop), + BeforeAttempt: icopy(i.BeforeAttempt), + BeforeSigning: icopy(i.BeforeSigning), + AfterSigning: icopy(i.AfterSigning), + BeforeTransmit: icopy(i.BeforeTransmit), + AfterTransmit: icopy(i.AfterTransmit), + BeforeDeserialization: icopy(i.BeforeDeserialization), + AfterDeserialization: icopy(i.AfterDeserialization), + AfterAttempt: icopy(i.AfterAttempt), + AfterExecution: icopy(i.AfterExecution), + } +} + +// AddBeforeExecution registers the provided BeforeExecutionInterceptor. +func (i *InterceptorRegistry) AddBeforeExecution(v BeforeExecutionInterceptor) { + i.BeforeExecution = append(i.BeforeExecution, v) +} + +// AddBeforeSerialization registers the provided BeforeSerializationInterceptor. +func (i *InterceptorRegistry) AddBeforeSerialization(v BeforeSerializationInterceptor) { + i.BeforeSerialization = append(i.BeforeSerialization, v) +} + +// AddAfterSerialization registers the provided AfterSerializationInterceptor. +func (i *InterceptorRegistry) AddAfterSerialization(v AfterSerializationInterceptor) { + i.AfterSerialization = append(i.AfterSerialization, v) +} + +// AddBeforeRetryLoop registers the provided BeforeRetryLoopInterceptor. +func (i *InterceptorRegistry) AddBeforeRetryLoop(v BeforeRetryLoopInterceptor) { + i.BeforeRetryLoop = append(i.BeforeRetryLoop, v) +} + +// AddBeforeAttempt registers the provided BeforeAttemptInterceptor. +func (i *InterceptorRegistry) AddBeforeAttempt(v BeforeAttemptInterceptor) { + i.BeforeAttempt = append(i.BeforeAttempt, v) +} + +// AddBeforeSigning registers the provided BeforeSigningInterceptor. +func (i *InterceptorRegistry) AddBeforeSigning(v BeforeSigningInterceptor) { + i.BeforeSigning = append(i.BeforeSigning, v) +} + +// AddAfterSigning registers the provided AfterSigningInterceptor. +func (i *InterceptorRegistry) AddAfterSigning(v AfterSigningInterceptor) { + i.AfterSigning = append(i.AfterSigning, v) +} + +// AddBeforeTransmit registers the provided BeforeTransmitInterceptor. +func (i *InterceptorRegistry) AddBeforeTransmit(v BeforeTransmitInterceptor) { + i.BeforeTransmit = append(i.BeforeTransmit, v) +} + +// AddAfterTransmit registers the provided AfterTransmitInterceptor. +func (i *InterceptorRegistry) AddAfterTransmit(v AfterTransmitInterceptor) { + i.AfterTransmit = append(i.AfterTransmit, v) +} + +// AddBeforeDeserialization registers the provided BeforeDeserializationInterceptor. +func (i *InterceptorRegistry) AddBeforeDeserialization(v BeforeDeserializationInterceptor) { + i.BeforeDeserialization = append(i.BeforeDeserialization, v) +} + +// AddAfterDeserialization registers the provided AfterDeserializationInterceptor. +func (i *InterceptorRegistry) AddAfterDeserialization(v AfterDeserializationInterceptor) { + i.AfterDeserialization = append(i.AfterDeserialization, v) +} + +// AddAfterAttempt registers the provided AfterAttemptInterceptor. +func (i *InterceptorRegistry) AddAfterAttempt(v AfterAttemptInterceptor) { + i.AfterAttempt = append(i.AfterAttempt, v) +} + +// AddAfterExecution registers the provided AfterExecutionInterceptor. +func (i *InterceptorRegistry) AddAfterExecution(v AfterExecutionInterceptor) { + i.AfterExecution = append(i.AfterExecution, v) +} + +// BeforeExecutionInterceptor runs before anything else in the operation +// lifecycle. +// +// Available InterceptorContext fields: +// - Input +type BeforeExecutionInterceptor interface { + BeforeExecution(ctx context.Context, in *InterceptorContext) error +} + +// BeforeSerializationInterceptor runs before the operation input is serialized +// into its transport request. +// +// Serialization occurs before the operation's retry loop. +// +// Available InterceptorContext fields: +// - Input +type BeforeSerializationInterceptor interface { + BeforeSerialization(ctx context.Context, in *InterceptorContext) error +} + +// AfterSerializationInterceptor runs after the operation input is serialized +// into its transport request. +// +// Available InterceptorContext fields: +// - Input +// - Request +type AfterSerializationInterceptor interface { + AfterSerialization(ctx context.Context, in *InterceptorContext) error +} + +// BeforeRetryLoopInterceptor runs right before the operation enters the retry loop. +// +// Available InterceptorContext fields: +// - Input +// - Request +type BeforeRetryLoopInterceptor interface { + BeforeRetryLoop(ctx context.Context, in *InterceptorContext) error +} + +// BeforeAttemptInterceptor runs right before every attempt in the retry loop. +// +// If this interceptor returns an error, AfterAttempt interceptors WILL NOT be +// invoked. +// +// Available InterceptorContext fields: +// - Input +// - Request +type BeforeAttemptInterceptor interface { + BeforeAttempt(ctx context.Context, in *InterceptorContext) error +} + +// BeforeSigningInterceptor runs right before the request is signed. +// +// Signing occurs within the operation's retry loop. +// +// Available InterceptorContext fields: +// - Input +// - Request +type BeforeSigningInterceptor interface { + BeforeSigning(ctx context.Context, in *InterceptorContext) error +} + +// AfterSigningInterceptor runs right after the request is signed. +// +// It is unsafe to modify the outgoing HTTP request at or past this hook, since +// doing so may invalidate the signature of the request. +// +// Available InterceptorContext fields: +// - Input +// - Request +type AfterSigningInterceptor interface { + AfterSigning(ctx context.Context, in *InterceptorContext) error +} + +// BeforeTransmitInterceptor runs right before the HTTP request is sent. +// +// HTTP transmit occurs within the operation's retry loop. +// +// Available InterceptorContext fields: +// - Input +// - Request +type BeforeTransmitInterceptor interface { + BeforeTransmit(ctx context.Context, in *InterceptorContext) error +} + +// AfterTransmitInterceptor runs right after the HTTP response is received. +// +// It will always be invoked when a response is received, regardless of its +// status code. Conversely, it WILL NOT be invoked if the HTTP round-trip was +// not successful, e.g. because of a DNS resolution error +// +// Available InterceptorContext fields: +// - Input +// - Request +// - Response +type AfterTransmitInterceptor interface { + AfterTransmit(ctx context.Context, in *InterceptorContext) error +} + +// BeforeDeserializationInterceptor runs right before the incoming HTTP response +// is deserialized. +// +// This interceptor IS NOT invoked if the HTTP round-trip was not successful. +// +// Deserialization occurs within the operation's retry loop. +// +// Available InterceptorContext fields: +// - Input +// - Request +// - Response +type BeforeDeserializationInterceptor interface { + BeforeDeserialization(ctx context.Context, in *InterceptorContext) error +} + +// AfterDeserializationInterceptor runs right after the incoming HTTP response +// is deserialized. This hook is invoked regardless of whether the deserialized +// result was an error. +// +// This interceptor IS NOT invoked if the HTTP round-trip was not successful. +// +// Available InterceptorContext fields: +// - Input +// - Output (IF the operation had a success-level response) +// - Request +// - Response +type AfterDeserializationInterceptor interface { + AfterDeserialization(ctx context.Context, in *InterceptorContext) error +} + +// AfterAttemptInterceptor runs right after the incoming HTTP response +// is deserialized. This hook is invoked regardless of whether the deserialized +// result was an error, or if another interceptor within the retry loop +// returned an error. +// +// Available InterceptorContext fields: +// - Input +// - Output (IF the operation had a success-level response) +// - Request (IF the operation did not return an error during serialization) +// - Response (IF the operation was able to transmit the HTTP request) +type AfterAttemptInterceptor interface { + AfterAttempt(ctx context.Context, in *InterceptorContext) error +} + +// AfterExecutionInterceptor runs after everything else. It runs regardless of +// how far the operation progressed in its lifecycle, and regardless of whether +// the operation succeeded or failed. +// +// Available InterceptorContext fields: +// - Input +// - Output (IF the operation had a success-level response) +// - Request (IF the operation did not return an error during serialization) +// - Response (IF the operation was able to transmit the HTTP request) +type AfterExecutionInterceptor interface { + AfterExecution(ctx context.Context, in *InterceptorContext) error +} diff --git a/vendor/github.com/aws/smithy-go/transport/http/interceptor_middleware.go b/vendor/github.com/aws/smithy-go/transport/http/interceptor_middleware.go new file mode 100644 index 0000000000..2cc4b57f89 --- /dev/null +++ b/vendor/github.com/aws/smithy-go/transport/http/interceptor_middleware.go @@ -0,0 +1,325 @@ +package http + +import ( + "context" + "errors" + + "github.com/aws/smithy-go/middleware" +) + +type ictxKey struct{} + +func withIctx(ctx context.Context) context.Context { + return middleware.WithStackValue(ctx, ictxKey{}, &InterceptorContext{}) +} + +func getIctx(ctx context.Context) *InterceptorContext { + return middleware.GetStackValue(ctx, ictxKey{}).(*InterceptorContext) +} + +// InterceptExecution runs Before/AfterExecutionInterceptors. +type InterceptExecution struct { + BeforeExecution []BeforeExecutionInterceptor + AfterExecution []AfterExecutionInterceptor +} + +// ID identifies the middleware. +func (m *InterceptExecution) ID() string { + return "InterceptExecution" +} + +// HandleInitialize runs the interceptors. +func (m *InterceptExecution) HandleInitialize( + ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, +) ( + out middleware.InitializeOutput, md middleware.Metadata, err error, +) { + ctx = withIctx(ctx) + getIctx(ctx).Input = in.Parameters + + for _, i := range m.BeforeExecution { + if err := i.BeforeExecution(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + out, md, err = next.HandleInitialize(ctx, in) + + for _, i := range m.AfterExecution { + if err := i.AfterExecution(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return out, md, err +} + +// InterceptBeforeSerialization runs BeforeSerializationInterceptors. +type InterceptBeforeSerialization struct { + Interceptors []BeforeSerializationInterceptor +} + +// ID identifies the middleware. +func (m *InterceptBeforeSerialization) ID() string { + return "InterceptBeforeSerialization" +} + +// HandleSerialize runs the interceptors. +func (m *InterceptBeforeSerialization) HandleSerialize( + ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, +) ( + out middleware.SerializeOutput, md middleware.Metadata, err error, +) { + for _, i := range m.Interceptors { + if err := i.BeforeSerialization(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return next.HandleSerialize(ctx, in) +} + +// InterceptAfterSerialization runs AfterSerializationInterceptors. +type InterceptAfterSerialization struct { + Interceptors []AfterSerializationInterceptor +} + +// ID identifies the middleware. +func (m *InterceptAfterSerialization) ID() string { + return "InterceptAfterSerialization" +} + +// HandleSerialize runs the interceptors. +func (m *InterceptAfterSerialization) HandleSerialize( + ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler, +) ( + out middleware.SerializeOutput, md middleware.Metadata, err error, +) { + getIctx(ctx).Request = in.Request.(*Request) + + for _, i := range m.Interceptors { + if err := i.AfterSerialization(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return next.HandleSerialize(ctx, in) +} + +// InterceptBeforeRetryLoop runs BeforeRetryLoopInterceptors. +type InterceptBeforeRetryLoop struct { + Interceptors []BeforeRetryLoopInterceptor +} + +// ID identifies the middleware. +func (m *InterceptBeforeRetryLoop) ID() string { + return "InterceptBeforeRetryLoop" +} + +// HandleFinalize runs the interceptors. +func (m *InterceptBeforeRetryLoop) HandleFinalize( + ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, +) ( + out middleware.FinalizeOutput, md middleware.Metadata, err error, +) { + for _, i := range m.Interceptors { + if err := i.BeforeRetryLoop(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return next.HandleFinalize(ctx, in) +} + +// InterceptBeforeSigning runs BeforeSigningInterceptors. +type InterceptBeforeSigning struct { + Interceptors []BeforeSigningInterceptor +} + +// ID identifies the middleware. +func (m *InterceptBeforeSigning) ID() string { + return "InterceptBeforeSigning" +} + +// HandleFinalize runs the interceptors. +func (m *InterceptBeforeSigning) HandleFinalize( + ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, +) ( + out middleware.FinalizeOutput, md middleware.Metadata, err error, +) { + for _, i := range m.Interceptors { + if err := i.BeforeSigning(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return next.HandleFinalize(ctx, in) +} + +// InterceptAfterSigning runs AfterSigningInterceptors. +type InterceptAfterSigning struct { + Interceptors []AfterSigningInterceptor +} + +// ID identifies the middleware. +func (m *InterceptAfterSigning) ID() string { + return "InterceptAfterSigning" +} + +// HandleFinalize runs the interceptors. +func (m *InterceptAfterSigning) HandleFinalize( + ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, +) ( + out middleware.FinalizeOutput, md middleware.Metadata, err error, +) { + for _, i := range m.Interceptors { + if err := i.AfterSigning(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return next.HandleFinalize(ctx, in) +} + +// InterceptTransmit runs BeforeTransmitInterceptors and AfterTransmitInterceptors. +type InterceptTransmit struct { + BeforeTransmit []BeforeTransmitInterceptor + AfterTransmit []AfterTransmitInterceptor +} + +// ID identifies the middleware. +func (m *InterceptTransmit) ID() string { + return "InterceptTransmit" +} + +// HandleDeserialize runs the interceptors. +func (m *InterceptTransmit) HandleDeserialize( + ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler, +) ( + out middleware.DeserializeOutput, md middleware.Metadata, err error, +) { + for _, i := range m.BeforeTransmit { + if err := i.BeforeTransmit(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + out, md, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, md, err + } + + // the root of the decorated middleware guarantees this will be here + // (client.go: ClientHandler.Handle) + getIctx(ctx).Response = out.RawResponse.(*Response) + + for _, i := range m.AfterTransmit { + if err := i.AfterTransmit(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return out, md, err +} + +// InterceptBeforeDeserialization runs BeforeDeserializationInterceptors. +type InterceptBeforeDeserialization struct { + Interceptors []BeforeDeserializationInterceptor +} + +// ID identifies the middleware. +func (m *InterceptBeforeDeserialization) ID() string { + return "InterceptBeforeDeserialization" +} + +// HandleDeserialize runs the interceptors. +func (m *InterceptBeforeDeserialization) HandleDeserialize( + ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler, +) ( + out middleware.DeserializeOutput, md middleware.Metadata, err error, +) { + out, md, err = next.HandleDeserialize(ctx, in) + if err != nil { + var terr *RequestSendError + if errors.As(err, &terr) { + return out, md, err + } + } + + for _, i := range m.Interceptors { + if err := i.BeforeDeserialization(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return out, md, err +} + +// InterceptAfterDeserialization runs AfterDeserializationInterceptors. +type InterceptAfterDeserialization struct { + Interceptors []AfterDeserializationInterceptor +} + +// ID identifies the middleware. +func (m *InterceptAfterDeserialization) ID() string { + return "InterceptAfterDeserialization" +} + +// HandleDeserialize runs the interceptors. +func (m *InterceptAfterDeserialization) HandleDeserialize( + ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler, +) ( + out middleware.DeserializeOutput, md middleware.Metadata, err error, +) { + out, md, err = next.HandleDeserialize(ctx, in) + if err != nil { + var terr *RequestSendError + if errors.As(err, &terr) { + return out, md, err + } + } + + getIctx(ctx).Output = out.Result + + for _, i := range m.Interceptors { + if err := i.AfterDeserialization(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return out, md, err +} + +// InterceptAttempt runs AfterAttemptInterceptors. +type InterceptAttempt struct { + BeforeAttempt []BeforeAttemptInterceptor + AfterAttempt []AfterAttemptInterceptor +} + +// ID identifies the middleware. +func (m *InterceptAttempt) ID() string { + return "InterceptAttempt" +} + +// HandleFinalize runs the interceptors. +func (m *InterceptAttempt) HandleFinalize( + ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler, +) ( + out middleware.FinalizeOutput, md middleware.Metadata, err error, +) { + for _, i := range m.BeforeAttempt { + if err := i.BeforeAttempt(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + out, md, err = next.HandleFinalize(ctx, in) + + for _, i := range m.AfterAttempt { + if err := i.AfterAttempt(ctx, getIctx(ctx)); err != nil { + return out, md, err + } + } + + return out, md, err +} diff --git a/vendor/github.com/aws/smithy-go/transport/http/metrics.go b/vendor/github.com/aws/smithy-go/transport/http/metrics.go index d1beaa595d..b4cd4a47e3 100644 --- a/vendor/github.com/aws/smithy-go/transport/http/metrics.go +++ b/vendor/github.com/aws/smithy-go/transport/http/metrics.go @@ -17,6 +17,12 @@ var now = time.Now func withMetrics(parent context.Context, client ClientDo, meter metrics.Meter) ( context.Context, ClientDo, error, ) { + // WithClientTrace is an expensive operation - avoid calling it if we're + // not actually using a metrics sink. + if _, ok := meter.(metrics.NopMeter); ok { + return parent, client, nil + } + hm, err := newHTTPMetrics(meter) if err != nil { return nil, nil, err diff --git a/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api/client.go b/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api/client.go index ae452396b4..6a4c389f73 100644 --- a/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api/client.go +++ b/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api/client.go @@ -37,7 +37,7 @@ const ( ecrPublicEndpoint = proxyEndpointScheme + ecrPublicName ) -var ecrPattern = regexp.MustCompile(`^(\d{12})\.dkr\.ecr(\-fips)?\.([a-zA-Z0-9][a-zA-Z0-9-_]*)\.(amazonaws\.com(\.cn)?|sc2s\.sgov\.gov|c2s\.ic\.gov|cloud\.adc-e\.uk|csp\.hci\.ic\.gov)$`) +var ecrPattern = regexp.MustCompile(`^(\d{12})\.dkr[\.\-]ecr(\-fips)?\.([a-zA-Z0-9][a-zA-Z0-9-_]*)\.(amazonaws\.(?:com(?:\.cn)?|eu)|on\.(?:aws|amazonwebservices\.com\.cn)|sc2s\.sgov\.gov|c2s\.ic\.gov|cloud\.adc-e\.uk|csp\.hci\.ic\.gov)$`) type Service string diff --git a/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/config/log.go b/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/config/log.go index e4c0b5b2d2..b5082570a7 100644 --- a/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/config/log.go +++ b/vendor/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/config/log.go @@ -39,7 +39,7 @@ func logrusConfig() { fmt.Fprintf(os.Stderr, "log: failed to create directory: %v", err) logdir = os.TempDir() } - file, err := os.OpenFile(filepath.Join(logdir, "ecr-login.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0664) + file, err := os.OpenFile(filepath.Join(logdir, "ecr-login.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) if err != nil { return } diff --git a/vendor/github.com/josharian/intern/license.md b/vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE similarity index 96% rename from vendor/github.com/josharian/intern/license.md rename to vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE index 353d3055f0..25cec1ed48 100644 --- a/vendor/github.com/josharian/intern/license.md +++ b/vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Josh Bleecher Snyder +Copyright (c) 2022 Ayman Bagabas Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/aymanbagabas/go-osc52/v2/README.md b/vendor/github.com/aymanbagabas/go-osc52/v2/README.md new file mode 100644 index 0000000000..4de3a22d14 --- /dev/null +++ b/vendor/github.com/aymanbagabas/go-osc52/v2/README.md @@ -0,0 +1,83 @@ + +# go-osc52 + +

+ Latest Release + GoDoc +

+ +A Go library to work with the [ANSI OSC52](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands) terminal sequence. + +## Usage + +You can use this small library to construct an ANSI OSC52 sequence suitable for +your terminal. + + +### Example + +```go +import ( + "os" + "fmt" + + "github.com/aymanbagabas/go-osc52/v2" +) + +func main() { + s := "Hello World!" + + // Copy `s` to system clipboard + osc52.New(s).WriteTo(os.Stderr) + + // Copy `s` to primary clipboard (X11) + osc52.New(s).Primary().WriteTo(os.Stderr) + + // Query the clipboard + osc52.Query().WriteTo(os.Stderr) + + // Clear system clipboard + osc52.Clear().WriteTo(os.Stderr) + + // Use the fmt.Stringer interface to copy `s` to system clipboard + fmt.Fprint(os.Stderr, osc52.New(s)) + + // Or to primary clipboard + fmt.Fprint(os.Stderr, osc52.New(s).Primary()) +} +``` + +## SSH Example + +You can use this over SSH using [gliderlabs/ssh](https://github.com/gliderlabs/ssh) for instance: + +```go +var sshSession ssh.Session +seq := osc52.New("Hello awesome!") +// Check if term is screen or tmux +pty, _, _ := s.Pty() +if pty.Term == "screen" { + seq = seq.Screen() +} else if isTmux { + seq = seq.Tmux() +} +seq.WriteTo(sshSession.Stderr()) +``` + +## Tmux + +Make sure you have `set-clipboard on` in your config, otherwise, tmux won't +allow your application to access the clipboard [^1]. + +Using the tmux option, `osc52.TmuxMode` or `osc52.New(...).Tmux()`, wraps the +OSC52 sequence in a special tmux DCS sequence and pass it to the outer +terminal. This requires `allow-passthrough on` in your config. +`allow-passthrough` is no longer enabled by default +[since tmux 3.3a](https://github.com/tmux/tmux/issues/3218#issuecomment-1153089282) [^2]. + +[^1]: See [tmux clipboard](https://github.com/tmux/tmux/wiki/Clipboard) +[^2]: [What is allow-passthrough](https://github.com/tmux/tmux/wiki/FAQ#what-is-the-passthrough-escape-sequence-and-how-do-i-use-it) + +## Credits + +* [vim-oscyank](https://github.com/ojroques/vim-oscyank) this is heavily inspired by vim-oscyank. diff --git a/vendor/github.com/aymanbagabas/go-osc52/v2/osc52.go b/vendor/github.com/aymanbagabas/go-osc52/v2/osc52.go new file mode 100644 index 0000000000..dc758d2869 --- /dev/null +++ b/vendor/github.com/aymanbagabas/go-osc52/v2/osc52.go @@ -0,0 +1,305 @@ +// OSC52 is a terminal escape sequence that allows copying text to the clipboard. +// +// The sequence consists of the following: +// +// OSC 52 ; Pc ; Pd BEL +// +// Pc is the clipboard choice: +// +// c: clipboard +// p: primary +// q: secondary (not supported) +// s: select (not supported) +// 0-7: cut-buffers (not supported) +// +// Pd is the data to copy to the clipboard. This string should be encoded in +// base64 (RFC-4648). +// +// If Pd is "?", the terminal replies to the host with the current contents of +// the clipboard. +// +// If Pd is neither a base64 string nor "?", the terminal clears the clipboard. +// +// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands +// where Ps = 52 => Manipulate Selection Data. +// +// Examples: +// +// // copy "hello world" to the system clipboard +// fmt.Fprint(os.Stderr, osc52.New("hello world")) +// +// // copy "hello world" to the primary Clipboard +// fmt.Fprint(os.Stderr, osc52.New("hello world").Primary()) +// +// // limit the size of the string to copy 10 bytes +// fmt.Fprint(os.Stderr, osc52.New("0123456789").Limit(10)) +// +// // escape the OSC52 sequence for screen using DCS sequences +// fmt.Fprint(os.Stderr, osc52.New("hello world").Screen()) +// +// // escape the OSC52 sequence for Tmux +// fmt.Fprint(os.Stderr, osc52.New("hello world").Tmux()) +// +// // query the system Clipboard +// fmt.Fprint(os.Stderr, osc52.Query()) +// +// // query the primary clipboard +// fmt.Fprint(os.Stderr, osc52.Query().Primary()) +// +// // clear the system Clipboard +// fmt.Fprint(os.Stderr, osc52.Clear()) +// +// // clear the primary Clipboard +// fmt.Fprint(os.Stderr, osc52.Clear().Primary()) +package osc52 + +import ( + "encoding/base64" + "fmt" + "io" + "strings" +) + +// Clipboard is the clipboard buffer to use. +type Clipboard rune + +const ( + // SystemClipboard is the system clipboard buffer. + SystemClipboard Clipboard = 'c' + // PrimaryClipboard is the primary clipboard buffer (X11). + PrimaryClipboard = 'p' +) + +// Mode is the mode to use for the OSC52 sequence. +type Mode uint + +const ( + // DefaultMode is the default OSC52 sequence mode. + DefaultMode Mode = iota + // ScreenMode escapes the OSC52 sequence for screen using DCS sequences. + ScreenMode + // TmuxMode escapes the OSC52 sequence for tmux. Not needed if tmux + // clipboard is set to `set-clipboard on` + TmuxMode +) + +// Operation is the OSC52 operation. +type Operation uint + +const ( + // SetOperation is the copy operation. + SetOperation Operation = iota + // QueryOperation is the query operation. + QueryOperation + // ClearOperation is the clear operation. + ClearOperation +) + +// Sequence is the OSC52 sequence. +type Sequence struct { + str string + limit int + op Operation + mode Mode + clipboard Clipboard +} + +var _ fmt.Stringer = Sequence{} + +var _ io.WriterTo = Sequence{} + +// String returns the OSC52 sequence. +func (s Sequence) String() string { + var seq strings.Builder + // mode escape sequences start + seq.WriteString(s.seqStart()) + // actual OSC52 sequence start + seq.WriteString(fmt.Sprintf("\x1b]52;%c;", s.clipboard)) + switch s.op { + case SetOperation: + str := s.str + if s.limit > 0 && len(str) > s.limit { + return "" + } + b64 := base64.StdEncoding.EncodeToString([]byte(str)) + switch s.mode { + case ScreenMode: + // Screen doesn't support OSC52 but will pass the contents of a DCS + // sequence to the outer terminal unchanged. + // + // Here, we split the encoded string into 76 bytes chunks and then + // join the chunks with sequences. Finally, + // wrap the whole thing in + // . + // s := strings.SplitN(b64, "", 76) + s := make([]string, 0, len(b64)/76+1) + for i := 0; i < len(b64); i += 76 { + end := i + 76 + if end > len(b64) { + end = len(b64) + } + s = append(s, b64[i:end]) + } + seq.WriteString(strings.Join(s, "\x1b\\\x1bP")) + default: + seq.WriteString(b64) + } + case QueryOperation: + // OSC52 queries the clipboard using "?" + seq.WriteString("?") + case ClearOperation: + // OSC52 clears the clipboard if the data is neither a base64 string nor "?" + // we're using "!" as a default + seq.WriteString("!") + } + // actual OSC52 sequence end + seq.WriteString("\x07") + // mode escape end + seq.WriteString(s.seqEnd()) + return seq.String() +} + +// WriteTo writes the OSC52 sequence to the writer. +func (s Sequence) WriteTo(out io.Writer) (int64, error) { + n, err := out.Write([]byte(s.String())) + return int64(n), err +} + +// Mode sets the mode for the OSC52 sequence. +func (s Sequence) Mode(m Mode) Sequence { + s.mode = m + return s +} + +// Tmux sets the mode to TmuxMode. +// Used to escape the OSC52 sequence for `tmux`. +// +// Note: this is not needed if tmux clipboard is set to `set-clipboard on`. If +// TmuxMode is used, tmux must have `allow-passthrough on` set. +// +// This is a syntactic sugar for s.Mode(TmuxMode). +func (s Sequence) Tmux() Sequence { + return s.Mode(TmuxMode) +} + +// Screen sets the mode to ScreenMode. +// Used to escape the OSC52 sequence for `screen`. +// +// This is a syntactic sugar for s.Mode(ScreenMode). +func (s Sequence) Screen() Sequence { + return s.Mode(ScreenMode) +} + +// Clipboard sets the clipboard buffer for the OSC52 sequence. +func (s Sequence) Clipboard(c Clipboard) Sequence { + s.clipboard = c + return s +} + +// Primary sets the clipboard buffer to PrimaryClipboard. +// This is the X11 primary clipboard. +// +// This is a syntactic sugar for s.Clipboard(PrimaryClipboard). +func (s Sequence) Primary() Sequence { + return s.Clipboard(PrimaryClipboard) +} + +// Limit sets the limit for the OSC52 sequence. +// The default limit is 0 (no limit). +// +// Strings longer than the limit get ignored. Settting the limit to 0 or a +// negative value disables the limit. Each terminal defines its own escapse +// sequence limit. +func (s Sequence) Limit(l int) Sequence { + if l < 0 { + s.limit = 0 + } else { + s.limit = l + } + return s +} + +// Operation sets the operation for the OSC52 sequence. +// The default operation is SetOperation. +func (s Sequence) Operation(o Operation) Sequence { + s.op = o + return s +} + +// Clear sets the operation to ClearOperation. +// This clears the clipboard. +// +// This is a syntactic sugar for s.Operation(ClearOperation). +func (s Sequence) Clear() Sequence { + return s.Operation(ClearOperation) +} + +// Query sets the operation to QueryOperation. +// This queries the clipboard contents. +// +// This is a syntactic sugar for s.Operation(QueryOperation). +func (s Sequence) Query() Sequence { + return s.Operation(QueryOperation) +} + +// SetString sets the string for the OSC52 sequence. Strings are joined with a +// space character. +func (s Sequence) SetString(strs ...string) Sequence { + s.str = strings.Join(strs, " ") + return s +} + +// New creates a new OSC52 sequence with the given string(s). Strings are +// joined with a space character. +func New(strs ...string) Sequence { + s := Sequence{ + str: strings.Join(strs, " "), + limit: 0, + mode: DefaultMode, + clipboard: SystemClipboard, + op: SetOperation, + } + return s +} + +// Query creates a new OSC52 sequence with the QueryOperation. +// This returns a new OSC52 sequence to query the clipboard contents. +// +// This is a syntactic sugar for New().Query(). +func Query() Sequence { + return New().Query() +} + +// Clear creates a new OSC52 sequence with the ClearOperation. +// This returns a new OSC52 sequence to clear the clipboard. +// +// This is a syntactic sugar for New().Clear(). +func Clear() Sequence { + return New().Clear() +} + +func (s Sequence) seqStart() string { + switch s.mode { + case TmuxMode: + // Write the start of a tmux escape sequence. + return "\x1bPtmux;\x1b" + case ScreenMode: + // Write the start of a DCS sequence. + return "\x1bP" + default: + return "" + } +} + +func (s Sequence) seqEnd() string { + switch s.mode { + case TmuxMode: + // Terminate the tmux escape sequence. + return "\x1b\\" + case ScreenMode: + // Write the end of a DCS sequence. + return "\x1b\x5c" + default: + return "" + } +} diff --git a/vendor/github.com/buildkite/agent/v3/api/annotations.go b/vendor/github.com/buildkite/agent/v3/api/annotations.go index 90f5649e57..2871d75bae 100644 --- a/vendor/github.com/buildkite/agent/v3/api/annotations.go +++ b/vendor/github.com/buildkite/agent/v3/api/annotations.go @@ -3,6 +3,7 @@ package api import ( "context" "fmt" + "net/url" ) // Annotation represents a Buildkite Agent API Annotation @@ -12,6 +13,7 @@ type Annotation struct { Style string `json:"style,omitempty"` Append bool `json:"append,omitempty"` Priority int `json:"priority,omitempty"` + Scope string `json:"scope,omitempty"` } // Annotate a build in the Buildkite UI @@ -27,7 +29,7 @@ func (c *Client) Annotate(ctx context.Context, jobId string, annotation *Annotat } // Remove an annotation from a build -func (c *Client) AnnotationRemove(ctx context.Context, jobId string, context string) (*Response, error) { +func (c *Client) AnnotationRemove(ctx context.Context, jobId, context, scope string) (*Response, error) { u := fmt.Sprintf("jobs/%s/annotations/%s", railsPathEscape(jobId), railsPathEscape(context)) req, err := c.newRequest(ctx, "DELETE", u, nil) @@ -35,5 +37,13 @@ func (c *Client) AnnotationRemove(ctx context.Context, jobId string, context str return nil, err } + q, err := url.ParseQuery(req.URL.RawQuery) + if err != nil { + return nil, fmt.Errorf("decoding query string: %w", err) + } + + q.Set("scope", scope) + req.URL.RawQuery = q.Encode() + return c.doRequest(req, nil) } diff --git a/vendor/github.com/buildkite/agent/v3/api/chunks.go b/vendor/github.com/buildkite/agent/v3/api/chunks.go index d238584b39..3d171e44dd 100644 --- a/vendor/github.com/buildkite/agent/v3/api/chunks.go +++ b/vendor/github.com/buildkite/agent/v3/api/chunks.go @@ -21,7 +21,9 @@ func (c *Client) UploadChunk(ctx context.Context, jobId string, chunk *Chunk) (* // Create a compressed buffer of the log content body := &bytes.Buffer{} gzipper := gzip.NewWriter(body) - gzipper.Write(chunk.Data) + if _, err := gzipper.Write(chunk.Data); err != nil { + return nil, err + } if err := gzipper.Close(); err != nil { return nil, err } diff --git a/vendor/github.com/buildkite/agent/v3/api/client.go b/vendor/github.com/buildkite/agent/v3/api/client.go index 059acedb17..8891f57be8 100644 --- a/vendor/github.com/buildkite/agent/v3/api/client.go +++ b/vendor/github.com/buildkite/agent/v3/api/client.go @@ -1,7 +1,5 @@ package api -//go:generate go run github.com/rjeczalik/interfaces/cmd/interfacer@v0.3.0 -for github.com/buildkite/agent/v3/api.Client -as agent.APIClient -o ../agent/api.go - import ( "bytes" "context" @@ -309,7 +307,6 @@ func newResponse(r *http.Response) *Response { // interface, the raw response body will be written to v, without attempting to // first decode it. func (c *Client) doRequest(req *http.Request, v any) (*Response, error) { - resp, err := agenthttp.Do(c.logger, c.client, req, agenthttp.WithDebugHTTP(c.conf.DebugHTTP), agenthttp.WithTraceHTTP(c.conf.TraceHTTP), @@ -317,8 +314,8 @@ func (c *Client) doRequest(req *http.Request, v any) (*Response, error) { if err != nil { return nil, err } - defer resp.Body.Close() - defer io.Copy(io.Discard, resp.Body) + defer resp.Body.Close() //nolint:errcheck // This is idiomatic for response bodies. + defer io.Copy(io.Discard, resp.Body) //nolint:errcheck // Body is a reader, io.Discard never errors. response := newResponse(resp) @@ -330,7 +327,9 @@ func (c *Client) doRequest(req *http.Request, v any) (*Response, error) { if v != nil { if w, ok := v.(io.Writer); ok { - io.Copy(w, resp.Body) + if _, err := io.Copy(w, resp.Body); err != nil { + return response, fmt.Errorf("failed to copy response into destination %T: %v", w, err) + } } else { if strings.Contains(req.Header.Get("Content-Type"), "application/msgpack") { return response, errors.New("Msgpack not supported") @@ -375,8 +374,13 @@ func checkResponse(r *http.Response) error { errorResponse := &ErrorResponse{Response: r} data, err := io.ReadAll(r.Body) - if err == nil && data != nil { - json.Unmarshal(data, errorResponse) + if err != nil { + return errorResponse + } + if data != nil { + // Unmarshaling the error JSON is best-effort, but we could consider + // reporting unmarshaling problems. + json.Unmarshal(data, errorResponse) //nolint:errcheck // ^^ } return errorResponse @@ -386,7 +390,7 @@ func checkResponse(r *http.Response) error { // be a struct whose fields may contain "url" tags. func addOptions(s string, opt any) (string, error) { v := reflect.ValueOf(opt) - if v.Kind() == reflect.Ptr && v.IsNil() { + if v.Kind() == reflect.Pointer && v.IsNil() { return s, nil } @@ -404,7 +408,7 @@ func addOptions(s string, opt any) (string, error) { return u.String(), nil } -func joinURLPath(endpoint string, path string) string { +func joinURLPath(endpoint, path string) string { return strings.TrimRight(endpoint, "/") + "/" + strings.TrimLeft(path, "/") } diff --git a/vendor/github.com/buildkite/agent/v3/api/github_code_access_token.go b/vendor/github.com/buildkite/agent/v3/api/github_code_access_token.go index 2ec224b29d..b7a369521b 100644 --- a/vendor/github.com/buildkite/agent/v3/api/github_code_access_token.go +++ b/vendor/github.com/buildkite/agent/v3/api/github_code_access_token.go @@ -54,7 +54,6 @@ func (c *Client) GenerateGithubCodeAccessToken(ctx context.Context, repoURL, job return resp, err }) - if err != nil { return "", resp, err } diff --git a/vendor/github.com/buildkite/agent/v3/api/jobs.go b/vendor/github.com/buildkite/agent/v3/api/jobs.go index 5a5343c16a..c30f799571 100644 --- a/vendor/github.com/buildkite/agent/v3/api/jobs.go +++ b/vendor/github.com/buildkite/agent/v3/api/jobs.go @@ -9,22 +9,24 @@ import ( // Job represents a Buildkite Agent API Job type Job struct { - ID string `json:"id,omitempty"` - Endpoint string `json:"endpoint"` - State string `json:"state,omitempty"` - Env map[string]string `json:"env,omitempty"` - Step pipeline.CommandStep `json:"step,omitempty"` - MatrixPermutation pipeline.MatrixPermutation `json:"matrix_permutation,omitempty"` - ChunksMaxSizeBytes uint64 `json:"chunks_max_size_bytes,omitempty"` - LogMaxSizeBytes uint64 `json:"log_max_size_bytes,omitempty"` - Token string `json:"token,omitempty"` - ExitStatus string `json:"exit_status,omitempty"` - Signal string `json:"signal,omitempty"` - SignalReason string `json:"signal_reason,omitempty"` - StartedAt string `json:"started_at,omitempty"` - FinishedAt string `json:"finished_at,omitempty"` - RunnableAt string `json:"runnable_at,omitempty"` - ChunksFailedCount int `json:"chunks_failed_count,omitempty"` + ID string `json:"id,omitempty"` + Endpoint string `json:"endpoint"` + State string `json:"state,omitempty"` + Env map[string]string `json:"env,omitempty"` + Step pipeline.CommandStep `json:"step"` + MatrixPermutation pipeline.MatrixPermutation `json:"matrix_permutation,omitempty"` + ChunksMaxSizeBytes uint64 `json:"chunks_max_size_bytes,omitempty"` + ChunksIntervalSeconds int `json:"chunks_interval_seconds,omitempty"` + LogMaxSizeBytes uint64 `json:"log_max_size_bytes,omitempty"` + Token string `json:"token,omitempty"` + ExitStatus string `json:"exit_status,omitempty"` + Signal string `json:"signal,omitempty"` + SignalReason string `json:"signal_reason,omitempty"` + StartedAt string `json:"started_at,omitempty"` + FinishedAt string `json:"finished_at,omitempty"` + RunnableAt string `json:"runnable_at,omitempty"` + ChunksFailedCount int `json:"chunks_failed_count,omitempty"` + TraceParent string `json:"traceparent"` } type JobState struct { diff --git a/vendor/github.com/buildkite/agent/v3/api/token.go b/vendor/github.com/buildkite/agent/v3/api/token.go new file mode 100644 index 0000000000..3f3918736e --- /dev/null +++ b/vendor/github.com/buildkite/agent/v3/api/token.go @@ -0,0 +1,35 @@ +package api + +import ( + "context" + "net/http" +) + +// AgentTokenIdentity describes token identity information. +type AgentTokenIdentity struct { + UUID string `json:"uuid"` + Description string `json:"description"` + TokenType string `json:"token_type"` + OrganizationSlug string `json:"organization_slug"` + OrganizationUUID string `json:"organization_uuid"` + ClusterUUID string `json:"cluster_uuid"` + ClusterName string `json:"cluster_name"` + OrganizationQueueUUID string `json:"organization_queue_uuid"` + OrganizationQueueKey string `json:"organization_queue_key"` +} + +// GetTokenIdentity gets the identity information of an agent token. +func (c *Client) GetTokenIdentity(ctx context.Context) (*AgentTokenIdentity, *Response, error) { + req, err := c.newRequest(ctx, http.MethodGet, "token", nil) + if err != nil { + return nil, nil, err + } + + ident := new(AgentTokenIdentity) + resp, err := c.doRequest(req, ident) + if err != nil { + return nil, resp, err + } + + return ident, resp, nil +} diff --git a/vendor/github.com/buildkite/agent/v3/internal/agenthttp/auth.go b/vendor/github.com/buildkite/agent/v3/internal/agenthttp/auth.go index 9e34f80017..cbdc7844ee 100644 --- a/vendor/github.com/buildkite/agent/v3/internal/agenthttp/auth.go +++ b/vendor/github.com/buildkite/agent/v3/internal/agenthttp/auth.go @@ -31,7 +31,7 @@ func (t authenticatedTransport) RoundTrip(req *http.Request) (*http.Response, er if req.Body != nil { defer func() { if !reqBodyClosed { - req.Body.Close() + req.Body.Close() //nolint:errcheck // req.Body is only used in a read-only manner. } }() } diff --git a/vendor/github.com/buildkite/agent/v3/internal/agenthttp/do.go b/vendor/github.com/buildkite/agent/v3/internal/agenthttp/do.go index 6d60e2e26f..8bf35b770f 100644 --- a/vendor/github.com/buildkite/agent/v3/internal/agenthttp/do.go +++ b/vendor/github.com/buildkite/agent/v3/internal/agenthttp/do.go @@ -85,11 +85,6 @@ type doConfig struct { func WithDebugHTTP(d bool) DoOption { return func(c *doConfig) { c.debugHTTP = d } } func WithTraceHTTP(t bool) DoOption { return func(c *doConfig) { c.traceHTTP = t } } -type traceEvent struct { - event string - since time.Duration -} - type tracer struct { startTime time.Time logger.Logger @@ -100,15 +95,15 @@ func (t *tracer) Start() { } func (t *tracer) LogTiming(event string) { - t.Logger = t.Logger.WithFields(logger.DurationField(event, time.Since(t.startTime))) + t.Logger = t.WithFields(logger.DurationField(event, time.Since(t.startTime))) } func (t *tracer) LogField(key, value string) { - t.Logger = t.Logger.WithFields(logger.StringField(key, value)) + t.Logger = t.WithFields(logger.StringField(key, value)) } func (t *tracer) LogDuration(event string, d time.Duration) { - t.Logger = t.Logger.WithFields(logger.DurationField(event, d)) + t.Logger = t.WithFields(logger.DurationField(event, d)) } // Currently logger.Logger doesn't give us a way to set the level we want to emit logs at dynamically diff --git a/vendor/github.com/buildkite/agent/v3/logger/buffer.go b/vendor/github.com/buildkite/agent/v3/logger/buffer.go index 84480b7517..e120aacfc4 100644 --- a/vendor/github.com/buildkite/agent/v3/logger/buffer.go +++ b/vendor/github.com/buildkite/agent/v3/logger/buffer.go @@ -26,31 +26,37 @@ func (b *Buffer) Debug(format string, v ...any) { defer b.mu.Unlock() b.Messages = append(b.Messages, "[debug] "+fmt.Sprintf(format, v...)) } + func (b *Buffer) Error(format string, v ...any) { b.mu.Lock() defer b.mu.Unlock() b.Messages = append(b.Messages, "[error] "+fmt.Sprintf(format, v...)) } + func (b *Buffer) Fatal(format string, v ...any) { b.mu.Lock() defer b.mu.Unlock() b.Messages = append(b.Messages, "[fatal] "+fmt.Sprintf(format, v...)) } + func (b *Buffer) Notice(format string, v ...any) { b.mu.Lock() defer b.mu.Unlock() b.Messages = append(b.Messages, "[notice] "+fmt.Sprintf(format, v...)) } + func (b *Buffer) Warn(format string, v ...any) { b.mu.Lock() defer b.mu.Unlock() b.Messages = append(b.Messages, "[warn] "+fmt.Sprintf(format, v...)) } + func (b *Buffer) Info(format string, v ...any) { b.mu.Lock() defer b.mu.Unlock() b.Messages = append(b.Messages, "[info] "+fmt.Sprintf(format, v...)) } + func (b *Buffer) WithFields(fields ...Field) Logger { return b } diff --git a/vendor/github.com/buildkite/agent/v3/logger/log.go b/vendor/github.com/buildkite/agent/v3/logger/log.go index baac48c3af..98b5dcc3d7 100644 --- a/vendor/github.com/buildkite/agent/v3/logger/log.go +++ b/vendor/github.com/buildkite/agent/v3/logger/log.go @@ -6,6 +6,7 @@ package logger import ( + "encoding/json" "fmt" "io" "os" @@ -250,7 +251,13 @@ func (p *JSONPrinter) Print(level Level, msg string, fields Fields) { b.WriteString(fmt.Sprintf(`"ts":%q,`, time.Now().Format(time.RFC3339))) b.WriteString(fmt.Sprintf(`"level":%q,`, level.String())) - b.WriteString(fmt.Sprintf(`"msg":%q,`, msg)) + + // Serialize msg to JSON so we're not producing invalid JSON + jsonMsg, err := json.Marshal(msg) + if err != nil { + jsonMsg = []byte(`"error marshaling message"`) + } + b.WriteString(fmt.Sprintf(`"msg":%s,`, jsonMsg)) for _, field := range fields { b.WriteString(fmt.Sprintf("%q:%q,", field.Key(), field.String())) diff --git a/vendor/github.com/buildkite/agent/v3/version/VERSION b/vendor/github.com/buildkite/agent/v3/version/VERSION index 471861b55f..dcb4257f32 100644 --- a/vendor/github.com/buildkite/agent/v3/version/VERSION +++ b/vendor/github.com/buildkite/agent/v3/version/VERSION @@ -1 +1 @@ -3.98.2 +3.114.1 diff --git a/vendor/github.com/buildkite/agent/v3/version/version.go b/vendor/github.com/buildkite/agent/v3/version/version.go index ac515e225a..d93d5ee0dd 100644 --- a/vendor/github.com/buildkite/agent/v3/version/version.go +++ b/vendor/github.com/buildkite/agent/v3/version/version.go @@ -38,10 +38,6 @@ func BuildNumber() string { return buildNumber } -func IsDevelopmentBuild() bool { - return buildNumber == "x" -} - // commitInfo returns a string consisting of the commit hash and whether the the build was made in a // `dirty` working directory or not. A dirty working directory is one that has uncommitted changes // to files that git would track. diff --git a/vendor/github.com/buildkite/go-pipeline/parser.go b/vendor/github.com/buildkite/go-pipeline/parser.go index a6fe2927f9..4594d97391 100644 --- a/vendor/github.com/buildkite/go-pipeline/parser.go +++ b/vendor/github.com/buildkite/go-pipeline/parser.go @@ -3,6 +3,7 @@ package pipeline import ( "errors" "io" + "iter" "strings" "github.com/buildkite/go-pipeline/ordered" @@ -13,6 +14,9 @@ import ( type Options func(*Pipeline) // Parse parses a pipeline. It does not apply interpolation. +// Note that it only parses the first YAML document in the input. +// To parse all YAML documents in the input reader as pipelines, use ParseAll. +// // Warnings are passed through the err return: // // p, err := Parse(src) @@ -42,6 +46,46 @@ func Parse(src io.Reader) (*Pipeline, error) { return p, ordered.Unmarshal(n, p) } +// ParseAll parses all YAML documents in the input stream as pipelines. +// It does not stop yielding on decoding or unmarshaling errors. +// It does not apply interpolation. +// +// Warnings are passed through the err return: +// +// for p, err := range ParseAll(src) { +// if w := warning.As(err); w != nil { +// // Here are some warnings that should be shown +// log.Printf("*Warning* - pipeline is not fully parsed:\n%v", w) +// } else if err != nil { +// // Parse could not understand src at all +// return err +// } +// // Use p +// } +func ParseAll(src io.Reader) iter.Seq2[*Pipeline, error] { + dec := yaml.NewDecoder(src) + return func(yield func(*Pipeline, error) bool) { + for { + // The loop body here is essentially similar to Parse (above). + n := new(yaml.Node) + if err := dec.Decode(n); err != nil { + if err == io.EOF { + return // end of stream + } + if !yield(nil, formatYAMLError(err)) { + return + } + continue + } + + p := new(Pipeline) + if !yield(p, ordered.Unmarshal(n, p)) { + return + } + } + } +} + func formatYAMLError(err error) error { return errors.New(strings.TrimPrefix(err.Error(), "yaml: ")) } diff --git a/vendor/github.com/buildkite/go-pipeline/pipeline.go b/vendor/github.com/buildkite/go-pipeline/pipeline.go index a535d49a65..ec8f0f0b8f 100644 --- a/vendor/github.com/buildkite/go-pipeline/pipeline.go +++ b/vendor/github.com/buildkite/go-pipeline/pipeline.go @@ -13,8 +13,9 @@ import ( // // Standard caveats apply - see the package comment. type Pipeline struct { - Steps Steps `yaml:"steps"` - Env *ordered.MapSS `yaml:"env,omitempty"` + Steps Steps `yaml:"steps"` + Env *ordered.MapSS `yaml:"env,omitempty"` + Secrets Secrets `yaml:"secrets,omitempty"` // RemainingFields stores any other top-level mapping items so they at least // survive an unmarshal-marshal round-trip. diff --git a/vendor/github.com/buildkite/go-pipeline/secret.go b/vendor/github.com/buildkite/go-pipeline/secret.go new file mode 100644 index 0000000000..8b5f437879 --- /dev/null +++ b/vendor/github.com/buildkite/go-pipeline/secret.go @@ -0,0 +1,43 @@ +package pipeline + +import ( + "encoding/json" + "fmt" +) + +var ( + _ interface { + json.Marshaler + selfInterpolater + } = (*Secret)(nil) +) + +// Secret represents a pipeline secret configuration. +type Secret struct { + Key string `json:"key" yaml:"key"` + EnvironmentVariable string `json:"environment_variable,omitempty" yaml:"environment_variable,omitempty"` + RemainingFields map[string]any `yaml:",inline"` +} + +// MarshalJSON marshals the secret to JSON. +func (s Secret) MarshalJSON() ([]byte, error) { + return inlineFriendlyMarshalJSON(s) +} + +func (s *Secret) interpolate(tf stringTransformer) error { + key, err := tf.Transform(s.Key) + if err != nil { + return fmt.Errorf("interpolating secret key: %w", err) + } + s.Key = key + + if s.EnvironmentVariable != "" { + envVar, err := tf.Transform(s.EnvironmentVariable) + if err != nil { + return fmt.Errorf("interpolating environment variable: %w", err) + } + s.EnvironmentVariable = envVar + } + + return nil +} diff --git a/vendor/github.com/buildkite/go-pipeline/secrets.go b/vendor/github.com/buildkite/go-pipeline/secrets.go new file mode 100644 index 0000000000..23d6522522 --- /dev/null +++ b/vendor/github.com/buildkite/go-pipeline/secrets.go @@ -0,0 +1,141 @@ +package pipeline + +import ( + "encoding/json" + "fmt" + + "github.com/buildkite/go-pipeline/ordered" + "gopkg.in/yaml.v3" +) + +var _ interface { + json.Unmarshaler + ordered.Unmarshaler + yaml.Marshaler +} = (*Secrets)(nil) + +// Secrets is a sequence of secrets. It is useful for unmarshaling. +type Secrets []Secret + +// UnmarshalOrdered unmarshals Secrets from []any (sequence of secret names). +func (s *Secrets) UnmarshalOrdered(o any) error { + switch o := o.(type) { + case nil: + // `secrets: null` is invalid - should be omitted entirely or use valid formats + return fmt.Errorf("unmarshaling secrets: secrets cannot be null") + + case *ordered.Map[string, any]: + // Handle map syntax: {"ENV_VAR": "SECRET_KEY"} + return o.Range(func(envVar string, secretKeyVal any) error { + secretKey, ok := secretKeyVal.(string) + if !ok { + return fmt.Errorf("unmarshaling secrets: secret key must be a string, but was %T", secretKeyVal) + } + if secretKey == "" { + return fmt.Errorf("unmarshaling secrets: secret key cannot be empty") + } + if envVar == "" { + return fmt.Errorf("unmarshaling secrets: environment variable name cannot be empty") + } + + secret := Secret{ + Key: secretKey, + EnvironmentVariable: envVar, + } + *s = append(*s, secret) + return nil + }) + + case []any: + for _, c := range o { + switch ct := c.(type) { + case string: + secret := Secret{ + Key: ct, + EnvironmentVariable: ct, // Default EnvironmentVariable to key value for simple string format + } + *s = append(*s, secret) + + case *ordered.Map[string, interface{}]: + // Backend sends ordered.Map format + secret := Secret{} + + keyVal, _ := ct.Get("key") + key, _ := keyVal.(string) + if key == "" { + return fmt.Errorf("unmarshaling secret: key must be a non-empty string, but was %[1]T %[1]v", keyVal) + } + secret.Key = key + + if envVarVal, _ := ct.Get("environment_variable"); envVarVal != nil { + envVar, ok := envVarVal.(string) + if !ok { + return fmt.Errorf("unmarshaling secret: environment_variable must be a string, but was %T", envVarVal) + } + secret.EnvironmentVariable = envVar + } + + *s = append(*s, secret) + + default: + return fmt.Errorf("unmarshaling secrets: secret type %T, want string, map[string]any, or *ordered.Map", c) + } + } + + default: + return fmt.Errorf("unmarshaling secrets: got %T, want []any or map[string]any", o) + } + + return nil +} + +// MergeWith merges these secrets with another set of secrets, with the other secrets taking precedence. +// Deduplication is performed based on the EnvironmentVariable field. +func (s Secrets) MergeWith(other Secrets) Secrets { + if len(s) == 0 { + return other + } + if len(other) == 0 { + return s + } + + // Create a map to track environment variables we've seen for deduplication + seen := make(map[string]bool) + var result Secrets + + for _, secret := range other { + if secret.EnvironmentVariable != "" && !seen[secret.EnvironmentVariable] { + result = append(result, secret) + seen[secret.EnvironmentVariable] = true + } + } + + for _, secret := range s { + if secret.EnvironmentVariable != "" && !seen[secret.EnvironmentVariable] { + result = append(result, secret) + seen[secret.EnvironmentVariable] = true + } + } + + return result +} + +// UnmarshalJSON is used for JSON unmarshaling. +func (s *Secrets) UnmarshalJSON(b []byte) error { + // JSON is just a specific kind of YAML. + var n yaml.Node + if err := yaml.Unmarshal(b, &n); err != nil { + return err + } + return ordered.Unmarshal(&n, &s) +} + +func (s Secrets) MarshalYAML() (any, error) { + if len(s) == 0 { + return nil, nil + } + + result := make([]Secret, len(s)) + copy(result, s) + return result, nil +} diff --git a/vendor/github.com/buildkite/go-pipeline/step_command.go b/vendor/github.com/buildkite/go-pipeline/step_command.go index b49ed4c2d0..29e6922543 100644 --- a/vendor/github.com/buildkite/go-pipeline/step_command.go +++ b/vendor/github.com/buildkite/go-pipeline/step_command.go @@ -33,6 +33,7 @@ type CommandStep struct { // Fields that are meaningful specifically for command steps Command string `yaml:"command"` Plugins Plugins `yaml:"plugins,omitempty"` + Secrets Secrets `yaml:"secrets,omitempty"` Env map[string]string `yaml:"env,omitempty"` Signature *Signature `yaml:"signature,omitempty"` Matrix *Matrix `yaml:"matrix,omitempty"` @@ -99,7 +100,7 @@ func (c *CommandStep) InterpolateMatrixPermutation(mp MatrixPermutation) error { func (c *CommandStep) interpolate(tf stringTransformer) error { // Fields that are interpolated with env vars and matrix tokens: - // command, plugins + // command, plugins, secrets if err := interpolateString(tf, &c.Command); err != nil { return fmt.Errorf("interpolating command: %w", err) } @@ -109,6 +110,9 @@ func (c *CommandStep) interpolate(tf stringTransformer) error { if err := interpolateSlice(tf, c.Plugins); err != nil { return fmt.Errorf("interpolating plugins: %w", err) } + if err := interpolateSlice(tf, c.Secrets); err != nil { + return fmt.Errorf("interpolating secrets: %w", err) + } switch tf.(type) { case envInterpolator: @@ -141,4 +145,10 @@ func (c *CommandStep) interpolate(tf stringTransformer) error { return nil } +// MergeSecretsFromPipeline merges pipeline-level secrets with this step's secrets. +// Step-level secrets take precedence over pipeline-level secrets for deduplication. +func (c *CommandStep) MergeSecretsFromPipeline(pipelineSecrets Secrets) { + c.Secrets = pipelineSecrets.MergeWith(c.Secrets) +} + func (CommandStep) stepTag() {} diff --git a/vendor/github.com/buildkite/go-pipeline/step_command_matrix.go b/vendor/github.com/buildkite/go-pipeline/step_command_matrix.go index ba75e74f18..e69ea4a762 100644 --- a/vendor/github.com/buildkite/go-pipeline/step_command_matrix.go +++ b/vendor/github.com/buildkite/go-pipeline/step_command_matrix.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "slices" "github.com/buildkite/go-pipeline/ordered" "gopkg.in/yaml.v3" @@ -158,14 +159,7 @@ func (m *Matrix) validatePermutation(p MatrixPermutation) error { // permutation). Whether they are or are not, we still check adjustments. valid := true for dim, val := range p { - match := false - for _, v := range m.Setup[dim] { - if val == v { - match = true - break - } - } - if !match { + if !slices.Contains(m.Setup[dim], val) { // Not a basic permutation. It could still be an adjustment though. valid = false break diff --git a/vendor/github.com/buildkite/roko/README.md b/vendor/github.com/buildkite/roko/README.md index 84b4c31801..509d71f193 100644 --- a/vendor/github.com/buildkite/roko/README.md +++ b/vendor/github.com/buildkite/roko/README.md @@ -197,8 +197,6 @@ The random number generator is only used for jitter, so it only makes sense to p Roko is named after [Josevata Rokocoko](https://en.wikipedia.org/wiki/Joe_Rokocoko), a Fijian-New Zealand rugby player, and one of the best to ever do it. He scored a lot of tries, thus, he's a re-trier. -Depending on who you ask, it's also [the owner of a basilisk](https://rationalwiki.org/wiki/Roko%27s_basilisk). - ## Contributing By all means, please contribute! We'd love to have your input. If you run into a bug, feel free to open an issue, and if you find missing functionality, please don't hesitate to open a PR. If you have a weird and wonderful retry strategy you'd like to add, we'd love to see it. diff --git a/vendor/github.com/buildkite/roko/retrier.go b/vendor/github.com/buildkite/roko/retrier.go index 17213ab43d..9a6ff2bc17 100644 --- a/vendor/github.com/buildkite/roko/retrier.go +++ b/vendor/github.com/buildkite/roko/retrier.go @@ -92,23 +92,23 @@ func ExponentialSubsecond(initial time.Duration) (Strategy, string) { }, exponentialStrategy } -type retrierOpt func(*Retrier) +type RetrierOpt func(*Retrier) // WithMaxAttempts sets the maximum number of retries that a retrier will attempt -func WithMaxAttempts(maxAttempts int) retrierOpt { +func WithMaxAttempts(maxAttempts int) RetrierOpt { return func(r *Retrier) { r.maxAttempts = maxAttempts } } -func WithRand(rand *rand.Rand) retrierOpt { +func WithRand(rand *rand.Rand) RetrierOpt { return func(r *Retrier) { r.rand = rand } } // WithStrategy sets the retry strategy that the retrier will use to determine how long to wait between retries -func WithStrategy(strategy Strategy, strategyType string) retrierOpt { +func WithStrategy(strategy Strategy, strategyType string) RetrierOpt { return func(r *Retrier) { r.strategyType = strategyType r.intervalCalculator = strategy @@ -119,7 +119,7 @@ func WithStrategy(strategy Strategy, strategyType string) retrierOpt { // The idea here is to avoid thundering herds - retries that are in parallel will happen at slightly different times when // jitter is enabled, whereas if jitter is disabled, all the retries might happen at the same time, causing further load // on the system that we're tryung to do something with -func WithJitter() retrierOpt { +func WithJitter() RetrierOpt { return func(r *Retrier) { r.jitter = true r.jitterRange = jitterRange{min: 0, max: defaultJitterInterval} @@ -131,7 +131,7 @@ func WithJitter() retrierOpt { // to the interval calculated by the retry strategy. The jitter will be recalculated for each retry. Both min and max may // be negative, but min must be less than max. min and max may both be zero, which is equivalent to disabling jitter. // If a negative jitter causes a negative interval, the interval will be clamped to zero. -func WithJitterRange(min, max time.Duration) retrierOpt { +func WithJitterRange(min, max time.Duration) RetrierOpt { if min >= max { panic("min must be less than max") } @@ -147,7 +147,7 @@ func WithJitterRange(min, max time.Duration) retrierOpt { // TryForever causes the retrier to to never give up retrying, until either the operation succeeds, or the operation // calls retrier.Break() -func TryForever() retrierOpt { +func TryForever() RetrierOpt { return func(r *Retrier) { r.forever = true } @@ -155,7 +155,7 @@ func TryForever() retrierOpt { // WithSleepFunc sets the function that the retrier uses to sleep between successive attempts // Only really useful for testing -func WithSleepFunc(f func(time.Duration)) retrierOpt { +func WithSleepFunc(f func(time.Duration)) RetrierOpt { return func(r *Retrier) { r.sleepFunc = f } @@ -163,7 +163,7 @@ func WithSleepFunc(f func(time.Duration)) retrierOpt { // NewRetrier creates a new instance of the Retrier struct. Pass in retrierOpt functions to customise the behaviour of // the retrier -func NewRetrier(opts ...retrierOpt) *Retrier { +func NewRetrier(opts ...RetrierOpt) *Retrier { r := &Retrier{ rand: defaultRandom, } diff --git a/vendor/github.com/cenkalti/backoff/v5/exponential.go b/vendor/github.com/cenkalti/backoff/v5/exponential.go index c1f3e442d3..79d425e874 100644 --- a/vendor/github.com/cenkalti/backoff/v5/exponential.go +++ b/vendor/github.com/cenkalti/backoff/v5/exponential.go @@ -1,7 +1,7 @@ package backoff import ( - "math/rand" + "math/rand/v2" "time" ) @@ -28,13 +28,7 @@ multiplied by the exponential, that is, between 2 and 6 seconds. Note: MaxInterval caps the RetryInterval and not the randomized interval. -If the time elapsed since an ExponentialBackOff instance is created goes past the -MaxElapsedTime, then the method NextBackOff() starts returning backoff.Stop. - -The elapsed time can be reset by calling Reset(). - -Example: Given the following default arguments, for 10 tries the sequence will be, -and assuming we go over the MaxElapsedTime on the 10th try: +Example: Given the following default arguments, for 9 tries the sequence will be: Request # RetryInterval (seconds) Randomized Interval (seconds) @@ -47,7 +41,6 @@ and assuming we go over the MaxElapsedTime on the 10th try: 7 5.692 [2.846, 8.538] 8 8.538 [4.269, 12.807] 9 12.807 [6.403, 19.210] - 10 19.210 backoff.Stop Note: Implementation is not thread-safe. */ diff --git a/vendor/github.com/cenkalti/backoff/v5/retry.go b/vendor/github.com/cenkalti/backoff/v5/retry.go index e43f47fb8a..32a7f98834 100644 --- a/vendor/github.com/cenkalti/backoff/v5/retry.go +++ b/vendor/github.com/cenkalti/backoff/v5/retry.go @@ -47,7 +47,7 @@ func WithNotify(n Notify) RetryOption { } } -// WithMaxTries limits the number of retry attempts. +// WithMaxTries limits the number of all attempts. func WithMaxTries(n uint) RetryOption { return func(args *retryOptions) { args.MaxTries = n @@ -97,7 +97,7 @@ func Retry[T any](ctx context.Context, operation Operation[T], opts ...RetryOpti // Handle permanent errors without retrying. var permanent *PermanentError if errors.As(err, &permanent) { - return res, err + return res, permanent.Unwrap() } // Stop retrying if context is cancelled. diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/build.go b/vendor/github.com/containerd/stargz-snapshotter/estargz/build.go index 6aba0ef1f6..a9e1b72ba7 100644 --- a/vendor/github.com/containerd/stargz-snapshotter/estargz/build.go +++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/build.go @@ -35,6 +35,7 @@ import ( "runtime" "strings" "sync" + "sync/atomic" "github.com/containerd/stargz-snapshotter/estargz/errorutil" "github.com/klauspost/compress/zstd" @@ -42,6 +43,8 @@ import ( "golang.org/x/sync/errgroup" ) +type GzipHelperFunc func(io.Reader) (io.ReadCloser, error) + type options struct { chunkSize int compressionLevel int @@ -50,6 +53,7 @@ type options struct { compression Compression ctx context.Context minChunkSize int + gzipHelperFunc GzipHelperFunc } type Option func(o *options) error @@ -127,11 +131,25 @@ func WithMinChunkSize(minChunkSize int) Option { } } +// WithGzipHelperFunc option specifies a custom function to decompress gzip-compressed layers. +// When a gzip-compressed layer is detected, this function will be used instead of the +// Go standard library gzip decompression for better performance. +// The function should take an io.Reader as input and return an io.ReadCloser. +// If nil, the Go standard library gzip.NewReader will be used. +func WithGzipHelperFunc(gzipHelperFunc GzipHelperFunc) Option { + return func(o *options) error { + o.gzipHelperFunc = gzipHelperFunc + return nil + } +} + // Blob is an eStargz blob. type Blob struct { io.ReadCloser - diffID digest.Digester - tocDigest digest.Digest + diffID digest.Digester + tocDigest digest.Digest + readCompleted *atomic.Bool + uncompressedSize *atomic.Int64 } // DiffID returns the digest of uncompressed blob. @@ -145,6 +163,19 @@ func (b *Blob) TOCDigest() digest.Digest { return b.tocDigest } +// UncompressedSize returns the size of uncompressed blob. +// UncompressedSize should only be called after the blob has been fully read. +func (b *Blob) UncompressedSize() (int64, error) { + switch { + case b.uncompressedSize == nil || b.readCompleted == nil: + return -1, fmt.Errorf("readCompleted or uncompressedSize is not initialized") + case !b.readCompleted.Load(): + return -1, fmt.Errorf("called UncompressedSize before the blob has been fully read") + default: + return b.uncompressedSize.Load(), nil + } +} + // Build builds an eStargz blob which is an extended version of stargz, from a blob (gzip, zstd // or plain tar) passed through the argument. If there are some prioritized files are listed in // the option, these files are grouped as "prioritized" and can be used for runtime optimization @@ -186,7 +217,7 @@ func Build(tarBlob *io.SectionReader, opt ...Option) (_ *Blob, rErr error) { rErr = fmt.Errorf("error from context %q: %w", cErr, rErr) } }() - tarBlob, err := decompressBlob(tarBlob, layerFiles) + tarBlob, err := decompressBlob(tarBlob, layerFiles, opts.gzipHelperFunc) if err != nil { return nil, err } @@ -252,17 +283,28 @@ func Build(tarBlob *io.SectionReader, opt ...Option) (_ *Blob, rErr error) { } diffID := digest.Canonical.Digester() pr, pw := io.Pipe() + readCompleted := new(atomic.Bool) + uncompressedSize := new(atomic.Int64) go func() { - r, err := opts.compression.Reader(io.TeeReader(io.MultiReader(append(rs, tocAndFooter)...), pw)) + var size int64 + var decompressFunc func(io.Reader) (io.ReadCloser, error) + if _, ok := opts.compression.(*gzipCompression); ok && opts.gzipHelperFunc != nil { + decompressFunc = opts.gzipHelperFunc + } else { + decompressFunc = opts.compression.Reader + } + decompressR, err := decompressFunc(io.TeeReader(io.MultiReader(append(rs, tocAndFooter)...), pw)) if err != nil { pw.CloseWithError(err) return } - defer r.Close() - if _, err := io.Copy(diffID.Hash(), r); err != nil { + defer decompressR.Close() + if size, err = io.Copy(diffID.Hash(), decompressR); err != nil { pw.CloseWithError(err) return } + uncompressedSize.Store(size) + readCompleted.Store(true) pw.Close() }() return &Blob{ @@ -270,8 +312,10 @@ func Build(tarBlob *io.SectionReader, opt ...Option) (_ *Blob, rErr error) { Reader: pr, closeFunc: layerFiles.CleanupAll, }, - tocDigest: tocDgst, - diffID: diffID, + tocDigest: tocDgst, + diffID: diffID, + readCompleted: readCompleted, + uncompressedSize: uncompressedSize, }, nil } @@ -366,8 +410,9 @@ func sortEntries(in io.ReaderAt, prioritized []string, missedPrioritized *[]stri // Sort the tar file respecting to the prioritized files list. sorted := &tarFile{} + picked := make(map[string]struct{}) for _, l := range prioritized { - if err := moveRec(l, intar, sorted); err != nil { + if err := moveRec(l, intar, sorted, picked); err != nil { if errors.Is(err, errNotFound) && missedPrioritized != nil { *missedPrioritized = append(*missedPrioritized, l) continue // allow not found @@ -395,8 +440,8 @@ func sortEntries(in io.ReaderAt, prioritized []string, missedPrioritized *[]stri }) } - // Dump all entry and concatinate them. - return append(sorted.dump(), intar.dump()...), nil + // Dump prioritized entries followed by the rest entries while skipping picked ones. + return append(sorted.dump(nil), intar.dump(picked)...), nil } // readerFromEntries returns a reader of tar archive that contains entries passed @@ -408,11 +453,11 @@ func readerFromEntries(entries ...*entry) io.Reader { defer tw.Close() for _, entry := range entries { if err := tw.WriteHeader(entry.header); err != nil { - pw.CloseWithError(fmt.Errorf("Failed to write tar header: %v", err)) + pw.CloseWithError(fmt.Errorf("failed to write tar header: %v", err)) return } if _, err := io.Copy(tw, entry.payload); err != nil { - pw.CloseWithError(fmt.Errorf("Failed to write tar payload: %v", err)) + pw.CloseWithError(fmt.Errorf("failed to write tar payload: %v", err)) return } } @@ -458,36 +503,42 @@ func importTar(in io.ReaderAt) (*tarFile, error) { return tf, nil } -func moveRec(name string, in *tarFile, out *tarFile) error { +func moveRec(name string, in *tarFile, out *tarFile, picked map[string]struct{}) error { name = cleanEntryName(name) if name == "" { // root directory. stop recursion. if e, ok := in.get(name); ok { // entry of the root directory exists. we should move it as well. // this case will occur if tar entries are prefixed with "./", "/", etc. - out.add(e) - in.remove(name) + if _, done := picked[name]; !done { + out.add(e) + picked[name] = struct{}{} + } } return nil } _, okIn := in.get(name) _, okOut := out.get(name) - if !okIn && !okOut { + _, okPicked := picked[name] + if !okIn && !okOut && !okPicked { return fmt.Errorf("file: %q: %w", name, errNotFound) } parent, _ := path.Split(strings.TrimSuffix(name, "/")) - if err := moveRec(parent, in, out); err != nil { + if err := moveRec(parent, in, out, picked); err != nil { return err } if e, ok := in.get(name); ok && e.header.Typeflag == tar.TypeLink { - if err := moveRec(e.header.Linkname, in, out); err != nil { + if err := moveRec(e.header.Linkname, in, out, picked); err != nil { return err } } + if _, done := picked[name]; done { + return nil + } if e, ok := in.get(name); ok { out.add(e) - in.remove(name) + picked[name] = struct{}{} } return nil } @@ -533,8 +584,18 @@ func (f *tarFile) get(name string) (e *entry, ok bool) { return } -func (f *tarFile) dump() []*entry { - return f.stream +func (f *tarFile) dump(skip map[string]struct{}) []*entry { + if len(skip) == 0 { + return f.stream + } + var out []*entry + for _, e := range f.stream { + if _, ok := skip[cleanEntryName(e.header.Name)]; ok { + continue + } + out = append(out, e) + } + return out } type readCloser struct { @@ -627,12 +688,12 @@ func (cr *countReadSeeker) Seek(offset int64, whence int) (int64, error) { switch whence { default: - return 0, fmt.Errorf("Unknown whence: %v", whence) + return 0, fmt.Errorf("unknown whence: %v", whence) case io.SeekStart: case io.SeekCurrent: offset += *cr.cPos case io.SeekEnd: - return 0, fmt.Errorf("Unsupported whence: %v", whence) + return 0, fmt.Errorf("unsupported whence: %v", whence) } if offset < 0 { @@ -649,7 +710,7 @@ func (cr *countReadSeeker) currentPos() int64 { return *cr.cPos } -func decompressBlob(org *io.SectionReader, tmp *tempFiles) (*io.SectionReader, error) { +func decompressBlob(org *io.SectionReader, tmp *tempFiles, gzipHelperFunc GzipHelperFunc) (*io.SectionReader, error) { if org.Size() < 4 { return org, nil } @@ -660,7 +721,13 @@ func decompressBlob(org *io.SectionReader, tmp *tempFiles) (*io.SectionReader, e var dR io.Reader if bytes.Equal([]byte{0x1F, 0x8B, 0x08}, src[:3]) { // gzip - dgR, err := gzip.NewReader(io.NewSectionReader(org, 0, org.Size())) + var dgR io.ReadCloser + var err error + if gzipHelperFunc != nil { + dgR, err = gzipHelperFunc(io.NewSectionReader(org, 0, org.Size())) + } else { + dgR, err = gzip.NewReader(io.NewSectionReader(org, 0, org.Size())) + } if err != nil { return nil, err } diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go b/vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go index f4d5546558..ff91a37add 100644 --- a/vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go +++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go @@ -307,6 +307,15 @@ func (r *Reader) initFields() error { } } + if len(r.m) == 0 { + r.m[""] = &TOCEntry{ + Name: "", + Type: "dir", + Mode: 0755, + NumLink: 1, + } + } + return nil } diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go b/vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go index f24afe32f4..88fa13b191 100644 --- a/vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go +++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go @@ -109,7 +109,7 @@ func gzipFooterBytes(tocOff int64) []byte { header[0], header[1] = 'S', 'G' subfield := fmt.Sprintf("%016xSTARGZ", tocOff) binary.LittleEndian.PutUint16(header[2:4], uint16(len(subfield))) // little-endian per RFC1952 - gz.Header.Extra = append(header, []byte(subfield)...) + gz.Extra = append(header, []byte(subfield)...) gz.Close() if buf.Len() != FooterSize { panic(fmt.Sprintf("footer buffer = %d, not %d", buf.Len(), FooterSize)) @@ -136,7 +136,7 @@ func (gz *GzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOffset, t return 0, 0, 0, err } defer zr.Close() - extra := zr.Header.Extra + extra := zr.Extra si1, si2, subfieldlen, subfield := extra[0], extra[1], extra[2:4], extra[4:] if si1 != 'S' || si2 != 'G' { return 0, 0, 0, fmt.Errorf("invalid subfield IDs: %q, %q; want E, S", si1, si2) @@ -181,7 +181,7 @@ func (gz *LegacyGzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOff return 0, 0, 0, fmt.Errorf("legacy: failed to get footer gzip reader: %w", err) } defer zr.Close() - extra := zr.Header.Extra + extra := zr.Extra if len(extra) != 16+len("STARGZ") { return 0, 0, 0, fmt.Errorf("legacy: invalid stargz's extra field size") } diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/testutil.go b/vendor/github.com/containerd/stargz-snapshotter/estargz/testutil.go index ba650b4d1d..ff165e090e 100644 --- a/vendor/github.com/containerd/stargz-snapshotter/estargz/testutil.go +++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/testutil.go @@ -38,7 +38,6 @@ import ( "reflect" "sort" "strings" - "testing" "time" "github.com/containerd/stargz-snapshotter/estargz/errorutil" @@ -49,16 +48,48 @@ import ( // TestingController is Compression with some helper methods necessary for testing. type TestingController interface { Compression - TestStreams(t *testing.T, b []byte, streams []int64) - DiffIDOf(*testing.T, []byte) string + TestStreams(t TestingT, b []byte, streams []int64) + DiffIDOf(TestingT, []byte) string String() string } +// TestingT is the minimal set of testing.T required to run the +// tests defined in CompressionTestSuite. This interface exists to prevent +// leaking the testing package from being exposed outside tests. +type TestingT interface { + Errorf(format string, args ...any) + FailNow() + Failed() bool + Fatal(args ...any) + Fatalf(format string, args ...any) + Logf(format string, args ...any) + Parallel() +} + +// Runner allows running subtests of TestingT. This exists instead of adding +// a Run method to TestingT interface because the Run implementation of +// testing.T would not satisfy the interface. +type Runner func(t TestingT, name string, fn func(t TestingT)) + +type TestRunner struct { + TestingT + Runner Runner +} + +func (r *TestRunner) Run(name string, run func(*TestRunner)) { + r.Runner(r.TestingT, name, func(t TestingT) { + run(&TestRunner{TestingT: t, Runner: r.Runner}) + }) +} + // CompressionTestSuite tests this pkg with controllers can build valid eStargz blobs and parse them. -func CompressionTestSuite(t *testing.T, controllers ...TestingControllerFactory) { - t.Run("testBuild", func(t *testing.T) { t.Parallel(); testBuild(t, controllers...) }) - t.Run("testDigestAndVerify", func(t *testing.T) { t.Parallel(); testDigestAndVerify(t, controllers...) }) - t.Run("testWriteAndOpen", func(t *testing.T) { t.Parallel(); testWriteAndOpen(t, controllers...) }) +func CompressionTestSuite(t *TestRunner, controllers ...TestingControllerFactory) { + t.Run("testBuild", func(t *TestRunner) { t.Parallel(); testBuild(t, controllers...) }) + t.Run("testDigestAndVerify", func(t *TestRunner) { + t.Parallel() + testDigestAndVerify(t, controllers...) + }) + t.Run("testWriteAndOpen", func(t *TestRunner) { t.Parallel(); testWriteAndOpen(t, controllers...) }) } type TestingControllerFactory func() TestingController @@ -79,7 +110,7 @@ var allowedPrefix = [4]string{"", "./", "/", "../"} // testBuild tests the resulting stargz blob built by this pkg has the same // contents as the normal stargz blob. -func testBuild(t *testing.T, controllers ...TestingControllerFactory) { +func testBuild(t *TestRunner, controllers ...TestingControllerFactory) { tests := []struct { name string chunkSize int @@ -165,7 +196,7 @@ func testBuild(t *testing.T, controllers ...TestingControllerFactory) { prefix := prefix for _, minChunkSize := range tt.minChunkSize { minChunkSize := minChunkSize - t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,src=%d,format=%s,minChunkSize=%d", newCL(), prefix, srcCompression, srcTarFormat, minChunkSize), func(t *testing.T) { + t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,src=%d,format=%s,minChunkSize=%d", newCL(), prefix, srcCompression, srcTarFormat, minChunkSize), func(t *TestRunner) { tarBlob := buildTar(t, tt.in, prefix, srcTarFormat) // Test divideEntries() entries, err := sortEntries(tarBlob, nil, nil) // identical order @@ -265,7 +296,7 @@ func testBuild(t *testing.T, controllers ...TestingControllerFactory) { } } -func isSameTarGz(t *testing.T, cla TestingController, a []byte, clb TestingController, b []byte) bool { +func isSameTarGz(t TestingT, cla TestingController, a []byte, clb TestingController, b []byte) bool { aGz, err := cla.Reader(bytes.NewReader(a)) if err != nil { t.Fatalf("failed to read A") @@ -325,7 +356,7 @@ func isSameTarGz(t *testing.T, cla TestingController, a []byte, clb TestingContr return true } -func isSameVersion(t *testing.T, cla TestingController, a []byte, clb TestingController, b []byte) bool { +func isSameVersion(t TestingT, cla TestingController, a []byte, clb TestingController, b []byte) bool { aJTOC, _, err := parseStargz(io.NewSectionReader(bytes.NewReader(a), 0, int64(len(a))), cla) if err != nil { t.Fatalf("failed to parse A: %v", err) @@ -339,7 +370,7 @@ func isSameVersion(t *testing.T, cla TestingController, a []byte, clb TestingCon return aJTOC.Version == bJTOC.Version } -func isSameEntries(t *testing.T, a, b *Reader) bool { +func isSameEntries(t TestingT, a, b *Reader) bool { aroot, ok := a.Lookup("") if !ok { t.Fatalf("failed to get root of A") @@ -353,18 +384,19 @@ func isSameEntries(t *testing.T, a, b *Reader) bool { return contains(t, aEntry, bEntry) && contains(t, bEntry, aEntry) } -func compressBlob(t *testing.T, src *io.SectionReader, srcCompression int) *io.SectionReader { +func compressBlob(t TestingT, src *io.SectionReader, srcCompression int) *io.SectionReader { buf := new(bytes.Buffer) var w io.WriteCloser var err error - if srcCompression == gzipType { + switch srcCompression { + case gzipType: w = gzip.NewWriter(buf) - } else if srcCompression == zstdType { + case zstdType: w, err = zstd.NewWriter(buf) if err != nil { t.Fatalf("failed to init zstd writer: %v", err) } - } else { + default: return src } src.Seek(0, io.SeekStart) @@ -386,7 +418,7 @@ type stargzEntry struct { // contains checks if all child entries in "b" are also contained in "a". // This function also checks if the files/chunks contain the same contents among "a" and "b". -func contains(t *testing.T, a, b stargzEntry) bool { +func contains(t TestingT, a, b stargzEntry) bool { ae, ar := a.e, a.r be, br := b.e, b.r t.Logf("Comparing: %q vs %q", ae.Name, be.Name) @@ -445,7 +477,7 @@ func contains(t *testing.T, a, b stargzEntry) bool { bbytes, bnext, bok := readOffset(t, bf, nr, b) if !aok && !bok { break - } else if !(aok && bok) || anext != bnext { + } else if !aok || !bok || anext != bnext { t.Logf("%q != %q (offset=%d): chunk existence a=%v vs b=%v, anext=%v vs bnext=%v", ae.Name, be.Name, nr, aok, bok, anext, bnext) return false @@ -497,7 +529,7 @@ func equalEntry(a, b *TOCEntry) bool { a.Digest == b.Digest } -func readOffset(t *testing.T, r *io.SectionReader, offset int64, e stargzEntry) ([]byte, int64, bool) { +func readOffset(t TestingT, r *io.SectionReader, offset int64, e stargzEntry) ([]byte, int64, bool) { ce, ok := e.r.ChunkEntryForOffset(e.e.Name, offset) if !ok { return nil, 0, false @@ -516,7 +548,7 @@ func readOffset(t *testing.T, r *io.SectionReader, offset int64, e stargzEntry) return data[:n], offset + ce.ChunkSize, true } -func dumpTOCJSON(t *testing.T, tocJSON *JTOC) string { +func dumpTOCJSON(t TestingT, tocJSON *JTOC) string { jtocData, err := json.Marshal(*tocJSON) if err != nil { t.Fatalf("failed to marshal TOC JSON: %v", err) @@ -530,20 +562,19 @@ func dumpTOCJSON(t *testing.T, tocJSON *JTOC) string { const chunkSize = 3 -// type check func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, compressionLevel int) -type check func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) +type check func(t *TestRunner, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) // testDigestAndVerify runs specified checks against sample stargz blobs. -func testDigestAndVerify(t *testing.T, controllers ...TestingControllerFactory) { +func testDigestAndVerify(t *TestRunner, controllers ...TestingControllerFactory) { tests := []struct { name string - tarInit func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) + tarInit func(t TestingT, dgstMap map[string]digest.Digest) (blob []tarEntry) checks []check minChunkSize []int }{ { name: "no-regfile", - tarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) { + tarInit: func(t TestingT, dgstMap map[string]digest.Digest) (blob []tarEntry) { return tarOf( dir("test/"), ) @@ -558,7 +589,7 @@ func testDigestAndVerify(t *testing.T, controllers ...TestingControllerFactory) }, { name: "small-files", - tarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) { + tarInit: func(t TestingT, dgstMap map[string]digest.Digest) (blob []tarEntry) { return tarOf( regDigest(t, "baz.txt", "", dgstMap), regDigest(t, "foo.txt", "a", dgstMap), @@ -582,7 +613,7 @@ func testDigestAndVerify(t *testing.T, controllers ...TestingControllerFactory) }, { name: "big-files", - tarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) { + tarInit: func(t TestingT, dgstMap map[string]digest.Digest) (blob []tarEntry) { return tarOf( regDigest(t, "baz.txt", "bazbazbazbazbazbazbaz", dgstMap), regDigest(t, "foo.txt", "a", dgstMap), @@ -606,7 +637,7 @@ func testDigestAndVerify(t *testing.T, controllers ...TestingControllerFactory) { name: "with-non-regfiles", minChunkSize: []int{0, 64000}, - tarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) { + tarInit: func(t TestingT, dgstMap map[string]digest.Digest) (blob []tarEntry) { return tarOf( regDigest(t, "baz.txt", "bazbazbazbazbazbazbaz", dgstMap), regDigest(t, "foo.txt", "a", dgstMap), @@ -653,7 +684,7 @@ func testDigestAndVerify(t *testing.T, controllers ...TestingControllerFactory) srcTarFormat := srcTarFormat for _, minChunkSize := range tt.minChunkSize { minChunkSize := minChunkSize - t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,format=%s,minChunkSize=%d", newCL(), prefix, srcTarFormat, minChunkSize), func(t *testing.T) { + t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,format=%s,minChunkSize=%d", newCL(), prefix, srcTarFormat, minChunkSize), func(t *TestRunner) { // Get original tar file and chunk digests dgstMap := make(map[string]digest.Digest) tarBlob := buildTar(t, tt.tarInit(t, dgstMap), prefix, srcTarFormat) @@ -689,7 +720,7 @@ func testDigestAndVerify(t *testing.T, controllers ...TestingControllerFactory) // checkStargzTOC checks the TOC JSON of the passed stargz has the expected // digest and contains valid chunks. It walks all entries in the stargz and // checks all chunk digests stored to the TOC JSON match the actual contents. -func checkStargzTOC(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { +func checkStargzTOC(t *TestRunner, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { sgz, err := Open( io.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))), WithDecompressors(controller), @@ -800,7 +831,7 @@ func checkStargzTOC(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstM // checkVerifyTOC checks the verification works for the TOC JSON of the passed // stargz. It walks all entries in the stargz and checks the verifications for // all chunks work. -func checkVerifyTOC(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { +func checkVerifyTOC(t *TestRunner, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { sgz, err := Open( io.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))), WithDecompressors(controller), @@ -881,9 +912,9 @@ func checkVerifyTOC(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstM // checkVerifyInvalidTOCEntryFail checks if misconfigured TOC JSON can be // detected during the verification and the verification returns an error. func checkVerifyInvalidTOCEntryFail(filename string) check { - return func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { + return func(t *TestRunner, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { funcs := map[string]rewriteFunc{ - "lost digest in a entry": func(t *testing.T, toc *JTOC, sgz *io.SectionReader) { + "lost digest in a entry": func(t TestingT, toc *JTOC, sgz *io.SectionReader) { var found bool for _, e := range toc.Entries { if cleanEntryName(e.Name) == filename { @@ -901,7 +932,7 @@ func checkVerifyInvalidTOCEntryFail(filename string) check { t.Fatalf("rewrite target not found") } }, - "duplicated entry offset": func(t *testing.T, toc *JTOC, sgz *io.SectionReader) { + "duplicated entry offset": func(t TestingT, toc *JTOC, sgz *io.SectionReader) { var ( sampleEntry *TOCEntry targetEntry *TOCEntry @@ -928,7 +959,7 @@ func checkVerifyInvalidTOCEntryFail(filename string) check { } for name, rFunc := range funcs { - t.Run(name, func(t *testing.T) { + t.Run(name, func(t *TestRunner) { newSgz, newTocDigest := rewriteTOCJSON(t, io.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))), rFunc, controller) buf := new(bytes.Buffer) if _, err := io.Copy(buf, newSgz); err != nil { @@ -957,7 +988,7 @@ func checkVerifyInvalidTOCEntryFail(filename string) check { // checkVerifyInvalidStargzFail checks if the verification detects that the // given stargz file doesn't match to the expected digest and returns error. func checkVerifyInvalidStargzFail(invalid *io.SectionReader) check { - return func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { + return func(t *TestRunner, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { cl := newController() rc, err := Build(invalid, WithChunkSize(chunkSize), WithCompression(cl)) if err != nil { @@ -989,7 +1020,7 @@ func checkVerifyInvalidStargzFail(invalid *io.SectionReader) check { // checkVerifyBrokenContentFail checks if the verifier detects broken contents // that doesn't match to the expected digest and returns error. func checkVerifyBrokenContentFail(filename string) check { - return func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { + return func(t *TestRunner, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) { // Parse stargz file sgz, err := Open( io.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))), @@ -1046,9 +1077,9 @@ func chunkID(name string, offset, size int64) string { return fmt.Sprintf("%s-%d-%d", cleanEntryName(name), offset, size) } -type rewriteFunc func(t *testing.T, toc *JTOC, sgz *io.SectionReader) +type rewriteFunc func(t TestingT, toc *JTOC, sgz *io.SectionReader) -func rewriteTOCJSON(t *testing.T, sgz *io.SectionReader, rewrite rewriteFunc, controller TestingController) (newSgz io.Reader, tocDigest digest.Digest) { +func rewriteTOCJSON(t TestingT, sgz *io.SectionReader, rewrite rewriteFunc, controller TestingController) (newSgz io.Reader, tocDigest digest.Digest) { decodedJTOC, jtocOffset, err := parseStargz(sgz, controller) if err != nil { t.Fatalf("failed to extract TOC JSON: %v", err) @@ -1119,7 +1150,7 @@ func parseStargz(sgz *io.SectionReader, controller TestingController) (decodedJT return decodedJTOC, tocOffset, nil } -func testWriteAndOpen(t *testing.T, controllers ...TestingControllerFactory) { +func testWriteAndOpen(t *TestRunner, controllers ...TestingControllerFactory) { const content = "Some contents" invalidUtf8 := "\xff\xfe\xfd" @@ -1463,7 +1494,7 @@ func testWriteAndOpen(t *testing.T, controllers ...TestingControllerFactory) { for _, srcTarFormat := range []tar.Format{tar.FormatUSTAR, tar.FormatPAX, tar.FormatGNU} { srcTarFormat := srcTarFormat for _, lossless := range []bool{true, false} { - t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,lossless=%v,format=%s", newCL(), prefix, lossless, srcTarFormat), func(t *testing.T) { + t.Run(tt.name+"-"+fmt.Sprintf("compression=%v,prefix=%q,lossless=%v,format=%s", newCL(), prefix, lossless, srcTarFormat), func(t *TestRunner) { var tr io.Reader = buildTar(t, tt.in, prefix, srcTarFormat) origTarDgstr := digest.Canonical.Digester() tr = io.TeeReader(tr, origTarDgstr.Hash()) @@ -1529,6 +1560,9 @@ func testWriteAndOpen(t *testing.T, controllers ...TestingControllerFactory) { if err != nil { t.Fatalf("stargz.Open: %v", err) } + if _, ok := r.Lookup(""); !ok { + t.Fatalf("failed to lookup rootdir: %v", err) + } wantTOCVersion := 1 if tt.wantTOCVersion > 0 { wantTOCVersion = tt.wantTOCVersion @@ -1627,7 +1661,7 @@ func digestFor(content string) string { type numTOCEntries int -func (n numTOCEntries) check(t *testing.T, r *Reader) { +func (n numTOCEntries) check(t TestingT, r *Reader) { if r.toc == nil { t.Fatal("nil TOC") } @@ -1647,15 +1681,15 @@ func (n numTOCEntries) check(t *testing.T, r *Reader) { func checks(s ...stargzCheck) []stargzCheck { return s } type stargzCheck interface { - check(t *testing.T, r *Reader) + check(t TestingT, r *Reader) } -type stargzCheckFn func(*testing.T, *Reader) +type stargzCheckFn func(TestingT, *Reader) -func (f stargzCheckFn) check(t *testing.T, r *Reader) { f(t, r) } +func (f stargzCheckFn) check(t TestingT, r *Reader) { f(t, r) } func maxDepth(max int) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { e, ok := r.Lookup("") if !ok { t.Fatal("root directory not found") @@ -1672,7 +1706,7 @@ func maxDepth(max int) stargzCheck { }) } -func getMaxDepth(t *testing.T, e *TOCEntry, current, limit int) (max int, rErr error) { +func getMaxDepth(t TestingT, e *TOCEntry, current, limit int) (max int, rErr error) { if current > limit { return -1, fmt.Errorf("walkMaxDepth: exceeds limit: current:%d > limit:%d", current, limit) @@ -1694,7 +1728,7 @@ func getMaxDepth(t *testing.T, e *TOCEntry, current, limit int) (max int, rErr e } func hasFileLen(file string, wantLen int) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { for _, ent := range r.toc.Entries { if ent.Name == file { if ent.Type != "reg" { @@ -1710,7 +1744,7 @@ func hasFileLen(file string, wantLen int) stargzCheck { } func hasFileXattrs(file, name, value string) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { for _, ent := range r.toc.Entries { if ent.Name == file { if ent.Type != "reg" { @@ -1737,7 +1771,7 @@ func hasFileXattrs(file, name, value string) stargzCheck { } func hasFileDigest(file string, digest string) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { ent, ok := r.Lookup(file) if !ok { t.Fatalf("didn't find TOCEntry for file %q", file) @@ -1749,7 +1783,7 @@ func hasFileDigest(file string, digest string) stargzCheck { } func hasFileContentsWithPreRead(file string, offset int, want string, extra ...chunkInfo) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { extraMap := make(map[string]chunkInfo) for _, e := range extra { extraMap[e.name] = e @@ -1796,7 +1830,7 @@ func hasFileContentsWithPreRead(file string, offset int, want string, extra ...c } func hasFileContentsRange(file string, offset int, want string) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { f, err := r.OpenFile(file) if err != nil { t.Fatal(err) @@ -1813,7 +1847,7 @@ func hasFileContentsRange(file string, offset int, want string) stargzCheck { } func hasChunkEntries(file string, wantChunks int) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { ent, ok := r.Lookup(file) if !ok { t.Fatalf("no file for %q", file) @@ -1857,7 +1891,7 @@ func hasChunkEntries(file string, wantChunks int) stargzCheck { } func entryHasChildren(dir string, want ...string) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { want := append([]string(nil), want...) var got []string ent, ok := r.Lookup(dir) @@ -1876,7 +1910,7 @@ func entryHasChildren(dir string, want ...string) stargzCheck { } func hasDir(file string) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { for _, ent := range r.toc.Entries { if ent.Name == cleanEntryName(file) { if ent.Type != "dir" { @@ -1890,7 +1924,7 @@ func hasDir(file string) stargzCheck { } func hasDirLinkCount(file string, count int) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { for _, ent := range r.toc.Entries { if ent.Name == cleanEntryName(file) { if ent.Type != "dir" { @@ -1908,7 +1942,7 @@ func hasDirLinkCount(file string, count int) stargzCheck { } func hasMode(file string, mode os.FileMode) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { for _, ent := range r.toc.Entries { if ent.Name == cleanEntryName(file) { if ent.Stat().Mode() != mode { @@ -1923,7 +1957,7 @@ func hasMode(file string, mode os.FileMode) stargzCheck { } func hasSymlink(file, target string) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { for _, ent := range r.toc.Entries { if ent.Name == file { if ent.Type != "symlink" { @@ -1939,7 +1973,7 @@ func hasSymlink(file, target string) stargzCheck { } func lookupMatch(name string, want *TOCEntry) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { e, ok := r.Lookup(name) if !ok { t.Fatalf("failed to Lookup entry %q", name) @@ -1952,7 +1986,7 @@ func lookupMatch(name string, want *TOCEntry) stargzCheck { } func hasEntryOwner(entry string, owner owner) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { ent, ok := r.Lookup(strings.TrimSuffix(entry, "/")) if !ok { t.Errorf("entry %q not found", entry) @@ -1966,7 +2000,7 @@ func hasEntryOwner(entry string, owner owner) stargzCheck { } func mustSameEntry(files ...string) stargzCheck { - return stargzCheckFn(func(t *testing.T, r *Reader) { + return stargzCheckFn(func(t TestingT, r *Reader) { var first *TOCEntry for _, f := range files { if first == nil { @@ -2038,7 +2072,7 @@ func (f tarEntryFunc) appendTar(tw *tar.Writer, prefix string, format tar.Format return f(tw, prefix, format) } -func buildTar(t *testing.T, ents []tarEntry, prefix string, opts ...interface{}) *io.SectionReader { +func buildTar(t TestingT, ents []tarEntry, prefix string, opts ...interface{}) *io.SectionReader { format := tar.FormatUnknown for _, opt := range opts { switch v := opt.(type) { @@ -2247,7 +2281,7 @@ func noPrefetchLandmark() tarEntry { }) } -func regDigest(t *testing.T, name string, contentStr string, digestMap map[string]digest.Digest) tarEntry { +func regDigest(t TestingT, name string, contentStr string, digestMap map[string]digest.Digest) tarEntry { if digestMap == nil { t.Fatalf("digest map mustn't be nil") } @@ -2317,7 +2351,7 @@ func (f fileInfoOnlyMode) ModTime() time.Time { return time.Now() } func (f fileInfoOnlyMode) IsDir() bool { return os.FileMode(f).IsDir() } func (f fileInfoOnlyMode) Sys() interface{} { return nil } -func CheckGzipHasStreams(t *testing.T, b []byte, streams []int64) { +func CheckGzipHasStreams(t TestingT, b []byte, streams []int64) { if len(streams) == 0 { return // nop } @@ -2346,8 +2380,8 @@ func CheckGzipHasStreams(t *testing.T, b []byte, streams []int64) { t.Fatalf("countStreams(gzip), Copy: %v", err) } var extra string - if len(zr.Header.Extra) > 0 { - extra = fmt.Sprintf("; extra=%q", zr.Header.Extra) + if len(zr.Extra) > 0 { + extra = fmt.Sprintf("; extra=%q", zr.Extra) } t.Logf(" [%d] at %d in stargz, uncompressed length %d%s", numStreams, zoff, n, extra) delete(wants, int64(zoff)) @@ -2355,7 +2389,7 @@ func CheckGzipHasStreams(t *testing.T, b []byte, streams []int64) { } } -func GzipDiffIDOf(t *testing.T, b []byte) string { +func GzipDiffIDOf(t TestingT, b []byte) string { h := sha256.New() zr, err := gzip.NewReader(bytes.NewReader(b)) if err != nil { diff --git a/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go b/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go index 6a846ece95..c5e4d787c8 100644 --- a/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go +++ b/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go @@ -11,7 +11,6 @@ import ( "io" "net/http" "sync" - "time" jose "github.com/go-jose/go-jose/v4" ) @@ -57,16 +56,12 @@ func (s *StaticKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, // The returned KeySet is a long lived verifier that caches keys based on any // keys change. Reuse a common remote key set instead of creating new ones as needed. func NewRemoteKeySet(ctx context.Context, jwksURL string) *RemoteKeySet { - return newRemoteKeySet(ctx, jwksURL, time.Now) + return newRemoteKeySet(ctx, jwksURL) } -func newRemoteKeySet(ctx context.Context, jwksURL string, now func() time.Time) *RemoteKeySet { - if now == nil { - now = time.Now - } +func newRemoteKeySet(ctx context.Context, jwksURL string) *RemoteKeySet { return &RemoteKeySet{ jwksURL: jwksURL, - now: now, // For historical reasons, this package uses contexts for configuration, not just // cancellation. In hindsight, this was a bad idea. // @@ -81,7 +76,6 @@ func newRemoteKeySet(ctx context.Context, jwksURL string, now func() time.Time) // a jwks_uri endpoint. type RemoteKeySet struct { jwksURL string - now func() time.Time // Used for configuration. Cancelation is ignored. ctx context.Context diff --git a/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go b/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go index f6a7ea8a58..2659518cc4 100644 --- a/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go +++ b/vendor/github.com/coreos/go-oidc/v3/oidc/oidc.go @@ -162,7 +162,7 @@ var supportedAlgorithms = map[string]bool{ // parsing. // // // Directly fetch the metadata document. -// resp, err := http.Get("https://login.example.com/custom-metadata-path") +// resp, err := http.Get("https://login.example.com/custom-metadata-path") // if err != nil { // // ... // } @@ -267,7 +267,7 @@ func NewProvider(ctx context.Context, issuer string) (*Provider, error) { issuerURL = issuer } if p.Issuer != issuerURL && !skipIssuerValidation { - return nil, fmt.Errorf("oidc: issuer did not match the issuer returned by provider, expected %q got %q", issuer, p.Issuer) + return nil, fmt.Errorf("oidc: issuer URL provided to client (%q) did not match the issuer URL returned by provider (%q)", issuer, p.Issuer) } var algs []string for _, a := range p.Algorithms { diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE new file mode 100644 index 0000000000..fdf6d88225 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE @@ -0,0 +1,17 @@ +ISC License + +Copyright (c) 2013-2017 The btcsuite developers +Copyright (c) 2015-2024 The Decred developers +Copyright (c) 2017 The Lightning Network Developers + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md new file mode 100644 index 0000000000..b84bcdb77d --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md @@ -0,0 +1,72 @@ +secp256k1 +========= + +[![Build Status](https://github.com/decred/dcrd/workflows/Build%20and%20Test/badge.svg)](https://github.com/decred/dcrd/actions) +[![ISC License](https://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) +[![Doc](https://img.shields.io/badge/doc-reference-blue.svg)](https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v4) + +Package secp256k1 implements optimized secp256k1 elliptic curve operations. + +This package provides an optimized pure Go implementation of elliptic curve +cryptography operations over the secp256k1 curve as well as data structures and +functions for working with public and private secp256k1 keys. See +https://www.secg.org/sec2-v2.pdf for details on the standard. + +In addition, sub packages are provided to produce, verify, parse, and serialize +ECDSA signatures and EC-Schnorr-DCRv0 (a custom Schnorr-based signature scheme +specific to Decred) signatures. See the README.md files in the relevant sub +packages for more details about those aspects. + +An overview of the features provided by this package are as follows: + +- Private key generation, serialization, and parsing +- Public key generation, serialization and parsing per ANSI X9.62-1998 + - Parses uncompressed, compressed, and hybrid public keys + - Serializes uncompressed and compressed public keys +- Specialized types for performing optimized and constant time field operations + - `FieldVal` type for working modulo the secp256k1 field prime + - `ModNScalar` type for working modulo the secp256k1 group order +- Elliptic curve operations in Jacobian projective coordinates + - Point addition + - Point doubling + - Scalar multiplication with an arbitrary point + - Scalar multiplication with the base point (group generator) +- Point decompression from a given x coordinate +- Nonce generation via RFC6979 with support for extra data and version + information that can be used to prevent nonce reuse between signing algorithms + +It also provides an implementation of the Go standard library `crypto/elliptic` +`Curve` interface via the `S256` function so that it may be used with other +packages in the standard library such as `crypto/tls`, `crypto/x509`, and +`crypto/ecdsa`. However, in the case of ECDSA, it is highly recommended to use +the `ecdsa` sub package of this package instead since it is optimized +specifically for secp256k1 and is significantly faster as a result. + +Although this package was primarily written for dcrd, it has intentionally been +designed so it can be used as a standalone package for any projects needing to +use optimized secp256k1 elliptic curve cryptography. + +Finally, a comprehensive suite of tests is provided to provide a high level of +quality assurance. + +## secp256k1 use in Decred + +At the time of this writing, the primary public key cryptography in widespread +use on the Decred network used to secure coins is based on elliptic curves +defined by the secp256k1 domain parameters. + +## Installation and Updating + +This package is part of the `github.com/decred/dcrd/dcrec/secp256k1/v4` module. +Use the standard go tooling for working with modules to incorporate it. + +## Examples + +* [Encryption](https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v4#example-package-EncryptDecryptMessage) + Demonstrates encrypting and decrypting a message using a shared key derived + through ECDHE. + +## License + +Package secp256k1 is licensed under the [copyfree](http://copyfree.org) ISC +License. diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go new file mode 100644 index 0000000000..bb0b41fda1 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go @@ -0,0 +1,18 @@ +// Copyright (c) 2015 The btcsuite developers +// Copyright (c) 2015-2022 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// Auto-generated file (see genprecomps.go) +// DO NOT EDIT + +var compressedBytePoints = "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" + +// Set accessor to a real function. +func init() { + compressedBytePointsFn = func() string { + return compressedBytePoints + } +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go new file mode 100644 index 0000000000..6d6d669f19 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go @@ -0,0 +1,1310 @@ +// Copyright (c) 2015-2024 The Decred developers +// Copyright 2013-2014 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + "encoding/hex" + "math/bits" +) + +// References: +// [SECG]: Recommended Elliptic Curve Domain Parameters +// https://www.secg.org/sec2-v2.pdf +// +// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone) +// +// [BRID]: On Binary Representations of Integers with Digits -1, 0, 1 +// (Prodinger, Helmut) +// +// [STWS]: Secure-TWS: Authenticating Node to Multi-user Communication in +// Shared Sensor Networks (Oliveira, Leonardo B. et al) + +// All group operations are performed using Jacobian coordinates. For a given +// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1) +// where x = x1/z1^2 and y = y1/z1^3. + +// hexToFieldVal converts the passed hex string into a FieldVal and will panic +// if there is an error. This is only provided for the hard-coded constants so +// errors in the source code can be detected. It will only (and must only) be +// called with hard-coded values. +func hexToFieldVal(s string) *FieldVal { + b, err := hex.DecodeString(s) + if err != nil { + panic("invalid hex in source file: " + s) + } + var f FieldVal + if overflow := f.SetByteSlice(b); overflow { + panic("hex in source file overflows mod P: " + s) + } + return &f +} + +// hexToModNScalar converts the passed hex string into a ModNScalar and will +// panic if there is an error. This is only provided for the hard-coded +// constants so errors in the source code can be detected. It will only (and +// must only) be called with hard-coded values. +func hexToModNScalar(s string) *ModNScalar { + var isNegative bool + if len(s) > 0 && s[0] == '-' { + isNegative = true + s = s[1:] + } + if len(s)%2 != 0 { + s = "0" + s + } + b, err := hex.DecodeString(s) + if err != nil { + panic("invalid hex in source file: " + s) + } + var scalar ModNScalar + if overflow := scalar.SetByteSlice(b); overflow { + panic("hex in source file overflows mod N scalar: " + s) + } + if isNegative { + scalar.Negate() + } + return &scalar +} + +var ( + // The following constants are used to accelerate scalar point + // multiplication through the use of the endomorphism: + // + // φ(Q) ⟼ λ*Q = (β*Q.x mod p, Q.y) + // + // See the code in the deriveEndomorphismParams function in genprecomps.go + // for details on their derivation. + // + // Additionally, see the scalar multiplication function in this file for + // details on how they are used. + endoNegLambda = hexToModNScalar("-5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72") + endoBeta = hexToFieldVal("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee") + endoNegB1 = hexToModNScalar("e4437ed6010e88286f547fa90abfe4c3") + endoNegB2 = hexToModNScalar("-3086d221a7d46bcde86c90e49284eb15") + endoZ1 = hexToModNScalar("3086d221a7d46bcde86c90e49284eb153daa8a1471e8ca7f") + endoZ2 = hexToModNScalar("e4437ed6010e88286f547fa90abfe4c4221208ac9df506c6") + + // Alternatively, the following parameters are valid as well, however, + // benchmarks show them to be about 2% slower in practice. + // endoNegLambda = hexToModNScalar("-ac9c52b33fa3cf1f5ad9e3fd77ed9ba4a880b9fc8ec739c2e0cfc810b51283ce") + // endoBeta = hexToFieldVal("851695d49a83f8ef919bb86153cbcb16630fb68aed0a766a3ec693d68e6afa40") + // endoNegB1 = hexToModNScalar("3086d221a7d46bcde86c90e49284eb15") + // endoNegB2 = hexToModNScalar("-114ca50f7a8e2f3f657c1108d9d44cfd8") + // endoZ1 = hexToModNScalar("114ca50f7a8e2f3f657c1108d9d44cfd95fbc92c10fddd145") + // endoZ2 = hexToModNScalar("3086d221a7d46bcde86c90e49284eb153daa8a1471e8ca7f") +) + +// JacobianPoint is an element of the group formed by the secp256k1 curve in +// Jacobian projective coordinates and thus represents a point on the curve. +type JacobianPoint struct { + // The X coordinate in Jacobian projective coordinates. The affine point is + // X/z^2. + X FieldVal + + // The Y coordinate in Jacobian projective coordinates. The affine point is + // Y/z^3. + Y FieldVal + + // The Z coordinate in Jacobian projective coordinates. + Z FieldVal +} + +// MakeJacobianPoint returns a Jacobian point with the provided X, Y, and Z +// coordinates. +func MakeJacobianPoint(x, y, z *FieldVal) JacobianPoint { + var p JacobianPoint + p.X.Set(x) + p.Y.Set(y) + p.Z.Set(z) + return p +} + +// Set sets the Jacobian point to the provided point. +func (p *JacobianPoint) Set(other *JacobianPoint) { + p.X.Set(&other.X) + p.Y.Set(&other.Y) + p.Z.Set(&other.Z) +} + +// ToAffine reduces the Z value of the existing point to 1 effectively +// making it an affine coordinate in constant time. The point will be +// normalized. +func (p *JacobianPoint) ToAffine() { + // Inversions are expensive and both point addition and point doubling + // are faster when working with points that have a z value of one. So, + // if the point needs to be converted to affine, go ahead and normalize + // the point itself at the same time as the calculation is the same. + var zInv, tempZ FieldVal + zInv.Set(&p.Z).Inverse() // zInv = Z^-1 + tempZ.SquareVal(&zInv) // tempZ = Z^-2 + p.X.Mul(&tempZ) // X = X/Z^2 (mag: 1) + p.Y.Mul(tempZ.Mul(&zInv)) // Y = Y/Z^3 (mag: 1) + p.Z.SetInt(1) // Z = 1 (mag: 1) + + // Normalize the x and y values. + p.X.Normalize() + p.Y.Normalize() +} + +// EquivalentNonConst returns whether or not two Jacobian points represent the +// same affine point in *non-constant* time. +func (p *JacobianPoint) EquivalentNonConst(other *JacobianPoint) bool { + // Since the point at infinity is the identity element for the group, note + // that P = P + ∞ trivially implies that P - P = ∞. + // + // Use that fact to determine if the points represent the same affine point. + var result JacobianPoint + result.Set(p) + result.Y.Normalize().Negate(1).Normalize() + AddNonConst(&result, other, &result) + return (result.X.IsZero() && result.Y.IsZero()) || result.Z.IsZero() +} + +// addZ1AndZ2EqualsOne adds two Jacobian points that are already known to have +// z values of 1 and stores the result in the provided result param. That is to +// say result = p1 + p2. It performs faster addition than the generic add +// routine since less arithmetic is needed due to the ability to avoid the z +// value multiplications. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func addZ1AndZ2EqualsOne(p1, p2, result *JacobianPoint) { + // To compute the point addition efficiently, this implementation splits + // the equation into intermediate elements which are used to minimize + // the number of field multiplications using the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl + // + // In particular it performs the calculations using the following: + // H = X2-X1, HH = H^2, I = 4*HH, J = H*I, r = 2*(Y2-Y1), V = X1*I + // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = 2*H + // + // This results in a cost of 4 field multiplications, 2 field squarings, + // 6 field additions, and 5 integer multiplications. + x1, y1 := &p1.X, &p1.Y + x2, y2 := &p2.X, &p2.Y + x3, y3, z3 := &result.X, &result.Y, &result.Z + + // When the x coordinates are the same for two points on the curve, the + // y coordinates either must be the same, in which case it is point + // doubling, or they are opposite and the result is the point at + // infinity per the group law for elliptic curve cryptography. + if x1.Equals(x2) { + if y1.Equals(y2) { + // Since x1 == x2 and y1 == y2, point doubling must be + // done, otherwise the addition would end up dividing + // by zero. + DoubleNonConst(p1, result) + return + } + + // Since x1 == x2 and y1 == -y2, the sum is the point at + // infinity per the group law. + x3.SetInt(0) + y3.SetInt(0) + z3.SetInt(0) + return + } + + // Calculate X3, Y3, and Z3 according to the intermediate elements + // breakdown above. + var h, i, j, r, v FieldVal + var negJ, neg2V, negX3 FieldVal + h.Set(x1).Negate(1).Add(x2) // H = X2-X1 (mag: 3) + i.SquareVal(&h).MulInt(4) // I = 4*H^2 (mag: 4) + j.Mul2(&h, &i) // J = H*I (mag: 1) + r.Set(y1).Negate(1).Add(y2).MulInt(2) // r = 2*(Y2-Y1) (mag: 6) + v.Mul2(x1, &i) // V = X1*I (mag: 1) + negJ.Set(&j).Negate(1) // negJ = -J (mag: 2) + neg2V.Set(&v).MulInt(2).Negate(2) // neg2V = -(2*V) (mag: 3) + x3.Set(&r).Square().Add(&negJ).Add(&neg2V) // X3 = r^2-J-2*V (mag: 6) + negX3.Set(x3).Negate(6) // negX3 = -X3 (mag: 7) + j.Mul(y1).MulInt(2).Negate(2) // J = -(2*Y1*J) (mag: 3) + y3.Set(&v).Add(&negX3).Mul(&r).Add(&j) // Y3 = r*(V-X3)-2*Y1*J (mag: 4) + z3.Set(&h).MulInt(2) // Z3 = 2*H (mag: 6) + + // Normalize the resulting field values as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// addZ1EqualsZ2 adds two Jacobian points that are already known to have the +// same z value and stores the result in the provided result param. That is to +// say result = p1 + p2. It performs faster addition than the generic add +// routine since less arithmetic is needed due to the known equivalence. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func addZ1EqualsZ2(p1, p2, result *JacobianPoint) { + // To compute the point addition efficiently, this implementation splits + // the equation into intermediate elements which are used to minimize + // the number of field multiplications using a slightly modified version + // of the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-zadd-2007-m + // + // In particular it performs the calculations using the following: + // A = X2-X1, B = A^2, C=Y2-Y1, D = C^2, E = X1*B, F = X2*B + // X3 = D-E-F, Y3 = C*(E-X3)-Y1*(F-E), Z3 = Z1*A + // + // This results in a cost of 5 field multiplications, 2 field squarings, + // 9 field additions, and 0 integer multiplications. + x1, y1, z1 := &p1.X, &p1.Y, &p1.Z + x2, y2 := &p2.X, &p2.Y + x3, y3, z3 := &result.X, &result.Y, &result.Z + + // When the x coordinates are the same for two points on the curve, the + // y coordinates either must be the same, in which case it is point + // doubling, or they are opposite and the result is the point at + // infinity per the group law for elliptic curve cryptography. + if x1.Equals(x2) { + if y1.Equals(y2) { + // Since x1 == x2 and y1 == y2, point doubling must be + // done, otherwise the addition would end up dividing + // by zero. + DoubleNonConst(p1, result) + return + } + + // Since x1 == x2 and y1 == -y2, the sum is the point at + // infinity per the group law. + x3.SetInt(0) + y3.SetInt(0) + z3.SetInt(0) + return + } + + // Calculate X3, Y3, and Z3 according to the intermediate elements + // breakdown above. + var a, b, c, d, e, f FieldVal + var negX1, negY1, negE, negX3 FieldVal + negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2) + negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2) + a.Set(&negX1).Add(x2) // A = X2-X1 (mag: 3) + b.SquareVal(&a) // B = A^2 (mag: 1) + c.Set(&negY1).Add(y2) // C = Y2-Y1 (mag: 3) + d.SquareVal(&c) // D = C^2 (mag: 1) + e.Mul2(x1, &b) // E = X1*B (mag: 1) + negE.Set(&e).Negate(1) // negE = -E (mag: 2) + f.Mul2(x2, &b) // F = X2*B (mag: 1) + x3.Add2(&e, &f).Negate(2).Add(&d) // X3 = D-E-F (mag: 4) + negX3.Set(x3).Negate(4) // negX3 = -X3 (mag: 5) + y3.Set(y1).Mul(f.Add(&negE)).Negate(1) // Y3 = -(Y1*(F-E)) (mag: 2) + y3.Add(e.Add(&negX3).Mul(&c)) // Y3 = C*(E-X3)+Y3 (mag: 3) + z3.Mul2(z1, &a) // Z3 = Z1*A (mag: 1) + + // Normalize the resulting field values as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// addZ2EqualsOne adds two Jacobian points when the second point is already +// known to have a z value of 1 (and the z value for the first point is not 1) +// and stores the result in the provided result param. That is to say result = +// p1 + p2. It performs faster addition than the generic add routine since +// less arithmetic is needed due to the ability to avoid multiplications by the +// second point's z value. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func addZ2EqualsOne(p1, p2, result *JacobianPoint) { + // To compute the point addition efficiently, this implementation splits + // the equation into intermediate elements which are used to minimize + // the number of field multiplications using the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl + // + // In particular it performs the calculations using the following: + // Z1Z1 = Z1^2, U2 = X2*Z1Z1, S2 = Y2*Z1*Z1Z1, H = U2-X1, HH = H^2, + // I = 4*HH, J = H*I, r = 2*(S2-Y1), V = X1*I + // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = (Z1+H)^2-Z1Z1-HH + // + // This results in a cost of 7 field multiplications, 4 field squarings, + // 9 field additions, and 4 integer multiplications. + x1, y1, z1 := &p1.X, &p1.Y, &p1.Z + x2, y2 := &p2.X, &p2.Y + x3, y3, z3 := &result.X, &result.Y, &result.Z + + // When the x coordinates are the same for two points on the curve, the + // y coordinates either must be the same, in which case it is point + // doubling, or they are opposite and the result is the point at + // infinity per the group law for elliptic curve cryptography. Since + // any number of Jacobian coordinates can represent the same affine + // point, the x and y values need to be converted to like terms. Due to + // the assumption made for this function that the second point has a z + // value of 1 (z2=1), the first point is already "converted". + var z1z1, u2, s2 FieldVal + z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1) + u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1) + s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1) + if x1.Equals(&u2) { + if y1.Equals(&s2) { + // Since x1 == x2 and y1 == y2, point doubling must be + // done, otherwise the addition would end up dividing + // by zero. + DoubleNonConst(p1, result) + return + } + + // Since x1 == x2 and y1 == -y2, the sum is the point at + // infinity per the group law. + x3.SetInt(0) + y3.SetInt(0) + z3.SetInt(0) + return + } + + // Calculate X3, Y3, and Z3 according to the intermediate elements + // breakdown above. + var h, hh, i, j, r, rr, v FieldVal + var negX1, negY1, negX3 FieldVal + negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2) + h.Add2(&u2, &negX1) // H = U2-X1 (mag: 3) + hh.SquareVal(&h) // HH = H^2 (mag: 1) + i.Set(&hh).MulInt(4) // I = 4 * HH (mag: 4) + j.Mul2(&h, &i) // J = H*I (mag: 1) + negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2) + r.Set(&s2).Add(&negY1).MulInt(2) // r = 2*(S2-Y1) (mag: 6) + rr.SquareVal(&r) // rr = r^2 (mag: 1) + v.Mul2(x1, &i) // V = X1*I (mag: 1) + x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4) + x3.Add(&rr) // X3 = r^2+X3 (mag: 5) + negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6) + y3.Set(y1).Mul(&j).MulInt(2).Negate(2) // Y3 = -(2*Y1*J) (mag: 3) + y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4) + z3.Add2(z1, &h).Square() // Z3 = (Z1+H)^2 (mag: 1) + z3.Add(z1z1.Add(&hh).Negate(2)) // Z3 = Z3-(Z1Z1+HH) (mag: 4) + + // Normalize the resulting field values as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// addGeneric adds two Jacobian points without any assumptions about the z +// values of the two points and stores the result in the provided result param. +// That is to say result = p1 + p2. It is the slowest of the add routines due +// to requiring the most arithmetic. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func addGeneric(p1, p2, result *JacobianPoint) { + // To compute the point addition efficiently, this implementation splits + // the equation into intermediate elements which are used to minimize + // the number of field multiplications using the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl + // + // In particular it performs the calculations using the following: + // Z1Z1 = Z1^2, Z2Z2 = Z2^2, U1 = X1*Z2Z2, U2 = X2*Z1Z1, S1 = Y1*Z2*Z2Z2 + // S2 = Y2*Z1*Z1Z1, H = U2-U1, I = (2*H)^2, J = H*I, r = 2*(S2-S1) + // V = U1*I + // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*S1*J, Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H + // + // This results in a cost of 11 field multiplications, 5 field squarings, + // 9 field additions, and 4 integer multiplications. + x1, y1, z1 := &p1.X, &p1.Y, &p1.Z + x2, y2, z2 := &p2.X, &p2.Y, &p2.Z + x3, y3, z3 := &result.X, &result.Y, &result.Z + + // When the x coordinates are the same for two points on the curve, the + // y coordinates either must be the same, in which case it is point + // doubling, or they are opposite and the result is the point at + // infinity. Since any number of Jacobian coordinates can represent the + // same affine point, the x and y values need to be converted to like + // terms. + var z1z1, z2z2, u1, u2, s1, s2 FieldVal + z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1) + z2z2.SquareVal(z2) // Z2Z2 = Z2^2 (mag: 1) + u1.Set(x1).Mul(&z2z2).Normalize() // U1 = X1*Z2Z2 (mag: 1) + u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1) + s1.Set(y1).Mul(&z2z2).Mul(z2).Normalize() // S1 = Y1*Z2*Z2Z2 (mag: 1) + s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1) + if u1.Equals(&u2) { + if s1.Equals(&s2) { + // Since x1 == x2 and y1 == y2, point doubling must be + // done, otherwise the addition would end up dividing + // by zero. + DoubleNonConst(p1, result) + return + } + + // Since x1 == x2 and y1 == -y2, the sum is the point at + // infinity per the group law. + x3.SetInt(0) + y3.SetInt(0) + z3.SetInt(0) + return + } + + // Calculate X3, Y3, and Z3 according to the intermediate elements + // breakdown above. + var h, i, j, r, rr, v FieldVal + var negU1, negS1, negX3 FieldVal + negU1.Set(&u1).Negate(1) // negU1 = -U1 (mag: 2) + h.Add2(&u2, &negU1) // H = U2-U1 (mag: 3) + i.Set(&h).MulInt(2).Square() // I = (2*H)^2 (mag: 1) + j.Mul2(&h, &i) // J = H*I (mag: 1) + negS1.Set(&s1).Negate(1) // negS1 = -S1 (mag: 2) + r.Set(&s2).Add(&negS1).MulInt(2) // r = 2*(S2-S1) (mag: 6) + rr.SquareVal(&r) // rr = r^2 (mag: 1) + v.Mul2(&u1, &i) // V = U1*I (mag: 1) + x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4) + x3.Add(&rr) // X3 = r^2+X3 (mag: 5) + negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6) + y3.Mul2(&s1, &j).MulInt(2).Negate(2) // Y3 = -(2*S1*J) (mag: 3) + y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4) + z3.Add2(z1, z2).Square() // Z3 = (Z1+Z2)^2 (mag: 1) + z3.Add(z1z1.Add(&z2z2).Negate(2)) // Z3 = Z3-(Z1Z1+Z2Z2) (mag: 4) + z3.Mul(&h) // Z3 = Z3*H (mag: 1) + + // Normalize the resulting field values as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// AddNonConst adds the passed Jacobian points together and stores the result in +// the provided result param in *non-constant* time. +// +// NOTE: The points must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func AddNonConst(p1, p2, result *JacobianPoint) { + // The point at infinity is the identity according to the group law for + // elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P. + if (p1.X.IsZero() && p1.Y.IsZero()) || p1.Z.IsZero() { + result.Set(p2) + return + } + if (p2.X.IsZero() && p2.Y.IsZero()) || p2.Z.IsZero() { + result.Set(p1) + return + } + + // Faster point addition can be achieved when certain assumptions are + // met. For example, when both points have the same z value, arithmetic + // on the z values can be avoided. This section thus checks for these + // conditions and calls an appropriate add function which is accelerated + // by using those assumptions. + isZ1One := p1.Z.IsOne() + isZ2One := p2.Z.IsOne() + switch { + case isZ1One && isZ2One: + addZ1AndZ2EqualsOne(p1, p2, result) + return + case p1.Z.Equals(&p2.Z): + addZ1EqualsZ2(p1, p2, result) + return + case isZ2One: + addZ2EqualsOne(p1, p2, result) + return + } + + // None of the above assumptions are true, so fall back to generic + // point addition. + addGeneric(p1, p2, result) +} + +// doubleZ1EqualsOne performs point doubling on the passed Jacobian point when +// the point is already known to have a z value of 1 and stores the result in +// the provided result param. That is to say result = 2*p. It performs faster +// point doubling than the generic routine since less arithmetic is needed due +// to the ability to avoid multiplication by the z value. +// +// NOTE: The resulting point will be normalized. +func doubleZ1EqualsOne(p, result *JacobianPoint) { + // This function uses the assumptions that z1 is 1, thus the point + // doubling formulas reduce to: + // + // X3 = (3*X1^2)^2 - 8*X1*Y1^2 + // Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4 + // Z3 = 2*Y1 + // + // To compute the above efficiently, this implementation splits the + // equation into intermediate elements which are used to minimize the + // number of field multiplications in favor of field squarings which + // are roughly 35% faster than field multiplications with the current + // implementation at the time this was written. + // + // This uses a slightly modified version of the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl + // + // In particular it performs the calculations using the following: + // A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C) + // E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C + // Z3 = 2*Y1 + // + // This results in a cost of 1 field multiplication, 5 field squarings, + // 6 field additions, and 5 integer multiplications. + x1, y1 := &p.X, &p.Y + x3, y3, z3 := &result.X, &result.Y, &result.Z + var a, b, c, d, e, f FieldVal + z3.Set(y1).MulInt(2) // Z3 = 2*Y1 (mag: 2) + a.SquareVal(x1) // A = X1^2 (mag: 1) + b.SquareVal(y1) // B = Y1^2 (mag: 1) + c.SquareVal(&b) // C = B^2 (mag: 1) + b.Add(x1).Square() // B = (X1+B)^2 (mag: 1) + d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3) + d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8) + e.Set(&a).MulInt(3) // E = 3*A (mag: 3) + f.SquareVal(&e) // F = E^2 (mag: 1) + x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17) + x3.Add(&f) // X3 = F+X3 (mag: 18) + f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1) + y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9) + y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10) + + // Normalize the resulting field values as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// doubleGeneric performs point doubling on the passed Jacobian point without +// any assumptions about the z value and stores the result in the provided +// result param. That is to say result = 2*p. It is the slowest of the point +// doubling routines due to requiring the most arithmetic. +// +// NOTE: The resulting point will be normalized. +func doubleGeneric(p, result *JacobianPoint) { + // Point doubling formula for Jacobian coordinates for the secp256k1 + // curve: + // + // X3 = (3*X1^2)^2 - 8*X1*Y1^2 + // Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4 + // Z3 = 2*Y1*Z1 + // + // To compute the above efficiently, this implementation splits the + // equation into intermediate elements which are used to minimize the + // number of field multiplications in favor of field squarings which + // are roughly 35% faster than field multiplications with the current + // implementation at the time this was written. + // + // This uses a slightly modified version of the method shown at: + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + // + // In particular it performs the calculations using the following: + // A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C) + // E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C + // Z3 = 2*Y1*Z1 + // + // This results in a cost of 1 field multiplication, 5 field squarings, + // 6 field additions, and 5 integer multiplications. + x1, y1, z1 := &p.X, &p.Y, &p.Z + x3, y3, z3 := &result.X, &result.Y, &result.Z + var a, b, c, d, e, f FieldVal + z3.Mul2(y1, z1).MulInt(2) // Z3 = 2*Y1*Z1 (mag: 2) + a.SquareVal(x1) // A = X1^2 (mag: 1) + b.SquareVal(y1) // B = Y1^2 (mag: 1) + c.SquareVal(&b) // C = B^2 (mag: 1) + b.Add(x1).Square() // B = (X1+B)^2 (mag: 1) + d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3) + d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8) + e.Set(&a).MulInt(3) // E = 3*A (mag: 3) + f.SquareVal(&e) // F = E^2 (mag: 1) + x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17) + x3.Add(&f) // X3 = F+X3 (mag: 18) + f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1) + y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9) + y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10) + + // Normalize the resulting field values as needed. + x3.Normalize() + y3.Normalize() + z3.Normalize() +} + +// DoubleNonConst doubles the passed Jacobian point and stores the result in the +// provided result parameter in *non-constant* time. +// +// NOTE: The point must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func DoubleNonConst(p, result *JacobianPoint) { + // Doubling the point at infinity is still infinity. + if p.Y.IsZero() || p.Z.IsZero() { + result.X.SetInt(0) + result.Y.SetInt(0) + result.Z.SetInt(0) + return + } + + // Slightly faster point doubling can be achieved when the z value is 1 + // by avoiding the multiplication on the z value. This section calls + // a point doubling function which is accelerated by using that + // assumption when possible. + if p.Z.IsOne() { + doubleZ1EqualsOne(p, result) + return + } + + // Fall back to generic point doubling which works with arbitrary z + // values. + doubleGeneric(p, result) +} + +// mulAdd64 multiplies the two passed base 2^64 digits together, adds the given +// value to the result, and returns the 128-bit result via a (hi, lo) tuple +// where the upper half of the bits are returned in hi and the lower half in lo. +func mulAdd64(digit1, digit2, m uint64) (hi, lo uint64) { + // Note the carry on the final add is safe to discard because the maximum + // possible value is: + // (2^64 - 1)(2^64 - 1) + (2^64 - 1) = 2^128 - 2^64 + // and: + // 2^128 - 2^64 < 2^128. + var c uint64 + hi, lo = bits.Mul64(digit1, digit2) + lo, c = bits.Add64(lo, m, 0) + hi, _ = bits.Add64(hi, 0, c) + return hi, lo +} + +// mulAdd64Carry multiplies the two passed base 2^64 digits together, adds both +// the given value and carry to the result, and returns the 128-bit result via a +// (hi, lo) tuple where the upper half of the bits are returned in hi and the +// lower half in lo. +func mulAdd64Carry(digit1, digit2, m, c uint64) (hi, lo uint64) { + // Note the carry on the high order add is safe to discard because the + // maximum possible value is: + // (2^64 - 1)(2^64 - 1) + 2*(2^64 - 1) = 2^128 - 1 + // and: + // 2^128 - 1 < 2^128. + var c2 uint64 + hi, lo = mulAdd64(digit1, digit2, m) + lo, c2 = bits.Add64(lo, c, 0) + hi, _ = bits.Add64(hi, 0, c2) + return hi, lo +} + +// mul512Rsh320Round computes the full 512-bit product of the two given scalars, +// right shifts the result by 320 bits, rounds to the nearest integer, and +// returns the result in constant time. +// +// Note that despite the inputs and output being mod n scalars, the 512-bit +// product is NOT reduced mod N prior to the right shift. This is intentional +// because it is used for replacing division with multiplication and thus the +// intermediate results must be done via a field extension to a larger field. +func mul512Rsh320Round(n1, n2 *ModNScalar) ModNScalar { + // Convert n1 and n2 to base 2^64 digits. + n1Digit0 := uint64(n1.n[0]) | uint64(n1.n[1])<<32 + n1Digit1 := uint64(n1.n[2]) | uint64(n1.n[3])<<32 + n1Digit2 := uint64(n1.n[4]) | uint64(n1.n[5])<<32 + n1Digit3 := uint64(n1.n[6]) | uint64(n1.n[7])<<32 + n2Digit0 := uint64(n2.n[0]) | uint64(n2.n[1])<<32 + n2Digit1 := uint64(n2.n[2]) | uint64(n2.n[3])<<32 + n2Digit2 := uint64(n2.n[4]) | uint64(n2.n[5])<<32 + n2Digit3 := uint64(n2.n[6]) | uint64(n2.n[7])<<32 + + // Compute the full 512-bit product n1*n2. + var r0, r1, r2, r3, r4, r5, r6, r7, c uint64 + + // Terms resulting from the product of the first digit of the second number + // by all digits of the first number. + // + // Note that r0 is ignored because it is not needed to compute the higher + // terms and it is shifted out below anyway. + c, _ = bits.Mul64(n2Digit0, n1Digit0) + c, r1 = mulAdd64(n2Digit0, n1Digit1, c) + c, r2 = mulAdd64(n2Digit0, n1Digit2, c) + r4, r3 = mulAdd64(n2Digit0, n1Digit3, c) + + // Terms resulting from the product of the second digit of the second number + // by all digits of the first number. + // + // Note that r1 is ignored because it is no longer needed to compute the + // higher terms and it is shifted out below anyway. + c, _ = mulAdd64(n2Digit1, n1Digit0, r1) + c, r2 = mulAdd64Carry(n2Digit1, n1Digit1, r2, c) + c, r3 = mulAdd64Carry(n2Digit1, n1Digit2, r3, c) + r5, r4 = mulAdd64Carry(n2Digit1, n1Digit3, r4, c) + + // Terms resulting from the product of the third digit of the second number + // by all digits of the first number. + // + // Note that r2 is ignored because it is no longer needed to compute the + // higher terms and it is shifted out below anyway. + c, _ = mulAdd64(n2Digit2, n1Digit0, r2) + c, r3 = mulAdd64Carry(n2Digit2, n1Digit1, r3, c) + c, r4 = mulAdd64Carry(n2Digit2, n1Digit2, r4, c) + r6, r5 = mulAdd64Carry(n2Digit2, n1Digit3, r5, c) + + // Terms resulting from the product of the fourth digit of the second number + // by all digits of the first number. + // + // Note that r3 is ignored because it is no longer needed to compute the + // higher terms and it is shifted out below anyway. + c, _ = mulAdd64(n2Digit3, n1Digit0, r3) + c, r4 = mulAdd64Carry(n2Digit3, n1Digit1, r4, c) + c, r5 = mulAdd64Carry(n2Digit3, n1Digit2, r5, c) + r7, r6 = mulAdd64Carry(n2Digit3, n1Digit3, r6, c) + + // At this point the upper 256 bits of the full 512-bit product n1*n2 are in + // r4..r7 (recall the low order results were discarded as noted above). + // + // Right shift the result 320 bits. Note that the MSB of r4 determines + // whether or not to round because it is the final bit that is shifted out. + // + // Also, notice that r3..r7 would also ordinarily be set to 0 as well for + // the full shift, but that is skipped since they are no longer used as + // their values are known to be zero. + roundBit := r4 >> 63 + r2, r1, r0 = r7, r6, r5 + + // Conditionally add 1 depending on the round bit in constant time. + r0, c = bits.Add64(r0, roundBit, 0) + r1, c = bits.Add64(r1, 0, c) + r2, r3 = bits.Add64(r2, 0, c) + + // Finally, convert the result to a mod n scalar. + // + // No modular reduction is needed because the result is guaranteed to be + // less than the group order given the group order is > 2^255 and the + // maximum possible value of the result is 2^192. + var result ModNScalar + result.n[0] = uint32(r0) + result.n[1] = uint32(r0 >> 32) + result.n[2] = uint32(r1) + result.n[3] = uint32(r1 >> 32) + result.n[4] = uint32(r2) + result.n[5] = uint32(r2 >> 32) + result.n[6] = uint32(r3) + result.n[7] = uint32(r3 >> 32) + return result +} + +// splitK returns two scalars (k1 and k2) that are a balanced length-two +// representation of the provided scalar such that k ≡ k1 + k2*λ (mod N), where +// N is the secp256k1 group order. +func splitK(k *ModNScalar) (ModNScalar, ModNScalar) { + // The ultimate goal is to decompose k into two scalars that are around + // half the bit length of k such that the following equation is satisfied: + // + // k1 + k2*λ ≡ k (mod n) + // + // The strategy used here is based on algorithm 3.74 from [GECC] with a few + // modifications to make use of the more efficient mod n scalar type, avoid + // some costly long divisions, and minimize the number of calculations. + // + // Start by defining a function that takes a vector v = ∈ ℤ⨯ℤ: + // + // f(v) = a + bλ (mod n) + // + // Then, find two vectors, v1 = , and v2 = in ℤ⨯ℤ such that: + // 1) v1 and v2 are linearly independent + // 2) f(v1) = f(v2) = 0 + // 3) v1 and v2 have small Euclidean norm + // + // The vectors that satisfy these properties are found via the Euclidean + // algorithm and are precomputed since both n and λ are fixed values for the + // secp256k1 curve. See genprecomps.go for derivation details. + // + // Next, consider k as a vector in ℚ⨯ℚ and by linear algebra write: + // + // = g1*v1 + g2*v2, where g1, g2 ∈ ℚ + // + // Note that, per above, the components of vector v1 are a1 and b1 while the + // components of vector v2 are a2 and b2. Given the vectors v1 and v2 were + // generated such that a1*b2 - a2*b1 = n, solving the equation for g1 and g2 + // yields: + // + // g1 = b2*k / n + // g2 = -b1*k / n + // + // Observe: + // = g1*v1 + g2*v2 + // = (b2*k/n)* + (-b1*k/n)* | substitute + // = + <-a2*b1*k/n, -b2*b1*k/n> | scalar mul + // = | vector add + // = <[a1*b2*k - a2*b1*k]/n, 0> | simplify + // = | factor out k + // = | substitute + // = | simplify + // + // Now, consider an integer-valued vector v: + // + // v = c1*v1 + c2*v2, where c1, c2 ∈ ℤ (mod n) + // + // Since vectors v1 and v2 are linearly independent and were generated such + // that f(v1) = f(v2) = 0, all possible scalars c1 and c2 also produce a + // vector v such that f(v) = 0. + // + // In other words, c1 and c2 can be any integers and the resulting + // decomposition will still satisfy the required equation. However, since + // the goal is to produce a balanced decomposition that provides a + // performance advantage by minimizing max(k1, k2), c1 and c2 need to be + // integers close to g1 and g2, respectively, so the resulting vector v is + // an integer-valued vector that is close to . + // + // Finally, consider the vector u: + // + // u = - v + // + // It follows that f(u) = k and thus the two components of vector u satisfy + // the required equation: + // + // k1 + k2*λ ≡ k (mod n) + // + // Choosing c1 and c2: + // ------------------- + // + // As mentioned above, c1 and c2 need to be integers close to g1 and g2, + // respectively. The algorithm in [GECC] chooses the following values: + // + // c1 = round(g1) = round(b2*k / n) + // c2 = round(g2) = round(-b1*k / n) + // + // However, as section 3.4.2 of [STWS] notes, the aforementioned approach + // requires costly long divisions that can be avoided by precomputing + // rounded estimates as follows: + // + // t = bitlen(n) + 1 + // z1 = round(2^t * b2 / n) + // z2 = round(2^t * -b1 / n) + // + // Then, use those precomputed estimates to perform a multiplication by k + // along with a floored division by 2^t, which is a simple right shift by t: + // + // c1 = floor(k * z1 / 2^t) = (k * z1) >> t + // c2 = floor(k * z2 / 2^t) = (k * z2) >> t + // + // Finally, round up if last bit discarded in the right shift by t is set by + // adding 1. + // + // As a further optimization, rather than setting t = bitlen(n) + 1 = 257 as + // stated by [STWS], this implementation uses a higher precision estimate of + // t = bitlen(n) + 64 = 320 because it allows simplification of the shifts + // in the internal calculations that are done via uint64s and also allows + // the use of floor in the precomputations. + // + // Thus, the calculations this implementation uses are: + // + // z1 = floor(b2<<320 / n) | precomputed + // z2 = floor((-b1)<<320) / n) | precomputed + // c1 = ((k * z1) >> 320) + (((k * z1) >> 319) & 1) + // c2 = ((k * z2) >> 320) + (((k * z2) >> 319) & 1) + // + // Putting it all together: + // ------------------------ + // + // Calculate the following vectors using the values discussed above: + // + // v = c1*v1 + c2*v2 + // u = - v + // + // The two components of the resulting vector v are: + // va = c1*a1 + c2*a2 + // vb = c1*b1 + c2*b2 + // + // Thus, the two components of the resulting vector u are: + // k1 = k - va + // k2 = 0 - vb = -vb + // + // As some final optimizations: + // + // 1) Note that k1 + k2*λ ≡ k (mod n) means that k1 ≡ k - k2*λ (mod n). + // Therefore, the computation of va can be avoided to save two + // field multiplications and a field addition. + // + // 2) Since k1 ≡ k - k2*λ ≡ k + k2*(-λ), an additional field negation is + // saved by storing and using the negative version of λ. + // + // 3) Since k2 ≡ -vb ≡ -(c1*b1 + c2*b2) ≡ c1*(-b1) + c2*(-b2), one more + // field negation is saved by storing and using the negative versions of + // b1 and b2. + // + // k2 = c1*(-b1) + c2*(-b2) + // k1 = k + k2*(-λ) + var k1, k2 ModNScalar + c1 := mul512Rsh320Round(k, endoZ1) + c2 := mul512Rsh320Round(k, endoZ2) + k2.Add2(c1.Mul(endoNegB1), c2.Mul(endoNegB2)) + k1.Mul2(&k2, endoNegLambda).Add(k) + return k1, k2 +} + +// nafScalar represents a positive integer up to a maximum value of 2^256 - 1 +// encoded in non-adjacent form. +// +// NAF is a signed-digit representation where each digit can be +1, 0, or -1. +// +// In order to efficiently encode that information, this type uses two arrays, a +// "positive" array where set bits represent the +1 signed digits and a +// "negative" array where set bits represent the -1 signed digits. 0 is +// represented by neither array having a bit set in that position. +// +// The Pos and Neg methods return the aforementioned positive and negative +// arrays, respectively. +type nafScalar struct { + // pos houses the positive portion of the representation. An additional + // byte is required for the positive portion because the NAF encoding can be + // up to 1 bit longer than the normal binary encoding of the value. + // + // neg houses the negative portion of the representation. Even though the + // additional byte is not required for the negative portion, since it can + // never exceed the length of the normal binary encoding of the value, + // keeping the same length for positive and negative portions simplifies + // working with the representation and allows extra conditional branches to + // be avoided. + // + // start and end specify the starting and ending index to use within the pos + // and neg arrays, respectively. This allows fixed size arrays to be used + // versus needing to dynamically allocate space on the heap. + // + // NOTE: The fields are defined in the order that they are to minimize the + // padding on 32-bit and 64-bit platforms. + pos [33]byte + start, end uint8 + neg [33]byte +} + +// Pos returns the bytes of the encoded value with bits set in the positions +// that represent a signed digit of +1. +func (s *nafScalar) Pos() []byte { + return s.pos[s.start:s.end] +} + +// Neg returns the bytes of the encoded value with bits set in the positions +// that represent a signed digit of -1. +func (s *nafScalar) Neg() []byte { + return s.neg[s.start:s.end] +} + +// naf takes a positive integer up to a maximum value of 2^256 - 1 and returns +// its non-adjacent form (NAF), which is a unique signed-digit representation +// such that no two consecutive digits are nonzero. See the documentation for +// the returned type for details on how the representation is encoded +// efficiently and how to interpret it +// +// NAF is useful in that it has the fewest nonzero digits of any signed digit +// representation, only 1/3rd of its digits are nonzero on average, and at least +// half of the digits will be 0. +// +// The aforementioned properties are particularly beneficial for optimizing +// elliptic curve point multiplication because they effectively minimize the +// number of required point additions in exchange for needing to perform a mix +// of fewer point additions and subtractions and possibly one additional point +// doubling. This is an excellent tradeoff because subtraction of points has +// the same computational complexity as addition of points and point doubling is +// faster than both. +func naf(k []byte) nafScalar { + // Strip leading zero bytes. + for len(k) > 0 && k[0] == 0x00 { + k = k[1:] + } + + // The non-adjacent form (NAF) of a positive integer k is an expression + // k = ∑_(i=0, l-1) k_i * 2^i where k_i ∈ {0,±1}, k_(l-1) != 0, and no two + // consecutive digits k_i are nonzero. + // + // The traditional method of computing the NAF of a positive integer is + // given by algorithm 3.30 in [GECC]. It consists of repeatedly dividing k + // by 2 and choosing the remainder so that the quotient (k−r)/2 is even + // which ensures the next NAF digit is 0. This requires log_2(k) steps. + // + // However, in [BRID], Prodinger notes that a closed form expression for the + // NAF representation is the bitwise difference 3k/2 - k/2. This is more + // efficient as it can be computed in O(1) versus the O(log(n)) of the + // traditional approach. + // + // The following code makes use of that formula to compute the NAF more + // efficiently. + // + // To understand the logic here, observe that the only way the NAF has a + // nonzero digit at a given bit is when either 3k/2 or k/2 has a bit set in + // that position, but not both. In other words, the result of a bitwise + // xor. This can be seen simply by considering that when the bits are the + // same, the subtraction is either 0-0 or 1-1, both of which are 0. + // + // Further, observe that the "+1" digits in the result are contributed by + // 3k/2 while the "-1" digits are from k/2. So, they can be determined by + // taking the bitwise and of each respective value with the result of the + // xor which identifies which bits are nonzero. + // + // Using that information, this loops backwards from the least significant + // byte to the most significant byte while performing the aforementioned + // calculations by propagating the potential carry and high order bit from + // the next word during the right shift. + kLen := len(k) + var result nafScalar + var carry uint8 + for byteNum := kLen - 1; byteNum >= 0; byteNum-- { + // Calculate k/2. Notice the carry from the previous word is added and + // the low order bit from the next word is shifted in accordingly. + kc := uint16(k[byteNum]) + uint16(carry) + var nextWord uint8 + if byteNum > 0 { + nextWord = k[byteNum-1] + } + halfK := kc>>1 | uint16(nextWord<<7) + + // Calculate 3k/2 and determine the non-zero digits in the result. + threeHalfK := kc + halfK + nonZeroResultDigits := threeHalfK ^ halfK + + // Determine the signed digits {0, ±1}. + result.pos[byteNum+1] = uint8(threeHalfK & nonZeroResultDigits) + result.neg[byteNum+1] = uint8(halfK & nonZeroResultDigits) + + // Propagate the potential carry from the 3k/2 calculation. + carry = uint8(threeHalfK >> 8) + } + result.pos[0] = carry + + // Set the starting and ending positions within the fixed size arrays to + // identify the bytes that are actually used. This is important since the + // encoding is big endian and thus trailing zero bytes changes its value. + result.start = 1 - carry + result.end = uint8(kLen + 1) + return result +} + +// ScalarMultNonConst multiplies k*P where k is a scalar modulo the curve order +// and P is a point in Jacobian projective coordinates and stores the result in +// the provided Jacobian point. +// +// NOTE: The point must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint) { + // ------------------------------------------------------------------------- + // This makes use of the following efficiently-computable endomorphism to + // accelerate the computation: + // + // φ(P) ⟼ λ*P = (β*P.x mod p, P.y) + // + // In other words, there is a special scalar λ that every point on the + // elliptic curve can be multiplied by that will result in the same point as + // performing a single field multiplication of the point's X coordinate by + // the special value β. + // + // This is useful because scalar point multiplication is significantly more + // expensive than a single field multiplication given the former involves a + // series of point doublings and additions which themselves consist of a + // combination of several field multiplications, squarings, and additions. + // + // So, the idea behind making use of the endomorphism is thus to decompose + // the scalar into two scalars that are each about half the bit length of + // the original scalar such that: + // + // k ≡ k1 + k2*λ (mod n) + // + // This in turn allows the scalar point multiplication to be performed as a + // sum of two smaller half-length multiplications as follows: + // + // k*P = (k1 + k2*λ)*P + // = k1*P + k2*λ*P + // = k1*P + k2*φ(P) + // + // Thus, a speedup is achieved so long as it's faster to decompose the + // scalar, compute φ(P), and perform a simultaneous multiply of the + // half-length point multiplications than it is to compute a full width + // point multiplication. + // + // In practice, benchmarks show the current implementation provides a + // speedup of around 30-35% versus not using the endomorphism. + // + // See section 3.5 in [GECC] for a more rigorous treatment. + // ------------------------------------------------------------------------- + + // Per above, the main equation here to remember is: + // k*P = k1*P + k2*φ(P) + // + // p1 below is P in the equation while p2 is φ(P) in the equation. + // + // NOTE: φ(x,y) = (β*x,y). The Jacobian z coordinates are the same, so this + // math goes through. + // + // Also, calculate -p1 and -p2 for use in the NAF optimization. + p1, p1Neg := new(JacobianPoint), new(JacobianPoint) + p1.Set(point) + p1Neg.Set(p1) + p1Neg.Y.Negate(1).Normalize() + p2, p2Neg := new(JacobianPoint), new(JacobianPoint) + p2.Set(p1) + p2.X.Mul(endoBeta).Normalize() + p2Neg.Set(p2) + p2Neg.Y.Negate(1).Normalize() + + // Decompose k into k1 and k2 such that k = k1 + k2*λ (mod n) where k1 and + // k2 are around half the bit length of k in order to halve the number of EC + // operations. + // + // Notice that this also flips the sign of the scalars and points as needed + // to minimize the bit lengths of the scalars k1 and k2. + // + // This is done because the scalars are operating modulo the group order + // which means that when they would otherwise be a small negative magnitude + // they will instead be a large positive magnitude. Since the goal is for + // the scalars to have a small magnitude to achieve a performance boost, use + // their negation when they are greater than the half order of the group and + // flip the positive and negative values of the corresponding point that + // will be multiplied by to compensate. + // + // In other words, transform the calc when k1 is over the half order to: + // k1*P = -k1*-P + // + // Similarly, transform the calc when k2 is over the half order to: + // k2*φ(P) = -k2*-φ(P) + k1, k2 := splitK(k) + if k1.IsOverHalfOrder() { + k1.Negate() + p1, p1Neg = p1Neg, p1 + } + if k2.IsOverHalfOrder() { + k2.Negate() + p2, p2Neg = p2Neg, p2 + } + + // Convert k1 and k2 into their NAF representations since NAF has a lot more + // zeros overall on average which minimizes the number of required point + // additions in exchange for a mix of fewer point additions and subtractions + // at the cost of one additional point doubling. + // + // This is an excellent tradeoff because subtraction of points has the same + // computational complexity as addition of points and point doubling is + // faster than both. + // + // Concretely, on average, 1/2 of all bits will be non-zero with the normal + // binary representation whereas only 1/3rd of the bits will be non-zero + // with NAF. + // + // The Pos version of the bytes contain the +1s and the Neg versions contain + // the -1s. + k1Bytes, k2Bytes := k1.Bytes(), k2.Bytes() + k1NAF, k2NAF := naf(k1Bytes[:]), naf(k2Bytes[:]) + k1PosNAF, k1NegNAF := k1NAF.Pos(), k1NAF.Neg() + k2PosNAF, k2NegNAF := k2NAF.Pos(), k2NAF.Neg() + k1Len, k2Len := len(k1PosNAF), len(k2PosNAF) + + // Add left-to-right using the NAF optimization. See algorithm 3.77 from + // [GECC]. + // + // Point Q = ∞ (point at infinity). + var q JacobianPoint + m := k1Len + if m < k2Len { + m = k2Len + } + for i := 0; i < m; i++ { + // Since k1 and k2 are potentially different lengths and the calculation + // is being done left to right, pad the front of the shorter one with + // 0s. + var k1BytePos, k1ByteNeg, k2BytePos, k2ByteNeg byte + if i >= m-k1Len { + k1BytePos, k1ByteNeg = k1PosNAF[i-(m-k1Len)], k1NegNAF[i-(m-k1Len)] + } + if i >= m-k2Len { + k2BytePos, k2ByteNeg = k2PosNAF[i-(m-k2Len)], k2NegNAF[i-(m-k2Len)] + } + + for mask := uint8(1 << 7); mask > 0; mask >>= 1 { + // Q = 2 * Q + DoubleNonConst(&q, &q) + + // Add or subtract the first point based on the signed digit of the + // NAF representation of k1 at this bit position. + // + // +1: Q = Q + p1 + // -1: Q = Q - p1 + // 0: Q = Q (no change) + if k1BytePos&mask == mask { + AddNonConst(&q, p1, &q) + } else if k1ByteNeg&mask == mask { + AddNonConst(&q, p1Neg, &q) + } + + // Add or subtract the second point based on the signed digit of the + // NAF representation of k2 at this bit position. + // + // +1: Q = Q + p2 + // -1: Q = Q - p2 + // 0: Q = Q (no change) + if k2BytePos&mask == mask { + AddNonConst(&q, p2, &q) + } else if k2ByteNeg&mask == mask { + AddNonConst(&q, p2Neg, &q) + } + } + } + + result.Set(&q) +} + +// ScalarBaseMultNonConst multiplies k*G where k is a scalar modulo the curve +// order and G is the base point of the group and stores the result in the +// provided Jacobian point. +// +// NOTE: The resulting point will be normalized. +func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) { + scalarBaseMultNonConst(k, result) +} + +// jacobianG is the secp256k1 base point converted to Jacobian coordinates and +// is defined here to avoid repeatedly converting it. +var jacobianG = func() JacobianPoint { + var G JacobianPoint + bigAffineToJacobian(curveParams.Gx, curveParams.Gy, &G) + return G +}() + +// scalarBaseMultNonConstSlow computes k*G through ScalarMultNonConst. +func scalarBaseMultNonConstSlow(k *ModNScalar, result *JacobianPoint) { + ScalarMultNonConst(k, &jacobianG, result) +} + +// scalarBaseMultNonConstFast computes k*G through the precomputed lookup +// tables. +func scalarBaseMultNonConstFast(k *ModNScalar, result *JacobianPoint) { + bytePoints := s256BytePoints() + + // Start with the point at infinity. + result.X.Zero() + result.Y.Zero() + result.Z.Zero() + + // bytePoints has all 256 byte points for each 8-bit window. The strategy + // is to add up the byte points. This is best understood by expressing k in + // base-256 which it already sort of is. Each "digit" in the 8-bit window + // can be looked up using bytePoints and added together. + kb := k.Bytes() + for i := 0; i < len(kb); i++ { + pt := &bytePoints[i][kb[i]] + AddNonConst(result, pt, result) + } +} + +// isOnCurve returns whether or not the affine point (x,y) is on the curve. +func isOnCurve(fx, fy *FieldVal) bool { + // Elliptic curve equation for secp256k1 is: y^2 = x^3 + 7 + y2 := new(FieldVal).SquareVal(fy).Normalize() + result := new(FieldVal).SquareVal(fx).Mul(fx).AddInt(7).Normalize() + return y2.Equals(result) +} + +// DecompressY attempts to calculate the Y coordinate for the given X coordinate +// such that the result pair is a point on the secp256k1 curve. It adjusts Y +// based on the desired oddness and returns whether or not it was successful +// since not all X coordinates are valid. +// +// The magnitude of the provided X coordinate field value must be a max of 8 for +// a correct result. The resulting Y field value will have a magnitude of 1. +// +// Preconditions: +// - The input field value MUST have a max magnitude of 8 +// Output Normalized: Yes if the func returns true, no otherwise +// Output Max Magnitude: 1 +func DecompressY(x *FieldVal, odd bool, resultY *FieldVal) bool { + // The curve equation for secp256k1 is: y^2 = x^3 + 7. Thus + // y = +-sqrt(x^3 + 7). + // + // The x coordinate must be invalid if there is no square root for the + // calculated rhs because it means the X coordinate is not for a point on + // the curve. + x3PlusB := new(FieldVal).SquareVal(x).Mul(x).AddInt(7) + if hasSqrt := resultY.SquareRootVal(x3PlusB); !hasSqrt { + return false + } + if resultY.Normalize().IsOdd() != odd { + resultY.Negate(1).Normalize() + } + return true +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_embedded.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_embedded.go new file mode 100644 index 0000000000..16288318c1 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_embedded.go @@ -0,0 +1,14 @@ +// Copyright (c) 2024 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +//go:build tinygo + +package secp256k1 + +// This file contains the variants suitable for +// memory or storage constrained environments. + +func scalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) { + scalarBaseMultNonConstSlow(k, result) +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_precompute.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_precompute.go new file mode 100644 index 0000000000..cf84f770ed --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_precompute.go @@ -0,0 +1,14 @@ +// Copyright (c) 2024 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +//go:build !tinygo + +package secp256k1 + +// This file contains the variants that don't fit in +// memory or storage constrained environments. + +func scalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) { + scalarBaseMultNonConstFast(k, result) +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go new file mode 100644 index 0000000000..ac01e2343c --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go @@ -0,0 +1,59 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2022 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +/* +Package secp256k1 implements optimized secp256k1 elliptic curve operations in +pure Go. + +This package provides an optimized pure Go implementation of elliptic curve +cryptography operations over the secp256k1 curve as well as data structures and +functions for working with public and private secp256k1 keys. See +https://www.secg.org/sec2-v2.pdf for details on the standard. + +In addition, sub packages are provided to produce, verify, parse, and serialize +ECDSA signatures and EC-Schnorr-DCRv0 (a custom Schnorr-based signature scheme +specific to Decred) signatures. See the README.md files in the relevant sub +packages for more details about those aspects. + +An overview of the features provided by this package are as follows: + + - Private key generation, serialization, and parsing + - Public key generation, serialization and parsing per ANSI X9.62-1998 + - Parses uncompressed, compressed, and hybrid public keys + - Serializes uncompressed and compressed public keys + - Specialized types for performing optimized and constant time field operations + - FieldVal type for working modulo the secp256k1 field prime + - ModNScalar type for working modulo the secp256k1 group order + - Elliptic curve operations in Jacobian projective coordinates + - Point addition + - Point doubling + - Scalar multiplication with an arbitrary point + - Scalar multiplication with the base point (group generator) + - Point decompression from a given x coordinate + - Nonce generation via RFC6979 with support for extra data and version + information that can be used to prevent nonce reuse between signing + algorithms + +It also provides an implementation of the Go standard library crypto/elliptic +Curve interface via the S256 function so that it may be used with other packages +in the standard library such as crypto/tls, crypto/x509, and crypto/ecdsa. +However, in the case of ECDSA, it is highly recommended to use the ecdsa sub +package of this package instead since it is optimized specifically for secp256k1 +and is significantly faster as a result. + +Although this package was primarily written for dcrd, it has intentionally been +designed so it can be used as a standalone package for any projects needing to +use optimized secp256k1 elliptic curve cryptography. + +Finally, a comprehensive suite of tests is provided to provide a high level of +quality assurance. + +# Use of secp256k1 in Decred + +At the time of this writing, the primary public key cryptography in widespread +use on the Decred network used to secure coins is based on elliptic curves +defined by the secp256k1 domain parameters. +*/ +package secp256k1 diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go new file mode 100644 index 0000000000..96869a3cd9 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go @@ -0,0 +1,21 @@ +// Copyright (c) 2015 The btcsuite developers +// Copyright (c) 2015-2023 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// GenerateSharedSecret generates a shared secret based on a private key and a +// public key using Diffie-Hellman key exchange (ECDH) (RFC 5903). +// RFC5903 Section 9 states we should only return x. +// +// It is recommended to securely hash the result before using as a cryptographic +// key. +func GenerateSharedSecret(privkey *PrivateKey, pubkey *PublicKey) []byte { + var point, result JacobianPoint + pubkey.AsJacobian(&point) + ScalarMultNonConst(&privkey.Key, &point, &result) + result.ToAffine() + xBytes := result.X.Bytes() + return xBytes[:] +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go new file mode 100644 index 0000000000..a3a45af317 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go @@ -0,0 +1,255 @@ +// Copyright 2020-2022 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// References: +// [SECG]: Recommended Elliptic Curve Domain Parameters +// https://www.secg.org/sec2-v2.pdf +// +// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone) + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "math/big" +) + +// CurveParams contains the parameters for the secp256k1 curve. +type CurveParams struct { + // P is the prime used in the secp256k1 field. + P *big.Int + + // N is the order of the secp256k1 curve group generated by the base point. + N *big.Int + + // Gx and Gy are the x and y coordinate of the base point, respectively. + Gx, Gy *big.Int + + // BitSize is the size of the underlying secp256k1 field in bits. + BitSize int + + // H is the cofactor of the secp256k1 curve. + H int + + // ByteSize is simply the bit size / 8 and is provided for convenience + // since it is calculated repeatedly. + ByteSize int +} + +// Curve parameters taken from [SECG] section 2.4.1. +var curveParams = CurveParams{ + P: fromHex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"), + N: fromHex("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"), + Gx: fromHex("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"), + Gy: fromHex("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"), + BitSize: 256, + H: 1, + ByteSize: 256 / 8, +} + +// Params returns the secp256k1 curve parameters for convenience. +func Params() *CurveParams { + return &curveParams +} + +// KoblitzCurve provides an implementation for secp256k1 that fits the ECC Curve +// interface from crypto/elliptic. +type KoblitzCurve struct { + *elliptic.CurveParams +} + +// bigAffineToJacobian takes an affine point (x, y) as big integers and converts +// it to Jacobian point with Z=1. +func bigAffineToJacobian(x, y *big.Int, result *JacobianPoint) { + result.X.SetByteSlice(x.Bytes()) + result.Y.SetByteSlice(y.Bytes()) + result.Z.SetInt(1) +} + +// jacobianToBigAffine takes a Jacobian point (x, y, z) as field values and +// converts it to an affine point as big integers. +func jacobianToBigAffine(point *JacobianPoint) (*big.Int, *big.Int) { + point.ToAffine() + + // Convert the field values for the now affine point to big.Ints. + x3, y3 := new(big.Int), new(big.Int) + x3.SetBytes(point.X.Bytes()[:]) + y3.SetBytes(point.Y.Bytes()[:]) + return x3, y3 +} + +// Params returns the parameters for the curve. +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) Params() *elliptic.CurveParams { + return curve.CurveParams +} + +// IsOnCurve returns whether or not the affine point (x,y) is on the curve. +// +// This is part of the elliptic.Curve interface implementation. This function +// differs from the crypto/elliptic algorithm since a = 0 not -3. +func (curve *KoblitzCurve) IsOnCurve(x, y *big.Int) bool { + // Convert big ints to a Jacobian point for faster arithmetic. + var point JacobianPoint + bigAffineToJacobian(x, y, &point) + return isOnCurve(&point.X, &point.Y) +} + +// Add returns the sum of (x1,y1) and (x2,y2). +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { + // The point at infinity is the identity according to the group law for + // elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P. + if x1.Sign() == 0 && y1.Sign() == 0 { + return x2, y2 + } + if x2.Sign() == 0 && y2.Sign() == 0 { + return x1, y1 + } + + // Convert the affine coordinates from big integers to Jacobian points, + // do the point addition in Jacobian projective space, and convert the + // Jacobian point back to affine big.Ints. + var p1, p2, result JacobianPoint + bigAffineToJacobian(x1, y1, &p1) + bigAffineToJacobian(x2, y2, &p2) + AddNonConst(&p1, &p2, &result) + return jacobianToBigAffine(&result) +} + +// Double returns 2*(x1,y1). +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { + if y1.Sign() == 0 { + return new(big.Int), new(big.Int) + } + + // Convert the affine coordinates from big integers to Jacobian points, + // do the point doubling in Jacobian projective space, and convert the + // Jacobian point back to affine big.Ints. + var point, result JacobianPoint + bigAffineToJacobian(x1, y1, &point) + DoubleNonConst(&point, &result) + return jacobianToBigAffine(&result) +} + +// moduloReduce reduces k from more than 32 bytes to 32 bytes and under. This +// is done by doing a simple modulo curve.N. We can do this since G^N = 1 and +// thus any other valid point on the elliptic curve has the same order. +func moduloReduce(k []byte) []byte { + // Since the order of G is curve.N, we can use a much smaller number by + // doing modulo curve.N + if len(k) > curveParams.ByteSize { + tmpK := new(big.Int).SetBytes(k) + tmpK.Mod(tmpK, curveParams.N) + return tmpK.Bytes() + } + + return k +} + +// ScalarMult returns k*(bx, by) where k is a big endian integer. +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) ScalarMult(bx, by *big.Int, k []byte) (*big.Int, *big.Int) { + // Convert the affine coordinates from big integers to Jacobian points, + // do the multiplication in Jacobian projective space, and convert the + // Jacobian point back to affine big.Ints. + var kModN ModNScalar + kModN.SetByteSlice(moduloReduce(k)) + var point, result JacobianPoint + bigAffineToJacobian(bx, by, &point) + ScalarMultNonConst(&kModN, &point, &result) + return jacobianToBigAffine(&result) +} + +// ScalarBaseMult returns k*G where G is the base point of the group and k is a +// big endian integer. +// +// This is part of the elliptic.Curve interface implementation. +func (curve *KoblitzCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { + // Perform the multiplication and convert the Jacobian point back to affine + // big.Ints. + var kModN ModNScalar + kModN.SetByteSlice(moduloReduce(k)) + var result JacobianPoint + ScalarBaseMultNonConst(&kModN, &result) + return jacobianToBigAffine(&result) +} + +// X returns the x coordinate of the public key. +func (p *PublicKey) X() *big.Int { + return new(big.Int).SetBytes(p.x.Bytes()[:]) +} + +// Y returns the y coordinate of the public key. +func (p *PublicKey) Y() *big.Int { + return new(big.Int).SetBytes(p.y.Bytes()[:]) +} + +// ToECDSA returns the public key as a *ecdsa.PublicKey. +func (p *PublicKey) ToECDSA() *ecdsa.PublicKey { + return &ecdsa.PublicKey{ + Curve: S256(), + X: p.X(), + Y: p.Y(), + } +} + +// ToECDSA returns the private key as a *ecdsa.PrivateKey. +func (p *PrivateKey) ToECDSA() *ecdsa.PrivateKey { + var privKeyBytes [PrivKeyBytesLen]byte + p.Key.PutBytes(&privKeyBytes) + var result JacobianPoint + ScalarBaseMultNonConst(&p.Key, &result) + x, y := jacobianToBigAffine(&result) + newPrivKey := &ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: S256(), + X: x, + Y: y, + }, + D: new(big.Int).SetBytes(privKeyBytes[:]), + } + zeroArray32(&privKeyBytes) + return newPrivKey +} + +// fromHex converts the passed hex string into a big integer pointer and will +// panic is there is an error. This is only provided for the hard-coded +// constants so errors in the source code can bet detected. It will only (and +// must only) be called for initialization purposes. +func fromHex(s string) *big.Int { + if s == "" { + return big.NewInt(0) + } + r, ok := new(big.Int).SetString(s, 16) + if !ok { + panic("invalid hex in source file: " + s) + } + return r +} + +// secp256k1 is a global instance of the KoblitzCurve implementation which in +// turn embeds and implements elliptic.CurveParams. +var secp256k1 = &KoblitzCurve{ + CurveParams: &elliptic.CurveParams{ + P: curveParams.P, + N: curveParams.N, + B: fromHex("0000000000000000000000000000000000000000000000000000000000000007"), + Gx: curveParams.Gx, + Gy: curveParams.Gy, + BitSize: curveParams.BitSize, + Name: "secp256k1", + }, +} + +// S256 returns an elliptic.Curve which implements secp256k1. +func S256() *KoblitzCurve { + return secp256k1 +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go new file mode 100644 index 0000000000..ac8c45127e --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go @@ -0,0 +1,67 @@ +// Copyright (c) 2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// ErrorKind identifies a kind of error. It has full support for errors.Is and +// errors.As, so the caller can directly check against an error kind when +// determining the reason for an error. +type ErrorKind string + +// These constants are used to identify a specific RuleError. +const ( + // ErrPubKeyInvalidLen indicates that the length of a serialized public + // key is not one of the allowed lengths. + ErrPubKeyInvalidLen = ErrorKind("ErrPubKeyInvalidLen") + + // ErrPubKeyInvalidFormat indicates an attempt was made to parse a public + // key that does not specify one of the supported formats. + ErrPubKeyInvalidFormat = ErrorKind("ErrPubKeyInvalidFormat") + + // ErrPubKeyXTooBig indicates that the x coordinate for a public key + // is greater than or equal to the prime of the field underlying the group. + ErrPubKeyXTooBig = ErrorKind("ErrPubKeyXTooBig") + + // ErrPubKeyYTooBig indicates that the y coordinate for a public key is + // greater than or equal to the prime of the field underlying the group. + ErrPubKeyYTooBig = ErrorKind("ErrPubKeyYTooBig") + + // ErrPubKeyNotOnCurve indicates that a public key is not a point on the + // secp256k1 curve. + ErrPubKeyNotOnCurve = ErrorKind("ErrPubKeyNotOnCurve") + + // ErrPubKeyMismatchedOddness indicates that a hybrid public key specified + // an oddness of the y coordinate that does not match the actual oddness of + // the provided y coordinate. + ErrPubKeyMismatchedOddness = ErrorKind("ErrPubKeyMismatchedOddness") +) + +// Error satisfies the error interface and prints human-readable errors. +func (e ErrorKind) Error() string { + return string(e) +} + +// Error identifies an error related to public key cryptography using a +// sec256k1 curve. It has full support for errors.Is and errors.As, so the +// caller can ascertain the specific reason for the error by checking +// the underlying error. +type Error struct { + Err error + Description string +} + +// Error satisfies the error interface and prints human-readable errors. +func (e Error) Error() string { + return e.Description +} + +// Unwrap returns the underlying wrapped error. +func (e Error) Unwrap() error { + return e.Err +} + +// makeError creates an Error given a set of arguments. +func makeError(kind ErrorKind, desc string) Error { + return Error{Err: kind, Description: desc} +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go new file mode 100644 index 0000000000..f979bb2efe --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go @@ -0,0 +1,1696 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2024 The Decred developers +// Copyright (c) 2013-2024 Dave Collins +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// References: +// [HAC]: Handbook of Applied Cryptography Menezes, van Oorschot, Vanstone. +// http://cacr.uwaterloo.ca/hac/ + +// All elliptic curve operations for secp256k1 are done in a finite field +// characterized by a 256-bit prime. Given this precision is larger than the +// biggest available native type, obviously some form of bignum math is needed. +// This package implements specialized fixed-precision field arithmetic rather +// than relying on an arbitrary-precision arithmetic package such as math/big +// for dealing with the field math since the size is known. As a result, rather +// large performance gains are achieved by taking advantage of many +// optimizations not available to arbitrary-precision arithmetic and generic +// modular arithmetic algorithms. +// +// There are various ways to internally represent each finite field element. +// For example, the most obvious representation would be to use an array of 4 +// uint64s (64 bits * 4 = 256 bits). However, that representation suffers from +// a couple of issues. First, there is no native Go type large enough to handle +// the intermediate results while adding or multiplying two 64-bit numbers, and +// second there is no space left for overflows when performing the intermediate +// arithmetic between each array element which would lead to expensive carry +// propagation. +// +// Given the above, this implementation represents the field elements as +// 10 uint32s with each word (array entry) treated as base 2^26. This was +// chosen for the following reasons: +// 1) Most systems at the current time are 64-bit (or at least have 64-bit +// registers available for specialized purposes such as MMX) so the +// intermediate results can typically be done using a native register (and +// using uint64s to avoid the need for additional half-word arithmetic) +// 2) In order to allow addition of the internal words without having to +// propagate the carry, the max normalized value for each register must +// be less than the number of bits available in the register +// 3) Since we're dealing with 32-bit values, 64-bits of overflow is a +// reasonable choice for #2 +// 4) Given the need for 256-bits of precision and the properties stated in #1, +// #2, and #3, the representation which best accommodates this is 10 uint32s +// with base 2^26 (26 bits * 10 = 260 bits, so the final word only needs 22 +// bits) which leaves the desired 64 bits (32 * 10 = 320, 320 - 256 = 64) for +// overflow +// +// Since it is so important that the field arithmetic is extremely fast for high +// performance crypto, this type does not perform any validation where it +// ordinarily would. See the documentation for FieldVal for more details. + +import ( + "encoding/hex" +) + +// Constants used to make the code more readable. +const ( + twoBitsMask = 0x3 + fourBitsMask = 0xf + sixBitsMask = 0x3f + eightBitsMask = 0xff +) + +// Constants related to the field representation. +const ( + // fieldWords is the number of words used to internally represent the + // 256-bit value. + fieldWords = 10 + + // fieldBase is the exponent used to form the numeric base of each word. + // 2^(fieldBase*i) where i is the word position. + fieldBase = 26 + + // fieldBaseMask is the mask for the bits in each word needed to + // represent the numeric base of each word (except the most significant + // word). + fieldBaseMask = (1 << fieldBase) - 1 + + // fieldMSBBits is the number of bits in the most significant word used + // to represent the value. + fieldMSBBits = 256 - (fieldBase * (fieldWords - 1)) + + // fieldMSBMask is the mask for the bits in the most significant word + // needed to represent the value. + fieldMSBMask = (1 << fieldMSBBits) - 1 + + // These fields provide convenient access to each of the words of the + // secp256k1 prime in the internal field representation to improve code + // readability. + fieldPrimeWordZero = 0x03fffc2f + fieldPrimeWordOne = 0x03ffffbf + fieldPrimeWordTwo = 0x03ffffff + fieldPrimeWordThree = 0x03ffffff + fieldPrimeWordFour = 0x03ffffff + fieldPrimeWordFive = 0x03ffffff + fieldPrimeWordSix = 0x03ffffff + fieldPrimeWordSeven = 0x03ffffff + fieldPrimeWordEight = 0x03ffffff + fieldPrimeWordNine = 0x003fffff +) + +// FieldVal implements optimized fixed-precision arithmetic over the +// secp256k1 finite field. This means all arithmetic is performed modulo +// +// 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f. +// +// WARNING: Since it is so important for the field arithmetic to be extremely +// fast for high performance crypto, this type does not perform any validation +// of documented preconditions where it ordinarily would. As a result, it is +// IMPERATIVE for callers to understand some key concepts that are described +// below and ensure the methods are called with the necessary preconditions that +// each method is documented with. For example, some methods only give the +// correct result if the field value is normalized and others require the field +// values involved to have a maximum magnitude and THERE ARE NO EXPLICIT CHECKS +// TO ENSURE THOSE PRECONDITIONS ARE SATISFIED. This does, unfortunately, make +// the type more difficult to use correctly and while I typically prefer to +// ensure all state and input is valid for most code, this is a bit of an +// exception because those extra checks really add up in what ends up being +// critical hot paths. +// +// The first key concept when working with this type is normalization. In order +// to avoid the need to propagate a ton of carries, the internal representation +// provides additional overflow bits for each word of the overall 256-bit value. +// This means that there are multiple internal representations for the same +// value and, as a result, any methods that rely on comparison of the value, +// such as equality and oddness determination, require the caller to provide a +// normalized value. +// +// The second key concept when working with this type is magnitude. As +// previously mentioned, the internal representation provides additional +// overflow bits which means that the more math operations that are performed on +// the field value between normalizations, the more those overflow bits +// accumulate. The magnitude is effectively that maximum possible number of +// those overflow bits that could possibly be required as a result of a given +// operation. Since there are only a limited number of overflow bits available, +// this implies that the max possible magnitude MUST be tracked by the caller +// and the caller MUST normalize the field value if a given operation would +// cause the magnitude of the result to exceed the max allowed value. +// +// IMPORTANT: The max allowed magnitude of a field value is 32. +type FieldVal struct { + // Each 256-bit value is represented as 10 32-bit integers in base 2^26. + // This provides 6 bits of overflow in each word (10 bits in the most + // significant word) for a total of 64 bits of overflow (9*6 + 10 = 64). It + // only implements the arithmetic needed for elliptic curve operations. + // + // The following depicts the internal representation: + // ----------------------------------------------------------------- + // | n[9] | n[8] | ... | n[0] | + // | 32 bits available | 32 bits available | ... | 32 bits available | + // | 22 bits for value | 26 bits for value | ... | 26 bits for value | + // | 10 bits overflow | 6 bits overflow | ... | 6 bits overflow | + // | Mult: 2^(26*9) | Mult: 2^(26*8) | ... | Mult: 2^(26*0) | + // ----------------------------------------------------------------- + // + // For example, consider the number 2^49 + 1. It would be represented as: + // n[0] = 1 + // n[1] = 2^23 + // n[2..9] = 0 + // + // The full 256-bit value is then calculated by looping i from 9..0 and + // doing sum(n[i] * 2^(26i)) like so: + // n[9] * 2^(26*9) = 0 * 2^234 = 0 + // n[8] * 2^(26*8) = 0 * 2^208 = 0 + // ... + // n[1] * 2^(26*1) = 2^23 * 2^26 = 2^49 + // n[0] * 2^(26*0) = 1 * 2^0 = 1 + // Sum: 0 + 0 + ... + 2^49 + 1 = 2^49 + 1 + n [10]uint32 +} + +// String returns the field value as a normalized human-readable hex string. +// +// Preconditions: None +// Output Normalized: Field is not modified -- same as input value +// Output Max Magnitude: Field is not modified -- same as input value +func (f FieldVal) String() string { + // f is a copy, so it's safe to normalize it without mutating the original. + f.Normalize() + return hex.EncodeToString(f.Bytes()[:]) +} + +// Zero sets the field value to zero in constant time. A newly created field +// value is already set to zero. This function can be useful to clear an +// existing field value for reuse. +// +// Preconditions: None +// Output Normalized: Yes +// Output Max Magnitude: 1 +func (f *FieldVal) Zero() { + f.n[0] = 0 + f.n[1] = 0 + f.n[2] = 0 + f.n[3] = 0 + f.n[4] = 0 + f.n[5] = 0 + f.n[6] = 0 + f.n[7] = 0 + f.n[8] = 0 + f.n[9] = 0 +} + +// Set sets the field value equal to the passed value in constant time. The +// normalization and magnitude of the two fields will be identical. +// +// The field value is returned to support chaining. This enables syntax like: +// f := new(FieldVal).Set(f2).Add(1) so that f = f2 + 1 where f2 is not +// modified. +// +// Preconditions: None +// Output Normalized: Same as input value +// Output Max Magnitude: Same as input value +func (f *FieldVal) Set(val *FieldVal) *FieldVal { + *f = *val + return f +} + +// SetInt sets the field value to the passed integer in constant time. This is +// a convenience function since it is fairly common to perform some arithmetic +// with small native integers. +// +// The field value is returned to support chaining. This enables syntax such +// as f := new(FieldVal).SetInt(2).Mul(f2) so that f = 2 * f2. +// +// Preconditions: None +// Output Normalized: Yes +// Output Max Magnitude: 1 +func (f *FieldVal) SetInt(ui uint16) *FieldVal { + f.Zero() + f.n[0] = uint32(ui) + return f +} + +// SetBytes packs the passed 32-byte big-endian value into the internal field +// value representation in constant time. SetBytes interprets the provided +// array as a 256-bit big-endian unsigned integer, packs it into the internal +// field value representation, and returns either 1 if it is greater than or +// equal to the field prime (aka it overflowed) or 0 otherwise in constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. +// +// Preconditions: None +// Output Normalized: Yes if no overflow, no otherwise +// Output Max Magnitude: 1 +func (f *FieldVal) SetBytes(b *[32]byte) uint32 { + // Pack the 256 total bits across the 10 uint32 words with a max of + // 26-bits per word. This could be done with a couple of for loops, + // but this unrolled version is significantly faster. Benchmarks show + // this is about 34 times faster than the variant which uses loops. + f.n[0] = uint32(b[31]) | uint32(b[30])<<8 | uint32(b[29])<<16 | + (uint32(b[28])&twoBitsMask)<<24 + f.n[1] = uint32(b[28])>>2 | uint32(b[27])<<6 | uint32(b[26])<<14 | + (uint32(b[25])&fourBitsMask)<<22 + f.n[2] = uint32(b[25])>>4 | uint32(b[24])<<4 | uint32(b[23])<<12 | + (uint32(b[22])&sixBitsMask)<<20 + f.n[3] = uint32(b[22])>>6 | uint32(b[21])<<2 | uint32(b[20])<<10 | + uint32(b[19])<<18 + f.n[4] = uint32(b[18]) | uint32(b[17])<<8 | uint32(b[16])<<16 | + (uint32(b[15])&twoBitsMask)<<24 + f.n[5] = uint32(b[15])>>2 | uint32(b[14])<<6 | uint32(b[13])<<14 | + (uint32(b[12])&fourBitsMask)<<22 + f.n[6] = uint32(b[12])>>4 | uint32(b[11])<<4 | uint32(b[10])<<12 | + (uint32(b[9])&sixBitsMask)<<20 + f.n[7] = uint32(b[9])>>6 | uint32(b[8])<<2 | uint32(b[7])<<10 | + uint32(b[6])<<18 + f.n[8] = uint32(b[5]) | uint32(b[4])<<8 | uint32(b[3])<<16 | + (uint32(b[2])&twoBitsMask)<<24 + f.n[9] = uint32(b[2])>>2 | uint32(b[1])<<6 | uint32(b[0])<<14 + + // The intuition here is that the field value is greater than the prime if + // one of the higher individual words is greater than corresponding word of + // the prime and all higher words in the field value are equal to their + // corresponding word of the prime. Since this type is modulo the prime, + // being equal is also an overflow back to 0. + // + // Note that because the input is 32 bytes and it was just packed into the + // field representation, the only words that can possibly be greater are + // zero and one, because ceil(log_2(2^256 - 1 - P)) = 33 bits max and the + // internal field representation encodes 26 bits with each word. + // + // Thus, there is no need to test if the upper words of the field value + // exceeds them, hence, only equality is checked for them. + highWordsEq := constantTimeEq(f.n[9], fieldPrimeWordNine) + highWordsEq &= constantTimeEq(f.n[8], fieldPrimeWordEight) + highWordsEq &= constantTimeEq(f.n[7], fieldPrimeWordSeven) + highWordsEq &= constantTimeEq(f.n[6], fieldPrimeWordSix) + highWordsEq &= constantTimeEq(f.n[5], fieldPrimeWordFive) + highWordsEq &= constantTimeEq(f.n[4], fieldPrimeWordFour) + highWordsEq &= constantTimeEq(f.n[3], fieldPrimeWordThree) + highWordsEq &= constantTimeEq(f.n[2], fieldPrimeWordTwo) + overflow := highWordsEq & constantTimeGreater(f.n[1], fieldPrimeWordOne) + highWordsEq &= constantTimeEq(f.n[1], fieldPrimeWordOne) + overflow |= highWordsEq & constantTimeGreaterOrEq(f.n[0], fieldPrimeWordZero) + + return overflow +} + +// SetByteSlice interprets the provided slice as a 256-bit big-endian unsigned +// integer (meaning it is truncated to the first 32 bytes), packs it into the +// internal field value representation, and returns whether or not the resulting +// truncated 256-bit integer is greater than or equal to the field prime (aka it +// overflowed) in constant time. +// +// Note that since passing a slice with more than 32 bytes is truncated, it is +// possible that the truncated value is less than the field prime and hence it +// will not be reported as having overflowed in that case. It is up to the +// caller to decide whether it needs to provide numbers of the appropriate size +// or it if is acceptable to use this function with the described truncation and +// overflow behavior. +// +// Preconditions: None +// Output Normalized: Yes if no overflow, no otherwise +// Output Max Magnitude: 1 +func (f *FieldVal) SetByteSlice(b []byte) bool { + var b32 [32]byte + b = b[:constantTimeMin(uint32(len(b)), 32)] + copy(b32[:], b32[:32-len(b)]) + copy(b32[32-len(b):], b) + result := f.SetBytes(&b32) + zeroArray32(&b32) + return result != 0 +} + +// Normalize normalizes the internal field words into the desired range and +// performs fast modular reduction over the secp256k1 prime by making use of the +// special form of the prime in constant time. +// +// Preconditions: None +// Output Normalized: Yes +// Output Max Magnitude: 1 +func (f *FieldVal) Normalize() *FieldVal { + // The field representation leaves 6 bits of overflow in each word so + // intermediate calculations can be performed without needing to + // propagate the carry to each higher word during the calculations. In + // order to normalize, we need to "compact" the full 256-bit value to + // the right while propagating any carries through to the high order + // word. + // + // Since this field is doing arithmetic modulo the secp256k1 prime, we + // also need to perform modular reduction over the prime. + // + // Per [HAC] section 14.3.4: Reduction method of moduli of special form, + // when the modulus is of the special form m = b^t - c, highly efficient + // reduction can be achieved. + // + // The secp256k1 prime is equivalent to 2^256 - 4294968273, so it fits + // this criteria. + // + // 4294968273 in field representation (base 2^26) is: + // n[0] = 977 + // n[1] = 64 + // That is to say (2^26 * 64) + 977 = 4294968273 + // + // The algorithm presented in the referenced section typically repeats + // until the quotient is zero. However, due to our field representation + // we already know to within one reduction how many times we would need + // to repeat as it's the uppermost bits of the high order word. Thus we + // can simply multiply the magnitude by the field representation of the + // prime and do a single iteration. After this step there might be an + // additional carry to bit 256 (bit 22 of the high order word). + t9 := f.n[9] + m := t9 >> fieldMSBBits + t9 &= fieldMSBMask + t0 := f.n[0] + m*977 + t1 := (t0 >> fieldBase) + f.n[1] + (m << 6) + t0 &= fieldBaseMask + t2 := (t1 >> fieldBase) + f.n[2] + t1 &= fieldBaseMask + t3 := (t2 >> fieldBase) + f.n[3] + t2 &= fieldBaseMask + t4 := (t3 >> fieldBase) + f.n[4] + t3 &= fieldBaseMask + t5 := (t4 >> fieldBase) + f.n[5] + t4 &= fieldBaseMask + t6 := (t5 >> fieldBase) + f.n[6] + t5 &= fieldBaseMask + t7 := (t6 >> fieldBase) + f.n[7] + t6 &= fieldBaseMask + t8 := (t7 >> fieldBase) + f.n[8] + t7 &= fieldBaseMask + t9 = (t8 >> fieldBase) + t9 + t8 &= fieldBaseMask + + // At this point, the magnitude is guaranteed to be one, however, the + // value could still be greater than the prime if there was either a + // carry through to bit 256 (bit 22 of the higher order word) or the + // value is greater than or equal to the field characteristic. The + // following determines if either or these conditions are true and does + // the final reduction in constant time. + // + // Also note that 'm' will be zero when neither of the aforementioned + // conditions are true and the value will not be changed when 'm' is zero. + m = constantTimeEq(t9, fieldMSBMask) + m &= constantTimeEq(t8&t7&t6&t5&t4&t3&t2, fieldBaseMask) + m &= constantTimeGreater(t1+64+((t0+977)>>fieldBase), fieldBaseMask) + m |= t9 >> fieldMSBBits + t0 += m * 977 + t1 = (t0 >> fieldBase) + t1 + (m << 6) + t0 &= fieldBaseMask + t2 = (t1 >> fieldBase) + t2 + t1 &= fieldBaseMask + t3 = (t2 >> fieldBase) + t3 + t2 &= fieldBaseMask + t4 = (t3 >> fieldBase) + t4 + t3 &= fieldBaseMask + t5 = (t4 >> fieldBase) + t5 + t4 &= fieldBaseMask + t6 = (t5 >> fieldBase) + t6 + t5 &= fieldBaseMask + t7 = (t6 >> fieldBase) + t7 + t6 &= fieldBaseMask + t8 = (t7 >> fieldBase) + t8 + t7 &= fieldBaseMask + t9 = (t8 >> fieldBase) + t9 + t8 &= fieldBaseMask + t9 &= fieldMSBMask // Remove potential multiple of 2^256. + + // Finally, set the normalized and reduced words. + f.n[0] = t0 + f.n[1] = t1 + f.n[2] = t2 + f.n[3] = t3 + f.n[4] = t4 + f.n[5] = t5 + f.n[6] = t6 + f.n[7] = t7 + f.n[8] = t8 + f.n[9] = t9 + return f +} + +// PutBytesUnchecked unpacks the field value to a 32-byte big-endian value +// directly into the passed byte slice in constant time. The target slice must +// have at least 32 bytes available or it will panic. +// +// There is a similar function, PutBytes, which unpacks the field value into a +// 32-byte array directly. This version is provided since it can be useful +// to write directly into part of a larger buffer without needing a separate +// allocation. +// +// Preconditions: +// - The field value MUST be normalized +// - The target slice MUST have at least 32 bytes available +func (f *FieldVal) PutBytesUnchecked(b []byte) { + // Unpack the 256 total bits from the 10 uint32 words with a max of + // 26-bits per word. This could be done with a couple of for loops, + // but this unrolled version is a bit faster. Benchmarks show this is + // about 10 times faster than the variant which uses loops. + b[31] = byte(f.n[0] & eightBitsMask) + b[30] = byte((f.n[0] >> 8) & eightBitsMask) + b[29] = byte((f.n[0] >> 16) & eightBitsMask) + b[28] = byte((f.n[0]>>24)&twoBitsMask | (f.n[1]&sixBitsMask)<<2) + b[27] = byte((f.n[1] >> 6) & eightBitsMask) + b[26] = byte((f.n[1] >> 14) & eightBitsMask) + b[25] = byte((f.n[1]>>22)&fourBitsMask | (f.n[2]&fourBitsMask)<<4) + b[24] = byte((f.n[2] >> 4) & eightBitsMask) + b[23] = byte((f.n[2] >> 12) & eightBitsMask) + b[22] = byte((f.n[2]>>20)&sixBitsMask | (f.n[3]&twoBitsMask)<<6) + b[21] = byte((f.n[3] >> 2) & eightBitsMask) + b[20] = byte((f.n[3] >> 10) & eightBitsMask) + b[19] = byte((f.n[3] >> 18) & eightBitsMask) + b[18] = byte(f.n[4] & eightBitsMask) + b[17] = byte((f.n[4] >> 8) & eightBitsMask) + b[16] = byte((f.n[4] >> 16) & eightBitsMask) + b[15] = byte((f.n[4]>>24)&twoBitsMask | (f.n[5]&sixBitsMask)<<2) + b[14] = byte((f.n[5] >> 6) & eightBitsMask) + b[13] = byte((f.n[5] >> 14) & eightBitsMask) + b[12] = byte((f.n[5]>>22)&fourBitsMask | (f.n[6]&fourBitsMask)<<4) + b[11] = byte((f.n[6] >> 4) & eightBitsMask) + b[10] = byte((f.n[6] >> 12) & eightBitsMask) + b[9] = byte((f.n[6]>>20)&sixBitsMask | (f.n[7]&twoBitsMask)<<6) + b[8] = byte((f.n[7] >> 2) & eightBitsMask) + b[7] = byte((f.n[7] >> 10) & eightBitsMask) + b[6] = byte((f.n[7] >> 18) & eightBitsMask) + b[5] = byte(f.n[8] & eightBitsMask) + b[4] = byte((f.n[8] >> 8) & eightBitsMask) + b[3] = byte((f.n[8] >> 16) & eightBitsMask) + b[2] = byte((f.n[8]>>24)&twoBitsMask | (f.n[9]&sixBitsMask)<<2) + b[1] = byte((f.n[9] >> 6) & eightBitsMask) + b[0] = byte((f.n[9] >> 14) & eightBitsMask) +} + +// PutBytes unpacks the field value to a 32-byte big-endian value using the +// passed byte array in constant time. +// +// There is a similar function, PutBytesUnchecked, which unpacks the field value +// into a slice that must have at least 32 bytes available. This version is +// provided since it can be useful to write directly into an array that is type +// checked. +// +// Alternatively, there is also Bytes, which unpacks the field value into a new +// array and returns that which can sometimes be more ergonomic in applications +// that aren't concerned about an additional copy. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) PutBytes(b *[32]byte) { + f.PutBytesUnchecked(b[:]) +} + +// Bytes unpacks the field value to a 32-byte big-endian value in constant time. +// +// See PutBytes and PutBytesUnchecked for variants that allow an array or slice +// to be passed which can be useful to cut down on the number of allocations by +// allowing the caller to reuse a buffer or write directly into part of a larger +// buffer. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) Bytes() *[32]byte { + b := new([32]byte) + f.PutBytesUnchecked(b[:]) + return b +} + +// IsZeroBit returns 1 when the field value is equal to zero or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. See IsZero for the version that returns +// a bool. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsZeroBit() uint32 { + // The value can only be zero if no bits are set in any of the words. + // This is a constant time implementation. + bits := f.n[0] | f.n[1] | f.n[2] | f.n[3] | f.n[4] | + f.n[5] | f.n[6] | f.n[7] | f.n[8] | f.n[9] + + return constantTimeEq(bits, 0) +} + +// IsZero returns whether or not the field value is equal to zero in constant +// time. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsZero() bool { + // The value can only be zero if no bits are set in any of the words. + // This is a constant time implementation. + bits := f.n[0] | f.n[1] | f.n[2] | f.n[3] | f.n[4] | + f.n[5] | f.n[6] | f.n[7] | f.n[8] | f.n[9] + + return bits == 0 +} + +// IsOneBit returns 1 when the field value is equal to one or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. See IsOne for the version that returns a +// bool. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsOneBit() uint32 { + // The value can only be one if the single lowest significant bit is set in + // the first word and no other bits are set in any of the other words. + // This is a constant time implementation. + bits := (f.n[0] ^ 1) | f.n[1] | f.n[2] | f.n[3] | f.n[4] | f.n[5] | + f.n[6] | f.n[7] | f.n[8] | f.n[9] + + return constantTimeEq(bits, 0) +} + +// IsOne returns whether or not the field value is equal to one in constant +// time. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsOne() bool { + // The value can only be one if the single lowest significant bit is set in + // the first word and no other bits are set in any of the other words. + // This is a constant time implementation. + bits := (f.n[0] ^ 1) | f.n[1] | f.n[2] | f.n[3] | f.n[4] | f.n[5] | + f.n[6] | f.n[7] | f.n[8] | f.n[9] + + return bits == 0 +} + +// IsOddBit returns 1 when the field value is an odd number or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. See IsOdd for the version that returns a +// bool. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsOddBit() uint32 { + // Only odd numbers have the bottom bit set. + return f.n[0] & 1 +} + +// IsOdd returns whether or not the field value is an odd number in constant +// time. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsOdd() bool { + // Only odd numbers have the bottom bit set. + return f.n[0]&1 == 1 +} + +// Equals returns whether or not the two field values are the same in constant +// time. +// +// Preconditions: +// - Both field values being compared MUST be normalized +func (f *FieldVal) Equals(val *FieldVal) bool { + // Xor only sets bits when they are different, so the two field values + // can only be the same if no bits are set after xoring each word. + // This is a constant time implementation. + bits := (f.n[0] ^ val.n[0]) | (f.n[1] ^ val.n[1]) | (f.n[2] ^ val.n[2]) | + (f.n[3] ^ val.n[3]) | (f.n[4] ^ val.n[4]) | (f.n[5] ^ val.n[5]) | + (f.n[6] ^ val.n[6]) | (f.n[7] ^ val.n[7]) | (f.n[8] ^ val.n[8]) | + (f.n[9] ^ val.n[9]) + + return bits == 0 +} + +// NegateVal negates the passed value and stores the result in f in constant +// time. The caller must provide the maximum magnitude of the passed value for +// a correct result. +// +// The field value is returned to support chaining. This enables syntax like: +// f.NegateVal(f2).AddInt(1) so that f = -f2 + 1. +// +// Preconditions: +// - The max magnitude MUST be 31 +// Output Normalized: No +// Output Max Magnitude: Input magnitude + 1 +func (f *FieldVal) NegateVal(val *FieldVal, magnitude uint32) *FieldVal { + // Negation in the field is just the prime minus the value. However, + // in order to allow negation against a field value without having to + // normalize/reduce it first, multiply by the magnitude (that is how + // "far" away it is from the normalized value) to adjust. Also, since + // negating a value pushes it one more order of magnitude away from the + // normalized range, add 1 to compensate. + // + // For some intuition here, imagine you're performing mod 12 arithmetic + // (picture a clock) and you are negating the number 7. So you start at + // 12 (which is of course 0 under mod 12) and count backwards (left on + // the clock) 7 times to arrive at 5. Notice this is just 12-7 = 5. + // Now, assume you're starting with 19, which is a number that is + // already larger than the modulus and congruent to 7 (mod 12). When a + // value is already in the desired range, its magnitude is 1. Since 19 + // is an additional "step", its magnitude (mod 12) is 2. Since any + // multiple of the modulus is congruent to zero (mod m), the answer can + // be shortcut by simply multiplying the magnitude by the modulus and + // subtracting. Keeping with the example, this would be (2*12)-19 = 5. + f.n[0] = (magnitude+1)*fieldPrimeWordZero - val.n[0] + f.n[1] = (magnitude+1)*fieldPrimeWordOne - val.n[1] + f.n[2] = (magnitude+1)*fieldBaseMask - val.n[2] + f.n[3] = (magnitude+1)*fieldBaseMask - val.n[3] + f.n[4] = (magnitude+1)*fieldBaseMask - val.n[4] + f.n[5] = (magnitude+1)*fieldBaseMask - val.n[5] + f.n[6] = (magnitude+1)*fieldBaseMask - val.n[6] + f.n[7] = (magnitude+1)*fieldBaseMask - val.n[7] + f.n[8] = (magnitude+1)*fieldBaseMask - val.n[8] + f.n[9] = (magnitude+1)*fieldMSBMask - val.n[9] + + return f +} + +// Negate negates the field value in constant time. The existing field value is +// modified. The caller must provide the maximum magnitude of the field value +// for a correct result. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Negate().AddInt(1) so that f = -f + 1. +// +// Preconditions: +// - The max magnitude MUST be 31 +// Output Normalized: No +// Output Max Magnitude: Input magnitude + 1 +func (f *FieldVal) Negate(magnitude uint32) *FieldVal { + return f.NegateVal(f, magnitude) +} + +// AddInt adds the passed integer to the existing field value and stores the +// result in f in constant time. This is a convenience function since it is +// fairly common to perform some arithmetic with small native integers. +// +// The field value is returned to support chaining. This enables syntax like: +// f.AddInt(1).Add(f2) so that f = f + 1 + f2. +// +// Preconditions: +// - The field value MUST have a max magnitude of 31 +// - The integer MUST be a max of 32767 +// Output Normalized: No +// Output Max Magnitude: Existing field magnitude + 1 +func (f *FieldVal) AddInt(ui uint16) *FieldVal { + // Since the field representation intentionally provides overflow bits, + // it's ok to use carryless addition as the carry bit is safely part of + // the word and will be normalized out. + f.n[0] += uint32(ui) + + return f +} + +// Add adds the passed value to the existing field value and stores the result +// in f in constant time. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Add(f2).AddInt(1) so that f = f + f2 + 1. +// +// Preconditions: +// - The sum of the magnitudes of the two field values MUST be a max of 32 +// Output Normalized: No +// Output Max Magnitude: Sum of the magnitude of the two individual field values +func (f *FieldVal) Add(val *FieldVal) *FieldVal { + // Since the field representation intentionally provides overflow bits, + // it's ok to use carryless addition as the carry bit is safely part of + // each word and will be normalized out. This could obviously be done + // in a loop, but the unrolled version is faster. + f.n[0] += val.n[0] + f.n[1] += val.n[1] + f.n[2] += val.n[2] + f.n[3] += val.n[3] + f.n[4] += val.n[4] + f.n[5] += val.n[5] + f.n[6] += val.n[6] + f.n[7] += val.n[7] + f.n[8] += val.n[8] + f.n[9] += val.n[9] + + return f +} + +// Add2 adds the passed two field values together and stores the result in f in +// constant time. +// +// The field value is returned to support chaining. This enables syntax like: +// f3.Add2(f, f2).AddInt(1) so that f3 = f + f2 + 1. +// +// Preconditions: +// - The sum of the magnitudes of the two field values MUST be a max of 32 +// Output Normalized: No +// Output Max Magnitude: Sum of the magnitude of the two field values +func (f *FieldVal) Add2(val *FieldVal, val2 *FieldVal) *FieldVal { + // Since the field representation intentionally provides overflow bits, + // it's ok to use carryless addition as the carry bit is safely part of + // each word and will be normalized out. This could obviously be done + // in a loop, but the unrolled version is faster. + f.n[0] = val.n[0] + val2.n[0] + f.n[1] = val.n[1] + val2.n[1] + f.n[2] = val.n[2] + val2.n[2] + f.n[3] = val.n[3] + val2.n[3] + f.n[4] = val.n[4] + val2.n[4] + f.n[5] = val.n[5] + val2.n[5] + f.n[6] = val.n[6] + val2.n[6] + f.n[7] = val.n[7] + val2.n[7] + f.n[8] = val.n[8] + val2.n[8] + f.n[9] = val.n[9] + val2.n[9] + + return f +} + +// MulInt multiplies the field value by the passed int and stores the result in +// f in constant time. Note that this function can overflow if multiplying the +// value by any of the individual words exceeds a max uint32. Therefore it is +// important that the caller ensures no overflows will occur before using this +// function. +// +// The field value is returned to support chaining. This enables syntax like: +// f.MulInt(2).Add(f2) so that f = 2 * f + f2. +// +// Preconditions: +// - The field value magnitude multiplied by given val MUST be a max of 32 +// Output Normalized: No +// Output Max Magnitude: Existing field magnitude times the provided integer val +func (f *FieldVal) MulInt(val uint8) *FieldVal { + // Since each word of the field representation can hold up to + // 32 - fieldBase extra bits which will be normalized out, it's safe + // to multiply each word without using a larger type or carry + // propagation so long as the values won't overflow a uint32. This + // could obviously be done in a loop, but the unrolled version is + // faster. + ui := uint32(val) + f.n[0] *= ui + f.n[1] *= ui + f.n[2] *= ui + f.n[3] *= ui + f.n[4] *= ui + f.n[5] *= ui + f.n[6] *= ui + f.n[7] *= ui + f.n[8] *= ui + f.n[9] *= ui + + return f +} + +// Mul multiplies the passed value to the existing field value and stores the +// result in f in constant time. Note that this function can overflow if +// multiplying any of the individual words exceeds a max uint32. In practice, +// this means the magnitude of either value involved in the multiplication must +// be a max of 8. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Mul(f2).AddInt(1) so that f = (f * f2) + 1. +// +// Preconditions: +// - Both field values MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) Mul(val *FieldVal) *FieldVal { + return f.Mul2(f, val) +} + +// Mul2 multiplies the passed two field values together and stores the result in +// f in constant time. Note that this function can overflow if multiplying any +// of the individual words exceeds a max uint32. In practice, this means the +// magnitude of either value involved in the multiplication must be a max of 8. +// +// The field value is returned to support chaining. This enables syntax like: +// f3.Mul2(f, f2).AddInt(1) so that f3 = (f * f2) + 1. +// +// Preconditions: +// - Both input field values MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) Mul2(val *FieldVal, val2 *FieldVal) *FieldVal { + // This could be done with a couple of for loops and an array to store + // the intermediate terms, but this unrolled version is significantly + // faster. + + // Terms for 2^(fieldBase*0). + m := uint64(val.n[0]) * uint64(val2.n[0]) + t0 := m & fieldBaseMask + + // Terms for 2^(fieldBase*1). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[1]) + + uint64(val.n[1])*uint64(val2.n[0]) + t1 := m & fieldBaseMask + + // Terms for 2^(fieldBase*2). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[2]) + + uint64(val.n[1])*uint64(val2.n[1]) + + uint64(val.n[2])*uint64(val2.n[0]) + t2 := m & fieldBaseMask + + // Terms for 2^(fieldBase*3). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[3]) + + uint64(val.n[1])*uint64(val2.n[2]) + + uint64(val.n[2])*uint64(val2.n[1]) + + uint64(val.n[3])*uint64(val2.n[0]) + t3 := m & fieldBaseMask + + // Terms for 2^(fieldBase*4). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[4]) + + uint64(val.n[1])*uint64(val2.n[3]) + + uint64(val.n[2])*uint64(val2.n[2]) + + uint64(val.n[3])*uint64(val2.n[1]) + + uint64(val.n[4])*uint64(val2.n[0]) + t4 := m & fieldBaseMask + + // Terms for 2^(fieldBase*5). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[5]) + + uint64(val.n[1])*uint64(val2.n[4]) + + uint64(val.n[2])*uint64(val2.n[3]) + + uint64(val.n[3])*uint64(val2.n[2]) + + uint64(val.n[4])*uint64(val2.n[1]) + + uint64(val.n[5])*uint64(val2.n[0]) + t5 := m & fieldBaseMask + + // Terms for 2^(fieldBase*6). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[6]) + + uint64(val.n[1])*uint64(val2.n[5]) + + uint64(val.n[2])*uint64(val2.n[4]) + + uint64(val.n[3])*uint64(val2.n[3]) + + uint64(val.n[4])*uint64(val2.n[2]) + + uint64(val.n[5])*uint64(val2.n[1]) + + uint64(val.n[6])*uint64(val2.n[0]) + t6 := m & fieldBaseMask + + // Terms for 2^(fieldBase*7). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[7]) + + uint64(val.n[1])*uint64(val2.n[6]) + + uint64(val.n[2])*uint64(val2.n[5]) + + uint64(val.n[3])*uint64(val2.n[4]) + + uint64(val.n[4])*uint64(val2.n[3]) + + uint64(val.n[5])*uint64(val2.n[2]) + + uint64(val.n[6])*uint64(val2.n[1]) + + uint64(val.n[7])*uint64(val2.n[0]) + t7 := m & fieldBaseMask + + // Terms for 2^(fieldBase*8). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[8]) + + uint64(val.n[1])*uint64(val2.n[7]) + + uint64(val.n[2])*uint64(val2.n[6]) + + uint64(val.n[3])*uint64(val2.n[5]) + + uint64(val.n[4])*uint64(val2.n[4]) + + uint64(val.n[5])*uint64(val2.n[3]) + + uint64(val.n[6])*uint64(val2.n[2]) + + uint64(val.n[7])*uint64(val2.n[1]) + + uint64(val.n[8])*uint64(val2.n[0]) + t8 := m & fieldBaseMask + + // Terms for 2^(fieldBase*9). + m = (m >> fieldBase) + + uint64(val.n[0])*uint64(val2.n[9]) + + uint64(val.n[1])*uint64(val2.n[8]) + + uint64(val.n[2])*uint64(val2.n[7]) + + uint64(val.n[3])*uint64(val2.n[6]) + + uint64(val.n[4])*uint64(val2.n[5]) + + uint64(val.n[5])*uint64(val2.n[4]) + + uint64(val.n[6])*uint64(val2.n[3]) + + uint64(val.n[7])*uint64(val2.n[2]) + + uint64(val.n[8])*uint64(val2.n[1]) + + uint64(val.n[9])*uint64(val2.n[0]) + t9 := m & fieldBaseMask + + // Terms for 2^(fieldBase*10). + m = (m >> fieldBase) + + uint64(val.n[1])*uint64(val2.n[9]) + + uint64(val.n[2])*uint64(val2.n[8]) + + uint64(val.n[3])*uint64(val2.n[7]) + + uint64(val.n[4])*uint64(val2.n[6]) + + uint64(val.n[5])*uint64(val2.n[5]) + + uint64(val.n[6])*uint64(val2.n[4]) + + uint64(val.n[7])*uint64(val2.n[3]) + + uint64(val.n[8])*uint64(val2.n[2]) + + uint64(val.n[9])*uint64(val2.n[1]) + t10 := m & fieldBaseMask + + // Terms for 2^(fieldBase*11). + m = (m >> fieldBase) + + uint64(val.n[2])*uint64(val2.n[9]) + + uint64(val.n[3])*uint64(val2.n[8]) + + uint64(val.n[4])*uint64(val2.n[7]) + + uint64(val.n[5])*uint64(val2.n[6]) + + uint64(val.n[6])*uint64(val2.n[5]) + + uint64(val.n[7])*uint64(val2.n[4]) + + uint64(val.n[8])*uint64(val2.n[3]) + + uint64(val.n[9])*uint64(val2.n[2]) + t11 := m & fieldBaseMask + + // Terms for 2^(fieldBase*12). + m = (m >> fieldBase) + + uint64(val.n[3])*uint64(val2.n[9]) + + uint64(val.n[4])*uint64(val2.n[8]) + + uint64(val.n[5])*uint64(val2.n[7]) + + uint64(val.n[6])*uint64(val2.n[6]) + + uint64(val.n[7])*uint64(val2.n[5]) + + uint64(val.n[8])*uint64(val2.n[4]) + + uint64(val.n[9])*uint64(val2.n[3]) + t12 := m & fieldBaseMask + + // Terms for 2^(fieldBase*13). + m = (m >> fieldBase) + + uint64(val.n[4])*uint64(val2.n[9]) + + uint64(val.n[5])*uint64(val2.n[8]) + + uint64(val.n[6])*uint64(val2.n[7]) + + uint64(val.n[7])*uint64(val2.n[6]) + + uint64(val.n[8])*uint64(val2.n[5]) + + uint64(val.n[9])*uint64(val2.n[4]) + t13 := m & fieldBaseMask + + // Terms for 2^(fieldBase*14). + m = (m >> fieldBase) + + uint64(val.n[5])*uint64(val2.n[9]) + + uint64(val.n[6])*uint64(val2.n[8]) + + uint64(val.n[7])*uint64(val2.n[7]) + + uint64(val.n[8])*uint64(val2.n[6]) + + uint64(val.n[9])*uint64(val2.n[5]) + t14 := m & fieldBaseMask + + // Terms for 2^(fieldBase*15). + m = (m >> fieldBase) + + uint64(val.n[6])*uint64(val2.n[9]) + + uint64(val.n[7])*uint64(val2.n[8]) + + uint64(val.n[8])*uint64(val2.n[7]) + + uint64(val.n[9])*uint64(val2.n[6]) + t15 := m & fieldBaseMask + + // Terms for 2^(fieldBase*16). + m = (m >> fieldBase) + + uint64(val.n[7])*uint64(val2.n[9]) + + uint64(val.n[8])*uint64(val2.n[8]) + + uint64(val.n[9])*uint64(val2.n[7]) + t16 := m & fieldBaseMask + + // Terms for 2^(fieldBase*17). + m = (m >> fieldBase) + + uint64(val.n[8])*uint64(val2.n[9]) + + uint64(val.n[9])*uint64(val2.n[8]) + t17 := m & fieldBaseMask + + // Terms for 2^(fieldBase*18). + m = (m >> fieldBase) + uint64(val.n[9])*uint64(val2.n[9]) + t18 := m & fieldBaseMask + + // What's left is for 2^(fieldBase*19). + t19 := m >> fieldBase + + // At this point, all of the terms are grouped into their respective + // base. + // + // Per [HAC] section 14.3.4: Reduction method of moduli of special form, + // when the modulus is of the special form m = b^t - c, highly efficient + // reduction can be achieved per the provided algorithm. + // + // The secp256k1 prime is equivalent to 2^256 - 4294968273, so it fits + // this criteria. + // + // 4294968273 in field representation (base 2^26) is: + // n[0] = 977 + // n[1] = 64 + // That is to say (2^26 * 64) + 977 = 4294968273 + // + // Since each word is in base 26, the upper terms (t10 and up) start + // at 260 bits (versus the final desired range of 256 bits), so the + // field representation of 'c' from above needs to be adjusted for the + // extra 4 bits by multiplying it by 2^4 = 16. 4294968273 * 16 = + // 68719492368. Thus, the adjusted field representation of 'c' is: + // n[0] = 977 * 16 = 15632 + // n[1] = 64 * 16 = 1024 + // That is to say (2^26 * 1024) + 15632 = 68719492368 + // + // To reduce the final term, t19, the entire 'c' value is needed instead + // of only n[0] because there are no more terms left to handle n[1]. + // This means there might be some magnitude left in the upper bits that + // is handled below. + m = t0 + t10*15632 + t0 = m & fieldBaseMask + m = (m >> fieldBase) + t1 + t10*1024 + t11*15632 + t1 = m & fieldBaseMask + m = (m >> fieldBase) + t2 + t11*1024 + t12*15632 + t2 = m & fieldBaseMask + m = (m >> fieldBase) + t3 + t12*1024 + t13*15632 + t3 = m & fieldBaseMask + m = (m >> fieldBase) + t4 + t13*1024 + t14*15632 + t4 = m & fieldBaseMask + m = (m >> fieldBase) + t5 + t14*1024 + t15*15632 + t5 = m & fieldBaseMask + m = (m >> fieldBase) + t6 + t15*1024 + t16*15632 + t6 = m & fieldBaseMask + m = (m >> fieldBase) + t7 + t16*1024 + t17*15632 + t7 = m & fieldBaseMask + m = (m >> fieldBase) + t8 + t17*1024 + t18*15632 + t8 = m & fieldBaseMask + m = (m >> fieldBase) + t9 + t18*1024 + t19*68719492368 + t9 = m & fieldMSBMask + m >>= fieldMSBBits + + // At this point, if the magnitude is greater than 0, the overall value + // is greater than the max possible 256-bit value. In particular, it is + // "how many times larger" than the max value it is. + // + // The algorithm presented in [HAC] section 14.3.4 repeats until the + // quotient is zero. However, due to the above, we already know at + // least how many times we would need to repeat as it's the value + // currently in m. Thus we can simply multiply the magnitude by the + // field representation of the prime and do a single iteration. Notice + // that nothing will be changed when the magnitude is zero, so we could + // skip this in that case, however always running regardless allows it + // to run in constant time. The final result will be in the range + // 0 <= result <= prime + (2^64 - c), so it is guaranteed to have a + // magnitude of 1, but it is denormalized. + d := t0 + m*977 + f.n[0] = uint32(d & fieldBaseMask) + d = (d >> fieldBase) + t1 + m*64 + f.n[1] = uint32(d & fieldBaseMask) + f.n[2] = uint32((d >> fieldBase) + t2) + f.n[3] = uint32(t3) + f.n[4] = uint32(t4) + f.n[5] = uint32(t5) + f.n[6] = uint32(t6) + f.n[7] = uint32(t7) + f.n[8] = uint32(t8) + f.n[9] = uint32(t9) + + return f +} + +// SquareRootVal either calculates the square root of the passed value when it +// exists or the square root of the negation of the value when it does not exist +// and stores the result in f in constant time. The return flag is true when +// the calculated square root is for the passed value itself and false when it +// is for its negation. +// +// Note that this function can overflow if multiplying any of the individual +// words exceeds a max uint32. In practice, this means the magnitude of the +// field must be a max of 8 to prevent overflow. The magnitude of the result +// will be 1. +// +// Preconditions: +// - The input field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) SquareRootVal(val *FieldVal) bool { + // This uses the Tonelli-Shanks method for calculating the square root of + // the value when it exists. The key principles of the method follow. + // + // Fermat's little theorem states that for a nonzero number 'a' and prime + // 'p', a^(p-1) ≡ 1 (mod p). + // + // Further, Euler's criterion states that an integer 'a' has a square root + // (aka is a quadratic residue) modulo a prime if a^((p-1)/2) ≡ 1 (mod p) + // and, conversely, when it does NOT have a square root (aka 'a' is a + // non-residue) a^((p-1)/2) ≡ -1 (mod p). + // + // This can be seen by considering that Fermat's little theorem can be + // written as (a^((p-1)/2) - 1)(a^((p-1)/2) + 1) ≡ 0 (mod p). Therefore, + // one of the two factors must be 0. Then, when a ≡ x^2 (aka 'a' is a + // quadratic residue), (x^2)^((p-1)/2) ≡ x^(p-1) ≡ 1 (mod p) which implies + // the first factor must be zero. Finally, per Lagrange's theorem, the + // non-residues are the only remaining possible solutions and thus must make + // the second factor zero to satisfy Fermat's little theorem implying that + // a^((p-1)/2) ≡ -1 (mod p) for that case. + // + // The Tonelli-Shanks method uses these facts along with factoring out + // powers of two to solve a congruence that results in either the solution + // when the square root exists or the square root of the negation of the + // value when it does not. In the case of primes that are ≡ 3 (mod 4), the + // possible solutions are r = ±a^((p+1)/4) (mod p). Therefore, either r^2 ≡ + // a (mod p) is true in which case ±r are the two solutions, or r^2 ≡ -a + // (mod p) in which case 'a' is a non-residue and there are no solutions. + // + // The secp256k1 prime is ≡ 3 (mod 4), so this result applies. + // + // In other words, calculate a^((p+1)/4) and then square it and check it + // against the original value to determine if it is actually the square + // root. + // + // In order to efficiently compute a^((p+1)/4), (p+1)/4 needs to be split + // into a sequence of squares and multiplications that minimizes the number + // of multiplications needed (since they are more costly than squarings). + // + // The secp256k1 prime + 1 / 4 is 2^254 - 2^30 - 244. In binary, that is: + // + // 00111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 10111111 11111111 11111111 00001100 + // + // Notice that can be broken up into three windows of consecutive 1s (in + // order of least to most significant) as: + // + // 6-bit window with two bits set (bits 4, 5, 6, 7 unset) + // 23-bit window with 22 bits set (bit 30 unset) + // 223-bit window with all 223 bits set + // + // Thus, the groups of 1 bits in each window forms the set: + // S = {2, 22, 223}. + // + // The strategy is to calculate a^(2^n - 1) for each grouping via an + // addition chain with a sliding window. + // + // The addition chain used is (credits to Peter Dettman): + // (0,0),(1,0),(2,2),(3,2),(4,1),(5,5),(6,6),(7,7),(8,8),(9,7),(10,2) + // => 2^1 2^[2] 2^3 2^6 2^9 2^11 2^[22] 2^44 2^88 2^176 2^220 2^[223] + // + // This has a cost of 254 field squarings and 13 field multiplications. + var a, a2, a3, a6, a9, a11, a22, a44, a88, a176, a220, a223 FieldVal + a.Set(val) + a2.SquareVal(&a).Mul(&a) // a2 = a^(2^2 - 1) + a3.SquareVal(&a2).Mul(&a) // a3 = a^(2^3 - 1) + a6.SquareVal(&a3).Square().Square() // a6 = a^(2^6 - 2^3) + a6.Mul(&a3) // a6 = a^(2^6 - 1) + a9.SquareVal(&a6).Square().Square() // a9 = a^(2^9 - 2^3) + a9.Mul(&a3) // a9 = a^(2^9 - 1) + a11.SquareVal(&a9).Square() // a11 = a^(2^11 - 2^2) + a11.Mul(&a2) // a11 = a^(2^11 - 1) + a22.SquareVal(&a11).Square().Square().Square().Square() // a22 = a^(2^16 - 2^5) + a22.Square().Square().Square().Square().Square() // a22 = a^(2^21 - 2^10) + a22.Square() // a22 = a^(2^22 - 2^11) + a22.Mul(&a11) // a22 = a^(2^22 - 1) + a44.SquareVal(&a22).Square().Square().Square().Square() // a44 = a^(2^27 - 2^5) + a44.Square().Square().Square().Square().Square() // a44 = a^(2^32 - 2^10) + a44.Square().Square().Square().Square().Square() // a44 = a^(2^37 - 2^15) + a44.Square().Square().Square().Square().Square() // a44 = a^(2^42 - 2^20) + a44.Square().Square() // a44 = a^(2^44 - 2^22) + a44.Mul(&a22) // a44 = a^(2^44 - 1) + a88.SquareVal(&a44).Square().Square().Square().Square() // a88 = a^(2^49 - 2^5) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^54 - 2^10) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^59 - 2^15) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^64 - 2^20) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^69 - 2^25) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^74 - 2^30) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^79 - 2^35) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^84 - 2^40) + a88.Square().Square().Square().Square() // a88 = a^(2^88 - 2^44) + a88.Mul(&a44) // a88 = a^(2^88 - 1) + a176.SquareVal(&a88).Square().Square().Square().Square() // a176 = a^(2^93 - 2^5) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^98 - 2^10) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^103 - 2^15) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^108 - 2^20) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^113 - 2^25) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^118 - 2^30) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^123 - 2^35) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^128 - 2^40) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^133 - 2^45) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^138 - 2^50) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^143 - 2^55) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^148 - 2^60) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^153 - 2^65) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^158 - 2^70) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^163 - 2^75) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^168 - 2^80) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^173 - 2^85) + a176.Square().Square().Square() // a176 = a^(2^176 - 2^88) + a176.Mul(&a88) // a176 = a^(2^176 - 1) + a220.SquareVal(&a176).Square().Square().Square().Square() // a220 = a^(2^181 - 2^5) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^186 - 2^10) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^191 - 2^15) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^196 - 2^20) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^201 - 2^25) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^206 - 2^30) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^211 - 2^35) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^216 - 2^40) + a220.Square().Square().Square().Square() // a220 = a^(2^220 - 2^44) + a220.Mul(&a44) // a220 = a^(2^220 - 1) + a223.SquareVal(&a220).Square().Square() // a223 = a^(2^223 - 2^3) + a223.Mul(&a3) // a223 = a^(2^223 - 1) + + f.SquareVal(&a223).Square().Square().Square().Square() // f = a^(2^228 - 2^5) + f.Square().Square().Square().Square().Square() // f = a^(2^233 - 2^10) + f.Square().Square().Square().Square().Square() // f = a^(2^238 - 2^15) + f.Square().Square().Square().Square().Square() // f = a^(2^243 - 2^20) + f.Square().Square().Square() // f = a^(2^246 - 2^23) + f.Mul(&a22) // f = a^(2^246 - 2^22 - 1) + f.Square().Square().Square().Square().Square() // f = a^(2^251 - 2^27 - 2^5) + f.Square() // f = a^(2^252 - 2^28 - 2^6) + f.Mul(&a2) // f = a^(2^252 - 2^28 - 2^6 - 2^1 - 1) + f.Square().Square() // f = a^(2^254 - 2^30 - 2^8 - 2^3 - 2^2) + // // = a^(2^254 - 2^30 - 244) + // // = a^((p+1)/4) + + // Ensure the calculated result is actually the square root by squaring it + // and checking against the original value. + var sqr FieldVal + return sqr.SquareVal(f).Normalize().Equals(val.Normalize()) +} + +// Square squares the field value in constant time. The existing field value is +// modified. Note that this function can overflow if multiplying any of the +// individual words exceeds a max uint32. In practice, this means the magnitude +// of the field must be a max of 8 to prevent overflow. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Square().Mul(f2) so that f = f^2 * f2. +// +// Preconditions: +// - The field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) Square() *FieldVal { + return f.SquareVal(f) +} + +// SquareVal squares the passed value and stores the result in f in constant +// time. Note that this function can overflow if multiplying any of the +// individual words exceeds a max uint32. In practice, this means the magnitude +// of the field being squared must be a max of 8 to prevent overflow. +// +// The field value is returned to support chaining. This enables syntax like: +// f3.SquareVal(f).Mul(f) so that f3 = f^2 * f = f^3. +// +// Preconditions: +// - The input field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) SquareVal(val *FieldVal) *FieldVal { + // This could be done with a couple of for loops and an array to store + // the intermediate terms, but this unrolled version is significantly + // faster. + + // Terms for 2^(fieldBase*0). + m := uint64(val.n[0]) * uint64(val.n[0]) + t0 := m & fieldBaseMask + + // Terms for 2^(fieldBase*1). + m = (m >> fieldBase) + 2*uint64(val.n[0])*uint64(val.n[1]) + t1 := m & fieldBaseMask + + // Terms for 2^(fieldBase*2). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[2]) + + uint64(val.n[1])*uint64(val.n[1]) + t2 := m & fieldBaseMask + + // Terms for 2^(fieldBase*3). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[3]) + + 2*uint64(val.n[1])*uint64(val.n[2]) + t3 := m & fieldBaseMask + + // Terms for 2^(fieldBase*4). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[4]) + + 2*uint64(val.n[1])*uint64(val.n[3]) + + uint64(val.n[2])*uint64(val.n[2]) + t4 := m & fieldBaseMask + + // Terms for 2^(fieldBase*5). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[5]) + + 2*uint64(val.n[1])*uint64(val.n[4]) + + 2*uint64(val.n[2])*uint64(val.n[3]) + t5 := m & fieldBaseMask + + // Terms for 2^(fieldBase*6). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[6]) + + 2*uint64(val.n[1])*uint64(val.n[5]) + + 2*uint64(val.n[2])*uint64(val.n[4]) + + uint64(val.n[3])*uint64(val.n[3]) + t6 := m & fieldBaseMask + + // Terms for 2^(fieldBase*7). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[7]) + + 2*uint64(val.n[1])*uint64(val.n[6]) + + 2*uint64(val.n[2])*uint64(val.n[5]) + + 2*uint64(val.n[3])*uint64(val.n[4]) + t7 := m & fieldBaseMask + + // Terms for 2^(fieldBase*8). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[8]) + + 2*uint64(val.n[1])*uint64(val.n[7]) + + 2*uint64(val.n[2])*uint64(val.n[6]) + + 2*uint64(val.n[3])*uint64(val.n[5]) + + uint64(val.n[4])*uint64(val.n[4]) + t8 := m & fieldBaseMask + + // Terms for 2^(fieldBase*9). + m = (m >> fieldBase) + + 2*uint64(val.n[0])*uint64(val.n[9]) + + 2*uint64(val.n[1])*uint64(val.n[8]) + + 2*uint64(val.n[2])*uint64(val.n[7]) + + 2*uint64(val.n[3])*uint64(val.n[6]) + + 2*uint64(val.n[4])*uint64(val.n[5]) + t9 := m & fieldBaseMask + + // Terms for 2^(fieldBase*10). + m = (m >> fieldBase) + + 2*uint64(val.n[1])*uint64(val.n[9]) + + 2*uint64(val.n[2])*uint64(val.n[8]) + + 2*uint64(val.n[3])*uint64(val.n[7]) + + 2*uint64(val.n[4])*uint64(val.n[6]) + + uint64(val.n[5])*uint64(val.n[5]) + t10 := m & fieldBaseMask + + // Terms for 2^(fieldBase*11). + m = (m >> fieldBase) + + 2*uint64(val.n[2])*uint64(val.n[9]) + + 2*uint64(val.n[3])*uint64(val.n[8]) + + 2*uint64(val.n[4])*uint64(val.n[7]) + + 2*uint64(val.n[5])*uint64(val.n[6]) + t11 := m & fieldBaseMask + + // Terms for 2^(fieldBase*12). + m = (m >> fieldBase) + + 2*uint64(val.n[3])*uint64(val.n[9]) + + 2*uint64(val.n[4])*uint64(val.n[8]) + + 2*uint64(val.n[5])*uint64(val.n[7]) + + uint64(val.n[6])*uint64(val.n[6]) + t12 := m & fieldBaseMask + + // Terms for 2^(fieldBase*13). + m = (m >> fieldBase) + + 2*uint64(val.n[4])*uint64(val.n[9]) + + 2*uint64(val.n[5])*uint64(val.n[8]) + + 2*uint64(val.n[6])*uint64(val.n[7]) + t13 := m & fieldBaseMask + + // Terms for 2^(fieldBase*14). + m = (m >> fieldBase) + + 2*uint64(val.n[5])*uint64(val.n[9]) + + 2*uint64(val.n[6])*uint64(val.n[8]) + + uint64(val.n[7])*uint64(val.n[7]) + t14 := m & fieldBaseMask + + // Terms for 2^(fieldBase*15). + m = (m >> fieldBase) + + 2*uint64(val.n[6])*uint64(val.n[9]) + + 2*uint64(val.n[7])*uint64(val.n[8]) + t15 := m & fieldBaseMask + + // Terms for 2^(fieldBase*16). + m = (m >> fieldBase) + + 2*uint64(val.n[7])*uint64(val.n[9]) + + uint64(val.n[8])*uint64(val.n[8]) + t16 := m & fieldBaseMask + + // Terms for 2^(fieldBase*17). + m = (m >> fieldBase) + 2*uint64(val.n[8])*uint64(val.n[9]) + t17 := m & fieldBaseMask + + // Terms for 2^(fieldBase*18). + m = (m >> fieldBase) + uint64(val.n[9])*uint64(val.n[9]) + t18 := m & fieldBaseMask + + // What's left is for 2^(fieldBase*19). + t19 := m >> fieldBase + + // At this point, all of the terms are grouped into their respective + // base. + // + // Per [HAC] section 14.3.4: Reduction method of moduli of special form, + // when the modulus is of the special form m = b^t - c, highly efficient + // reduction can be achieved per the provided algorithm. + // + // The secp256k1 prime is equivalent to 2^256 - 4294968273, so it fits + // this criteria. + // + // 4294968273 in field representation (base 2^26) is: + // n[0] = 977 + // n[1] = 64 + // That is to say (2^26 * 64) + 977 = 4294968273 + // + // Since each word is in base 26, the upper terms (t10 and up) start + // at 260 bits (versus the final desired range of 256 bits), so the + // field representation of 'c' from above needs to be adjusted for the + // extra 4 bits by multiplying it by 2^4 = 16. 4294968273 * 16 = + // 68719492368. Thus, the adjusted field representation of 'c' is: + // n[0] = 977 * 16 = 15632 + // n[1] = 64 * 16 = 1024 + // That is to say (2^26 * 1024) + 15632 = 68719492368 + // + // To reduce the final term, t19, the entire 'c' value is needed instead + // of only n[0] because there are no more terms left to handle n[1]. + // This means there might be some magnitude left in the upper bits that + // is handled below. + m = t0 + t10*15632 + t0 = m & fieldBaseMask + m = (m >> fieldBase) + t1 + t10*1024 + t11*15632 + t1 = m & fieldBaseMask + m = (m >> fieldBase) + t2 + t11*1024 + t12*15632 + t2 = m & fieldBaseMask + m = (m >> fieldBase) + t3 + t12*1024 + t13*15632 + t3 = m & fieldBaseMask + m = (m >> fieldBase) + t4 + t13*1024 + t14*15632 + t4 = m & fieldBaseMask + m = (m >> fieldBase) + t5 + t14*1024 + t15*15632 + t5 = m & fieldBaseMask + m = (m >> fieldBase) + t6 + t15*1024 + t16*15632 + t6 = m & fieldBaseMask + m = (m >> fieldBase) + t7 + t16*1024 + t17*15632 + t7 = m & fieldBaseMask + m = (m >> fieldBase) + t8 + t17*1024 + t18*15632 + t8 = m & fieldBaseMask + m = (m >> fieldBase) + t9 + t18*1024 + t19*68719492368 + t9 = m & fieldMSBMask + m >>= fieldMSBBits + + // At this point, if the magnitude is greater than 0, the overall value + // is greater than the max possible 256-bit value. In particular, it is + // "how many times larger" than the max value it is. + // + // The algorithm presented in [HAC] section 14.3.4 repeats until the + // quotient is zero. However, due to the above, we already know at + // least how many times we would need to repeat as it's the value + // currently in m. Thus we can simply multiply the magnitude by the + // field representation of the prime and do a single iteration. Notice + // that nothing will be changed when the magnitude is zero, so we could + // skip this in that case, however always running regardless allows it + // to run in constant time. The final result will be in the range + // 0 <= result <= prime + (2^64 - c), so it is guaranteed to have a + // magnitude of 1, but it is denormalized. + n := t0 + m*977 + f.n[0] = uint32(n & fieldBaseMask) + n = (n >> fieldBase) + t1 + m*64 + f.n[1] = uint32(n & fieldBaseMask) + f.n[2] = uint32((n >> fieldBase) + t2) + f.n[3] = uint32(t3) + f.n[4] = uint32(t4) + f.n[5] = uint32(t5) + f.n[6] = uint32(t6) + f.n[7] = uint32(t7) + f.n[8] = uint32(t8) + f.n[9] = uint32(t9) + + return f +} + +// Inverse finds the modular multiplicative inverse of the field value in +// constant time. The existing field value is modified. +// +// The field value is returned to support chaining. This enables syntax like: +// f.Inverse().Mul(f2) so that f = f^-1 * f2. +// +// Preconditions: +// - The field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 +func (f *FieldVal) Inverse() *FieldVal { + // Fermat's little theorem states that for a nonzero number 'a' and prime + // 'p', a^(p-1) ≡ 1 (mod p). Multiplying both sides of the equation by the + // multiplicative inverse a^-1 yields a^(p-2) ≡ a^-1 (mod p). Thus, a^(p-2) + // is the multiplicative inverse. + // + // In order to efficiently compute a^(p-2), p-2 needs to be split into a + // sequence of squares and multiplications that minimizes the number of + // multiplications needed (since they are more costly than squarings). + // Intermediate results are saved and reused as well. + // + // The secp256k1 prime - 2 is 2^256 - 4294968275. In binary, that is: + // + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111111 + // 11111111 11111111 11111111 11111110 + // 11111111 11111111 11111100 00101101 + // + // Notice that can be broken up into five windows of consecutive 1s (in + // order of least to most significant) as: + // + // 2-bit window with 1 bit set (bit 1 unset) + // 3-bit window with 2 bits set (bit 4 unset) + // 5-bit window with 1 bit set (bits 6, 7, 8, 9 unset) + // 23-bit window with 22 bits set (bit 32 unset) + // 223-bit window with all 223 bits set + // + // Thus, the groups of 1 bits in each window forms the set: + // S = {1, 2, 22, 223}. + // + // The strategy is to calculate a^(2^n - 1) for each grouping via an + // addition chain with a sliding window. + // + // The addition chain used is (credits to Peter Dettman): + // (0,0),(1,0),(2,2),(3,2),(4,1),(5,5),(6,6),(7,7),(8,8),(9,7),(10,2) + // => 2^[1] 2^[2] 2^3 2^6 2^9 2^11 2^[22] 2^44 2^88 2^176 2^220 2^[223] + // + // This has a cost of 255 field squarings and 15 field multiplications. + var a, a2, a3, a6, a9, a11, a22, a44, a88, a176, a220, a223 FieldVal + a.Set(f) + a2.SquareVal(&a).Mul(&a) // a2 = a^(2^2 - 1) + a3.SquareVal(&a2).Mul(&a) // a3 = a^(2^3 - 1) + a6.SquareVal(&a3).Square().Square() // a6 = a^(2^6 - 2^3) + a6.Mul(&a3) // a6 = a^(2^6 - 1) + a9.SquareVal(&a6).Square().Square() // a9 = a^(2^9 - 2^3) + a9.Mul(&a3) // a9 = a^(2^9 - 1) + a11.SquareVal(&a9).Square() // a11 = a^(2^11 - 2^2) + a11.Mul(&a2) // a11 = a^(2^11 - 1) + a22.SquareVal(&a11).Square().Square().Square().Square() // a22 = a^(2^16 - 2^5) + a22.Square().Square().Square().Square().Square() // a22 = a^(2^21 - 2^10) + a22.Square() // a22 = a^(2^22 - 2^11) + a22.Mul(&a11) // a22 = a^(2^22 - 1) + a44.SquareVal(&a22).Square().Square().Square().Square() // a44 = a^(2^27 - 2^5) + a44.Square().Square().Square().Square().Square() // a44 = a^(2^32 - 2^10) + a44.Square().Square().Square().Square().Square() // a44 = a^(2^37 - 2^15) + a44.Square().Square().Square().Square().Square() // a44 = a^(2^42 - 2^20) + a44.Square().Square() // a44 = a^(2^44 - 2^22) + a44.Mul(&a22) // a44 = a^(2^44 - 1) + a88.SquareVal(&a44).Square().Square().Square().Square() // a88 = a^(2^49 - 2^5) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^54 - 2^10) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^59 - 2^15) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^64 - 2^20) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^69 - 2^25) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^74 - 2^30) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^79 - 2^35) + a88.Square().Square().Square().Square().Square() // a88 = a^(2^84 - 2^40) + a88.Square().Square().Square().Square() // a88 = a^(2^88 - 2^44) + a88.Mul(&a44) // a88 = a^(2^88 - 1) + a176.SquareVal(&a88).Square().Square().Square().Square() // a176 = a^(2^93 - 2^5) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^98 - 2^10) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^103 - 2^15) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^108 - 2^20) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^113 - 2^25) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^118 - 2^30) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^123 - 2^35) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^128 - 2^40) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^133 - 2^45) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^138 - 2^50) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^143 - 2^55) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^148 - 2^60) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^153 - 2^65) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^158 - 2^70) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^163 - 2^75) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^168 - 2^80) + a176.Square().Square().Square().Square().Square() // a176 = a^(2^173 - 2^85) + a176.Square().Square().Square() // a176 = a^(2^176 - 2^88) + a176.Mul(&a88) // a176 = a^(2^176 - 1) + a220.SquareVal(&a176).Square().Square().Square().Square() // a220 = a^(2^181 - 2^5) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^186 - 2^10) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^191 - 2^15) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^196 - 2^20) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^201 - 2^25) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^206 - 2^30) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^211 - 2^35) + a220.Square().Square().Square().Square().Square() // a220 = a^(2^216 - 2^40) + a220.Square().Square().Square().Square() // a220 = a^(2^220 - 2^44) + a220.Mul(&a44) // a220 = a^(2^220 - 1) + a223.SquareVal(&a220).Square().Square() // a223 = a^(2^223 - 2^3) + a223.Mul(&a3) // a223 = a^(2^223 - 1) + + f.SquareVal(&a223).Square().Square().Square().Square() // f = a^(2^228 - 2^5) + f.Square().Square().Square().Square().Square() // f = a^(2^233 - 2^10) + f.Square().Square().Square().Square().Square() // f = a^(2^238 - 2^15) + f.Square().Square().Square().Square().Square() // f = a^(2^243 - 2^20) + f.Square().Square().Square() // f = a^(2^246 - 2^23) + f.Mul(&a22) // f = a^(2^246 - 4194305) + f.Square().Square().Square().Square().Square() // f = a^(2^251 - 134217760) + f.Mul(&a) // f = a^(2^251 - 134217759) + f.Square().Square().Square() // f = a^(2^254 - 1073742072) + f.Mul(&a2) // f = a^(2^254 - 1073742069) + f.Square().Square() // f = a^(2^256 - 4294968276) + return f.Mul(&a) // f = a^(2^256 - 4294968275) = a^(p-2) +} + +// IsGtOrEqPrimeMinusOrder returns whether or not the field value is greater +// than or equal to the field prime minus the secp256k1 group order in constant +// time. +// +// Preconditions: +// - The field value MUST be normalized +func (f *FieldVal) IsGtOrEqPrimeMinusOrder() bool { + // The secp256k1 prime is equivalent to 2^256 - 4294968273 and the group + // order is 2^256 - 432420386565659656852420866394968145599. Thus, + // the prime minus the group order is: + // 432420386565659656852420866390673177326 + // + // In hex that is: + // 0x00000000 00000000 00000000 00000001 45512319 50b75fc4 402da172 2fc9baee + // + // Converting that to field representation (base 2^26) is: + // + // n[0] = 0x03c9baee + // n[1] = 0x03685c8b + // n[2] = 0x01fc4402 + // n[3] = 0x006542dd + // n[4] = 0x01455123 + // + // This can be verified with the following test code: + // pMinusN := new(big.Int).Sub(curveParams.P, curveParams.N) + // var fv FieldVal + // fv.SetByteSlice(pMinusN.Bytes()) + // t.Logf("%x", fv.n) + // + // Outputs: [3c9baee 3685c8b 1fc4402 6542dd 1455123 0 0 0 0 0] + const ( + pMinusNWordZero = 0x03c9baee + pMinusNWordOne = 0x03685c8b + pMinusNWordTwo = 0x01fc4402 + pMinusNWordThree = 0x006542dd + pMinusNWordFour = 0x01455123 + pMinusNWordFive = 0x00000000 + pMinusNWordSix = 0x00000000 + pMinusNWordSeven = 0x00000000 + pMinusNWordEight = 0x00000000 + pMinusNWordNine = 0x00000000 + ) + + // The intuition here is that the value is greater than field prime minus + // the group order if one of the higher individual words is greater than the + // corresponding word and all higher words in the value are equal. + result := constantTimeGreater(f.n[9], pMinusNWordNine) + highWordsEqual := constantTimeEq(f.n[9], pMinusNWordNine) + result |= highWordsEqual & constantTimeGreater(f.n[8], pMinusNWordEight) + highWordsEqual &= constantTimeEq(f.n[8], pMinusNWordEight) + result |= highWordsEqual & constantTimeGreater(f.n[7], pMinusNWordSeven) + highWordsEqual &= constantTimeEq(f.n[7], pMinusNWordSeven) + result |= highWordsEqual & constantTimeGreater(f.n[6], pMinusNWordSix) + highWordsEqual &= constantTimeEq(f.n[6], pMinusNWordSix) + result |= highWordsEqual & constantTimeGreater(f.n[5], pMinusNWordFive) + highWordsEqual &= constantTimeEq(f.n[5], pMinusNWordFive) + result |= highWordsEqual & constantTimeGreater(f.n[4], pMinusNWordFour) + highWordsEqual &= constantTimeEq(f.n[4], pMinusNWordFour) + result |= highWordsEqual & constantTimeGreater(f.n[3], pMinusNWordThree) + highWordsEqual &= constantTimeEq(f.n[3], pMinusNWordThree) + result |= highWordsEqual & constantTimeGreater(f.n[2], pMinusNWordTwo) + highWordsEqual &= constantTimeEq(f.n[2], pMinusNWordTwo) + result |= highWordsEqual & constantTimeGreater(f.n[1], pMinusNWordOne) + highWordsEqual &= constantTimeEq(f.n[1], pMinusNWordOne) + result |= highWordsEqual & constantTimeGreaterOrEq(f.n[0], pMinusNWordZero) + + return result != 0 +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go new file mode 100644 index 0000000000..91c3d37769 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go @@ -0,0 +1,91 @@ +// Copyright 2015 The btcsuite developers +// Copyright (c) 2015-2022 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + "compress/zlib" + "encoding/base64" + "io" + "strings" + "sync" +) + +//go:generate go run genprecomps.go + +// bytePointTable describes a table used to house pre-computed values for +// accelerating scalar base multiplication. +type bytePointTable [32][256]JacobianPoint + +// compressedBytePointsFn is set to a real function by the code generation to +// return the compressed pre-computed values for accelerating scalar base +// multiplication. +var compressedBytePointsFn func() string + +// s256BytePoints houses pre-computed values used to accelerate scalar base +// multiplication such that they are only loaded on first use. +var s256BytePoints = func() func() *bytePointTable { + // mustLoadBytePoints decompresses and deserializes the pre-computed byte + // points used to accelerate scalar base multiplication for the secp256k1 + // curve. + // + // This approach is used since it allows the compile to use significantly + // less ram and be performed much faster than it is with hard-coding the + // final in-memory data structure. At the same time, it is quite fast to + // generate the in-memory data structure on first use with this approach + // versus computing the table. + // + // It will panic on any errors because the data is hard coded and thus any + // errors means something is wrong in the source code. + var data *bytePointTable + mustLoadBytePoints := func() { + // There will be no byte points to load when generating them. + if compressedBytePointsFn == nil { + return + } + bp := compressedBytePointsFn() + + // Decompress the pre-computed table used to accelerate scalar base + // multiplication. + decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(bp)) + r, err := zlib.NewReader(decoder) + if err != nil { + panic(err) + } + serialized, err := io.ReadAll(r) + if err != nil { + panic(err) + } + + // Deserialize the precomputed byte points and set the memory table to + // them. + offset := 0 + var bytePoints bytePointTable + for byteNum := 0; byteNum < len(bytePoints); byteNum++ { + // All points in this window. + for i := 0; i < len(bytePoints[byteNum]); i++ { + p := &bytePoints[byteNum][i] + p.X.SetByteSlice(serialized[offset:]) + offset += 32 + p.Y.SetByteSlice(serialized[offset:]) + offset += 32 + p.Z.SetInt(1) + } + } + data = &bytePoints + } + + // Return a closure that initializes the data on first access. This is done + // because the table takes a non-trivial amount of memory and initializing + // it unconditionally would cause anything that imports the package, either + // directly, or indirectly via transitive deps, to use that memory even if + // the caller never accesses any parts of the package that actually needs + // access to it. + var loadBytePointsOnce sync.Once + return func() *bytePointTable { + loadBytePointsOnce.Do(mustLoadBytePoints) + return data + } +}() diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go new file mode 100644 index 0000000000..225016d8de --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go @@ -0,0 +1,1105 @@ +// Copyright (c) 2020-2024 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + "encoding/hex" + "math/big" +) + +// References: +// [SECG]: Recommended Elliptic Curve Domain Parameters +// https://www.secg.org/sec2-v2.pdf +// +// [HAC]: Handbook of Applied Cryptography Menezes, van Oorschot, Vanstone. +// http://cacr.uwaterloo.ca/hac/ + +// Many elliptic curve operations require working with scalars in a finite field +// characterized by the order of the group underlying the secp256k1 curve. +// Given this precision is larger than the biggest available native type, +// obviously some form of bignum math is needed. This code implements +// specialized fixed-precision field arithmetic rather than relying on an +// arbitrary-precision arithmetic package such as math/big for dealing with the +// math modulo the group order since the size is known. As a result, rather +// large performance gains are achieved by taking advantage of many +// optimizations not available to arbitrary-precision arithmetic and generic +// modular arithmetic algorithms. +// +// There are various ways to internally represent each element. For example, +// the most obvious representation would be to use an array of 4 uint64s (64 +// bits * 4 = 256 bits). However, that representation suffers from the fact +// that there is no native Go type large enough to handle the intermediate +// results while adding or multiplying two 64-bit numbers. +// +// Given the above, this implementation represents the field elements as 8 +// uint32s with each word (array entry) treated as base 2^32. This was chosen +// because most systems at the current time are 64-bit (or at least have 64-bit +// registers available for specialized purposes such as MMX) so the intermediate +// results can typically be done using a native register (and using uint64s to +// avoid the need for additional half-word arithmetic) + +const ( + // These fields provide convenient access to each of the words of the + // secp256k1 curve group order N to improve code readability. + // + // The group order of the curve per [SECG] is: + // 0xffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141 + // + // nolint: dupword + orderWordZero uint32 = 0xd0364141 + orderWordOne uint32 = 0xbfd25e8c + orderWordTwo uint32 = 0xaf48a03b + orderWordThree uint32 = 0xbaaedce6 + orderWordFour uint32 = 0xfffffffe + orderWordFive uint32 = 0xffffffff + orderWordSix uint32 = 0xffffffff + orderWordSeven uint32 = 0xffffffff + + // These fields provide convenient access to each of the words of the two's + // complement of the secp256k1 curve group order N to improve code + // readability. + // + // The two's complement of the group order is: + // 0x00000000 00000000 00000000 00000001 45512319 50b75fc4 402da173 2fc9bebf + orderComplementWordZero uint32 = (^orderWordZero) + 1 + orderComplementWordOne uint32 = ^orderWordOne + orderComplementWordTwo uint32 = ^orderWordTwo + orderComplementWordThree uint32 = ^orderWordThree + // orderComplementWordFour uint32 = ^orderWordFour // unused + // orderComplementWordFive uint32 = ^orderWordFive // unused + // orderComplementWordSix uint32 = ^orderWordSix // unused + // orderComplementWordSeven uint32 = ^orderWordSeven // unused + + // These fields provide convenient access to each of the words of the + // secp256k1 curve group order N / 2 to improve code readability and avoid + // the need to recalculate them. + // + // The half order of the secp256k1 curve group is: + // 0x7fffffff ffffffff ffffffff ffffffff 5d576e73 57a4501d dfe92f46 681b20a0 + // + // nolint: dupword + halfOrderWordZero uint32 = 0x681b20a0 + halfOrderWordOne uint32 = 0xdfe92f46 + halfOrderWordTwo uint32 = 0x57a4501d + halfOrderWordThree uint32 = 0x5d576e73 + halfOrderWordFour uint32 = 0xffffffff + halfOrderWordFive uint32 = 0xffffffff + halfOrderWordSix uint32 = 0xffffffff + halfOrderWordSeven uint32 = 0x7fffffff + + // uint32Mask is simply a mask with all bits set for a uint32 and is used to + // improve the readability of the code. + uint32Mask = 0xffffffff +) + +var ( + // zero32 is an array of 32 bytes used for the purposes of zeroing and is + // defined here to avoid extra allocations. + zero32 = [32]byte{} +) + +// ModNScalar implements optimized 256-bit constant-time fixed-precision +// arithmetic over the secp256k1 group order. This means all arithmetic is +// performed modulo: +// +// 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 +// +// It only implements the arithmetic needed for elliptic curve operations, +// however, the operations that are not implemented can typically be worked +// around if absolutely needed. For example, subtraction can be performed by +// adding the negation. +// +// Should it be absolutely necessary, conversion to the standard library +// math/big.Int can be accomplished by using the Bytes method, slicing the +// resulting fixed-size array, and feeding it to big.Int.SetBytes. However, +// that should typically be avoided when possible as conversion to big.Ints +// requires allocations, is not constant time, and is slower when working modulo +// the group order. +type ModNScalar struct { + // The scalar is represented as 8 32-bit integers in base 2^32. + // + // The following depicts the internal representation: + // --------------------------------------------------------- + // | n[7] | n[6] | ... | n[0] | + // | 32 bits | 32 bits | ... | 32 bits | + // | Mult: 2^(32*7) | Mult: 2^(32*6) | ... | Mult: 2^(32*0) | + // --------------------------------------------------------- + // + // For example, consider the number 2^87 + 2^42 + 1. It would be + // represented as: + // n[0] = 1 + // n[1] = 2^10 + // n[2] = 2^23 + // n[3..7] = 0 + // + // The full 256-bit value is then calculated by looping i from 7..0 and + // doing sum(n[i] * 2^(32i)) like so: + // n[7] * 2^(32*7) = 0 * 2^224 = 0 + // n[6] * 2^(32*6) = 0 * 2^192 = 0 + // ... + // n[2] * 2^(32*2) = 2^23 * 2^64 = 2^87 + // n[1] * 2^(32*1) = 2^10 * 2^32 = 2^42 + // n[0] * 2^(32*0) = 1 * 2^0 = 1 + // Sum: 0 + 0 + ... + 2^87 + 2^42 + 1 = 2^87 + 2^42 + 1 + n [8]uint32 +} + +// String returns the scalar as a human-readable hex string. +// +// This is NOT constant time. +func (s ModNScalar) String() string { + b := s.Bytes() + return hex.EncodeToString(b[:]) +} + +// Set sets the scalar equal to a copy of the passed one in constant time. +// +// The scalar is returned to support chaining. This enables syntax like: +// s := new(ModNScalar).Set(s2).Add(1) so that s = s2 + 1 where s2 is not +// modified. +func (s *ModNScalar) Set(val *ModNScalar) *ModNScalar { + *s = *val + return s +} + +// Zero sets the scalar to zero in constant time. A newly created scalar is +// already set to zero. This function can be useful to clear an existing scalar +// for reuse. +func (s *ModNScalar) Zero() { + s.n[0] = 0 + s.n[1] = 0 + s.n[2] = 0 + s.n[3] = 0 + s.n[4] = 0 + s.n[5] = 0 + s.n[6] = 0 + s.n[7] = 0 +} + +// IsZeroBit returns 1 when the scalar is equal to zero or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. See IsZero for the version that returns +// a bool. +func (s *ModNScalar) IsZeroBit() uint32 { + // The scalar can only be zero if no bits are set in any of the words. + bits := s.n[0] | s.n[1] | s.n[2] | s.n[3] | s.n[4] | s.n[5] | s.n[6] | s.n[7] + return constantTimeEq(bits, 0) +} + +// IsZero returns whether or not the scalar is equal to zero in constant time. +func (s *ModNScalar) IsZero() bool { + // The scalar can only be zero if no bits are set in any of the words. + bits := s.n[0] | s.n[1] | s.n[2] | s.n[3] | s.n[4] | s.n[5] | s.n[6] | s.n[7] + return bits == 0 +} + +// SetInt sets the scalar to the passed integer in constant time. This is a +// convenience function since it is fairly common to perform some arithmetic +// with small native integers. +// +// The scalar is returned to support chaining. This enables syntax like: +// s := new(ModNScalar).SetInt(2).Mul(s2) so that s = 2 * s2. +func (s *ModNScalar) SetInt(ui uint32) *ModNScalar { + s.Zero() + s.n[0] = ui + return s +} + +// constantTimeEq returns 1 if a == b or 0 otherwise in constant time. +func constantTimeEq(a, b uint32) uint32 { + return uint32((uint64(a^b) - 1) >> 63) +} + +// constantTimeNotEq returns 1 if a != b or 0 otherwise in constant time. +func constantTimeNotEq(a, b uint32) uint32 { + return ^uint32((uint64(a^b)-1)>>63) & 1 +} + +// constantTimeLess returns 1 if a < b or 0 otherwise in constant time. +func constantTimeLess(a, b uint32) uint32 { + return uint32((uint64(a) - uint64(b)) >> 63) +} + +// constantTimeLessOrEq returns 1 if a <= b or 0 otherwise in constant time. +func constantTimeLessOrEq(a, b uint32) uint32 { + return uint32((uint64(a) - uint64(b) - 1) >> 63) +} + +// constantTimeGreater returns 1 if a > b or 0 otherwise in constant time. +func constantTimeGreater(a, b uint32) uint32 { + return constantTimeLess(b, a) +} + +// constantTimeGreaterOrEq returns 1 if a >= b or 0 otherwise in constant time. +func constantTimeGreaterOrEq(a, b uint32) uint32 { + return constantTimeLessOrEq(b, a) +} + +// constantTimeMin returns min(a,b) in constant time. +func constantTimeMin(a, b uint32) uint32 { + return b ^ ((a ^ b) & -constantTimeLess(a, b)) +} + +// overflows determines if the current scalar is greater than or equal to the +// group order in constant time and returns 1 if it is or 0 otherwise. +func (s *ModNScalar) overflows() uint32 { + // The intuition here is that the scalar is greater than the group order if + // one of the higher individual words is greater than corresponding word of + // the group order and all higher words in the scalar are equal to their + // corresponding word of the group order. Since this type is modulo the + // group order, being equal is also an overflow back to 0. + // + // Note that the words 5, 6, and 7 are all the max uint32 value, so there is + // no need to test if those individual words of the scalar exceeds them, + // hence, only equality is checked for them. + highWordsEqual := constantTimeEq(s.n[7], orderWordSeven) + highWordsEqual &= constantTimeEq(s.n[6], orderWordSix) + highWordsEqual &= constantTimeEq(s.n[5], orderWordFive) + overflow := highWordsEqual & constantTimeGreater(s.n[4], orderWordFour) + highWordsEqual &= constantTimeEq(s.n[4], orderWordFour) + overflow |= highWordsEqual & constantTimeGreater(s.n[3], orderWordThree) + highWordsEqual &= constantTimeEq(s.n[3], orderWordThree) + overflow |= highWordsEqual & constantTimeGreater(s.n[2], orderWordTwo) + highWordsEqual &= constantTimeEq(s.n[2], orderWordTwo) + overflow |= highWordsEqual & constantTimeGreater(s.n[1], orderWordOne) + highWordsEqual &= constantTimeEq(s.n[1], orderWordOne) + overflow |= highWordsEqual & constantTimeGreaterOrEq(s.n[0], orderWordZero) + + return overflow +} + +// reduce256 reduces the current scalar modulo the group order in accordance +// with the overflows parameter in constant time. The overflows parameter +// specifies whether or not the scalar is known to be greater than the group +// order and MUST either be 1 in the case it is or 0 in the case it is not for a +// correct result. +func (s *ModNScalar) reduce256(overflows uint32) { + // Notice that since s < 2^256 < 2N (where N is the group order), the max + // possible number of reductions required is one. Therefore, in the case a + // reduction is needed, it can be performed with a single subtraction of N. + // Also, recall that subtraction is equivalent to addition by the two's + // complement while ignoring the carry. + // + // When s >= N, the overflows parameter will be 1. Conversely, it will be 0 + // when s < N. Thus multiplying by the overflows parameter will either + // result in 0 or the multiplicand itself. + // + // Combining the above along with the fact that s + 0 = s, the following is + // a constant time implementation that works by either adding 0 or the two's + // complement of N as needed. + // + // The final result will be in the range 0 <= s < N as expected. + overflows64 := uint64(overflows) + c := uint64(s.n[0]) + overflows64*uint64(orderComplementWordZero) + s.n[0] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[1]) + overflows64*uint64(orderComplementWordOne) + s.n[1] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[2]) + overflows64*uint64(orderComplementWordTwo) + s.n[2] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[3]) + overflows64*uint64(orderComplementWordThree) + s.n[3] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[4]) + overflows64 // * 1 + s.n[4] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[5]) // + overflows64 * 0 + s.n[5] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[6]) // + overflows64 * 0 + s.n[6] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(s.n[7]) // + overflows64 * 0 + s.n[7] = uint32(c & uint32Mask) +} + +// SetBytes interprets the provided array as a 256-bit big-endian unsigned +// integer, reduces it modulo the group order, sets the scalar to the result, +// and returns either 1 if it was reduced (aka it overflowed) or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. +func (s *ModNScalar) SetBytes(b *[32]byte) uint32 { + // Pack the 256 total bits across the 8 uint32 words. This could be done + // with a for loop, but benchmarks show this unrolled version is about 2 + // times faster than the variant that uses a loop. + s.n[0] = uint32(b[31]) | uint32(b[30])<<8 | uint32(b[29])<<16 | uint32(b[28])<<24 + s.n[1] = uint32(b[27]) | uint32(b[26])<<8 | uint32(b[25])<<16 | uint32(b[24])<<24 + s.n[2] = uint32(b[23]) | uint32(b[22])<<8 | uint32(b[21])<<16 | uint32(b[20])<<24 + s.n[3] = uint32(b[19]) | uint32(b[18])<<8 | uint32(b[17])<<16 | uint32(b[16])<<24 + s.n[4] = uint32(b[15]) | uint32(b[14])<<8 | uint32(b[13])<<16 | uint32(b[12])<<24 + s.n[5] = uint32(b[11]) | uint32(b[10])<<8 | uint32(b[9])<<16 | uint32(b[8])<<24 + s.n[6] = uint32(b[7]) | uint32(b[6])<<8 | uint32(b[5])<<16 | uint32(b[4])<<24 + s.n[7] = uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 + + // The value might be >= N, so reduce it as required and return whether or + // not it was reduced. + needsReduce := s.overflows() + s.reduce256(needsReduce) + return needsReduce +} + +// zeroArray32 zeroes the provided 32-byte buffer. +func zeroArray32(b *[32]byte) { + copy(b[:], zero32[:]) +} + +// SetByteSlice interprets the provided slice as a 256-bit big-endian unsigned +// integer (meaning it is truncated to the first 32 bytes), reduces it modulo +// the group order, sets the scalar to the result, and returns whether or not +// the resulting truncated 256-bit integer overflowed in constant time. +// +// Note that since passing a slice with more than 32 bytes is truncated, it is +// possible that the truncated value is less than the order of the curve and +// hence it will not be reported as having overflowed in that case. It is up to +// the caller to decide whether it needs to provide numbers of the appropriate +// size or it is acceptable to use this function with the described truncation +// and overflow behavior. +func (s *ModNScalar) SetByteSlice(b []byte) bool { + var b32 [32]byte + b = b[:constantTimeMin(uint32(len(b)), 32)] + copy(b32[:], b32[:32-len(b)]) + copy(b32[32-len(b):], b) + result := s.SetBytes(&b32) + zeroArray32(&b32) + return result != 0 +} + +// PutBytesUnchecked unpacks the scalar to a 32-byte big-endian value directly +// into the passed byte slice in constant time. The target slice must have at +// least 32 bytes available or it will panic. +// +// There is a similar function, PutBytes, which unpacks the scalar into a +// 32-byte array directly. This version is provided since it can be useful to +// write directly into part of a larger buffer without needing a separate +// allocation. +// +// Preconditions: +// - The target slice MUST have at least 32 bytes available +func (s *ModNScalar) PutBytesUnchecked(b []byte) { + // Unpack the 256 total bits from the 8 uint32 words. This could be done + // with a for loop, but benchmarks show this unrolled version is about 2 + // times faster than the variant which uses a loop. + b[31] = byte(s.n[0]) + b[30] = byte(s.n[0] >> 8) + b[29] = byte(s.n[0] >> 16) + b[28] = byte(s.n[0] >> 24) + b[27] = byte(s.n[1]) + b[26] = byte(s.n[1] >> 8) + b[25] = byte(s.n[1] >> 16) + b[24] = byte(s.n[1] >> 24) + b[23] = byte(s.n[2]) + b[22] = byte(s.n[2] >> 8) + b[21] = byte(s.n[2] >> 16) + b[20] = byte(s.n[2] >> 24) + b[19] = byte(s.n[3]) + b[18] = byte(s.n[3] >> 8) + b[17] = byte(s.n[3] >> 16) + b[16] = byte(s.n[3] >> 24) + b[15] = byte(s.n[4]) + b[14] = byte(s.n[4] >> 8) + b[13] = byte(s.n[4] >> 16) + b[12] = byte(s.n[4] >> 24) + b[11] = byte(s.n[5]) + b[10] = byte(s.n[5] >> 8) + b[9] = byte(s.n[5] >> 16) + b[8] = byte(s.n[5] >> 24) + b[7] = byte(s.n[6]) + b[6] = byte(s.n[6] >> 8) + b[5] = byte(s.n[6] >> 16) + b[4] = byte(s.n[6] >> 24) + b[3] = byte(s.n[7]) + b[2] = byte(s.n[7] >> 8) + b[1] = byte(s.n[7] >> 16) + b[0] = byte(s.n[7] >> 24) +} + +// PutBytes unpacks the scalar to a 32-byte big-endian value using the passed +// byte array in constant time. +// +// There is a similar function, PutBytesUnchecked, which unpacks the scalar into +// a slice that must have at least 32 bytes available. This version is provided +// since it can be useful to write directly into an array that is type checked. +// +// Alternatively, there is also Bytes, which unpacks the scalar into a new array +// and returns that which can sometimes be more ergonomic in applications that +// aren't concerned about an additional copy. +func (s *ModNScalar) PutBytes(b *[32]byte) { + s.PutBytesUnchecked(b[:]) +} + +// Bytes unpacks the scalar to a 32-byte big-endian value in constant time. +// +// See PutBytes and PutBytesUnchecked for variants that allow an array or slice +// to be passed which can be useful to cut down on the number of allocations +// by allowing the caller to reuse a buffer or write directly into part of a +// larger buffer. +func (s *ModNScalar) Bytes() [32]byte { + var b [32]byte + s.PutBytesUnchecked(b[:]) + return b +} + +// IsOdd returns whether or not the scalar is an odd number in constant time. +func (s *ModNScalar) IsOdd() bool { + // Only odd numbers have the bottom bit set. + return s.n[0]&1 == 1 +} + +// Equals returns whether or not the two scalars are the same in constant time. +func (s *ModNScalar) Equals(val *ModNScalar) bool { + // Xor only sets bits when they are different, so the two scalars can only + // be the same if no bits are set after xoring each word. + bits := (s.n[0] ^ val.n[0]) | (s.n[1] ^ val.n[1]) | (s.n[2] ^ val.n[2]) | + (s.n[3] ^ val.n[3]) | (s.n[4] ^ val.n[4]) | (s.n[5] ^ val.n[5]) | + (s.n[6] ^ val.n[6]) | (s.n[7] ^ val.n[7]) + + return bits == 0 +} + +// Add2 adds the passed two scalars together modulo the group order in constant +// time and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s3.Add2(s, s2).AddInt(1) so that s3 = s + s2 + 1. +func (s *ModNScalar) Add2(val1, val2 *ModNScalar) *ModNScalar { + c := uint64(val1.n[0]) + uint64(val2.n[0]) + s.n[0] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[1]) + uint64(val2.n[1]) + s.n[1] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[2]) + uint64(val2.n[2]) + s.n[2] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[3]) + uint64(val2.n[3]) + s.n[3] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[4]) + uint64(val2.n[4]) + s.n[4] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[5]) + uint64(val2.n[5]) + s.n[5] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[6]) + uint64(val2.n[6]) + s.n[6] = uint32(c & uint32Mask) + c = (c >> 32) + uint64(val1.n[7]) + uint64(val2.n[7]) + s.n[7] = uint32(c & uint32Mask) + + // The result is now 256 bits, but it might still be >= N, so use the + // existing normal reduce method for 256-bit values. + s.reduce256(uint32(c>>32) + s.overflows()) + return s +} + +// Add adds the passed scalar to the existing one modulo the group order in +// constant time and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Add(s2).AddInt(1) so that s = s + s2 + 1. +func (s *ModNScalar) Add(val *ModNScalar) *ModNScalar { + return s.Add2(s, val) +} + +// accumulator96 provides a 96-bit accumulator for use in the intermediate +// calculations requiring more than 64-bits. +type accumulator96 struct { + n [3]uint32 +} + +// Add adds the passed unsigned 64-bit value to the accumulator. +func (a *accumulator96) Add(v uint64) { + low := uint32(v & uint32Mask) + hi := uint32(v >> 32) + a.n[0] += low + hi += constantTimeLess(a.n[0], low) // Carry if overflow in n[0]. + a.n[1] += hi + a.n[2] += constantTimeLess(a.n[1], hi) // Carry if overflow in n[1]. +} + +// Rsh32 right shifts the accumulator by 32 bits. +func (a *accumulator96) Rsh32() { + a.n[0] = a.n[1] + a.n[1] = a.n[2] + a.n[2] = 0 +} + +// reduce385 reduces the 385-bit intermediate result in the passed terms modulo +// the group order in constant time and stores the result in s. +func (s *ModNScalar) reduce385(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12 uint64) { + // At this point, the intermediate result in the passed terms has been + // reduced to fit within 385 bits, so reduce it again using the same method + // described in reduce512. As before, the intermediate result will end up + // being reduced by another 127 bits to 258 bits, thus 9 32-bit terms are + // needed for this iteration. The reduced terms are assigned back to t0 + // through t8. + // + // Note that several of the intermediate calculations require adding 64-bit + // products together which would overflow a uint64, so a 96-bit accumulator + // is used instead until the value is reduced enough to use native uint64s. + + // Terms for 2^(32*0). + var acc accumulator96 + acc.n[0] = uint32(t0) // == acc.Add(t0) because acc is guaranteed to be 0. + acc.Add(t8 * uint64(orderComplementWordZero)) + t0 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*1). + acc.Add(t1) + acc.Add(t8 * uint64(orderComplementWordOne)) + acc.Add(t9 * uint64(orderComplementWordZero)) + t1 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*2). + acc.Add(t2) + acc.Add(t8 * uint64(orderComplementWordTwo)) + acc.Add(t9 * uint64(orderComplementWordOne)) + acc.Add(t10 * uint64(orderComplementWordZero)) + t2 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*3). + acc.Add(t3) + acc.Add(t8 * uint64(orderComplementWordThree)) + acc.Add(t9 * uint64(orderComplementWordTwo)) + acc.Add(t10 * uint64(orderComplementWordOne)) + acc.Add(t11 * uint64(orderComplementWordZero)) + t3 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*4). + acc.Add(t4) + acc.Add(t8) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t9 * uint64(orderComplementWordThree)) + acc.Add(t10 * uint64(orderComplementWordTwo)) + acc.Add(t11 * uint64(orderComplementWordOne)) + acc.Add(t12 * uint64(orderComplementWordZero)) + t4 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*5). + acc.Add(t5) + // acc.Add(t8 * uint64(orderComplementWordFive)) // 0 + acc.Add(t9) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t10 * uint64(orderComplementWordThree)) + acc.Add(t11 * uint64(orderComplementWordTwo)) + acc.Add(t12 * uint64(orderComplementWordOne)) + t5 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*6). + acc.Add(t6) + // acc.Add(t8 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t9 * uint64(orderComplementWordFive)) // 0 + acc.Add(t10) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t11 * uint64(orderComplementWordThree)) + acc.Add(t12 * uint64(orderComplementWordTwo)) + t6 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*7). + acc.Add(t7) + // acc.Add(t8 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t9 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t10 * uint64(orderComplementWordFive)) // 0 + acc.Add(t11) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t12 * uint64(orderComplementWordThree)) + t7 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*8). + // acc.Add(t9 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t10 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t11 * uint64(orderComplementWordFive)) // 0 + acc.Add(t12) // * uint64(orderComplementWordFour) // * 1 + t8 = uint64(acc.n[0]) + // acc.Rsh32() // No need since not used after this. Guaranteed to be 0. + + // NOTE: All of the remaining multiplications for this iteration result in 0 + // as they all involve multiplying by combinations of the fifth, sixth, and + // seventh words of the two's complement of N, which are 0, so skip them. + + // At this point, the result is reduced to fit within 258 bits, so reduce it + // again using a slightly modified version of the same method. The maximum + // value in t8 is 2 at this point and therefore multiplying it by each word + // of the two's complement of N and adding it to a 32-bit term will result + // in a maximum requirement of 33 bits, so it is safe to use native uint64s + // here for the intermediate term carry propagation. + // + // Also, since the maximum value in t8 is 2, this ends up reducing by + // another 2 bits to 256 bits. + c := t0 + t8*uint64(orderComplementWordZero) + s.n[0] = uint32(c & uint32Mask) + c = (c >> 32) + t1 + t8*uint64(orderComplementWordOne) + s.n[1] = uint32(c & uint32Mask) + c = (c >> 32) + t2 + t8*uint64(orderComplementWordTwo) + s.n[2] = uint32(c & uint32Mask) + c = (c >> 32) + t3 + t8*uint64(orderComplementWordThree) + s.n[3] = uint32(c & uint32Mask) + c = (c >> 32) + t4 + t8 // * uint64(orderComplementWordFour) == * 1 + s.n[4] = uint32(c & uint32Mask) + c = (c >> 32) + t5 // + t8*uint64(orderComplementWordFive) == 0 + s.n[5] = uint32(c & uint32Mask) + c = (c >> 32) + t6 // + t8*uint64(orderComplementWordSix) == 0 + s.n[6] = uint32(c & uint32Mask) + c = (c >> 32) + t7 // + t8*uint64(orderComplementWordSeven) == 0 + s.n[7] = uint32(c & uint32Mask) + + // The result is now 256 bits, but it might still be >= N, so use the + // existing normal reduce method for 256-bit values. + s.reduce256(uint32(c>>32) + s.overflows()) +} + +// reduce512 reduces the 512-bit intermediate result in the passed terms modulo +// the group order down to 385 bits in constant time and stores the result in s. +func (s *ModNScalar) reduce512(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15 uint64) { + // At this point, the intermediate result in the passed terms is grouped + // into the respective bases. + // + // Per [HAC] section 14.3.4: Reduction method of moduli of special form, + // when the modulus is of the special form m = b^t - c, where log_2(c) < t, + // highly efficient reduction can be achieved per the provided algorithm. + // + // The secp256k1 group order fits this criteria since it is: + // 2^256 - 432420386565659656852420866394968145599 + // + // Technically the max possible value here is (N-1)^2 since the two scalars + // being multiplied are always mod N. Nevertheless, it is safer to consider + // it to be (2^256-1)^2 = 2^512 - 2^257 + 1 since it is the product of two + // 256-bit values. + // + // The algorithm is to reduce the result modulo the prime by subtracting + // multiples of the group order N. However, in order simplify carry + // propagation, this adds with the two's complement of N to achieve the same + // result. + // + // Since the two's complement of N has 127 leading zero bits, this will end + // up reducing the intermediate result from 512 bits to 385 bits, resulting + // in 13 32-bit terms. The reduced terms are assigned back to t0 through + // t12. + // + // Note that several of the intermediate calculations require adding 64-bit + // products together which would overflow a uint64, so a 96-bit accumulator + // is used instead. + + // Terms for 2^(32*0). + var acc accumulator96 + acc.n[0] = uint32(t0) // == acc.Add(t0) because acc is guaranteed to be 0. + acc.Add(t8 * uint64(orderComplementWordZero)) + t0 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*1). + acc.Add(t1) + acc.Add(t8 * uint64(orderComplementWordOne)) + acc.Add(t9 * uint64(orderComplementWordZero)) + t1 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*2). + acc.Add(t2) + acc.Add(t8 * uint64(orderComplementWordTwo)) + acc.Add(t9 * uint64(orderComplementWordOne)) + acc.Add(t10 * uint64(orderComplementWordZero)) + t2 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*3). + acc.Add(t3) + acc.Add(t8 * uint64(orderComplementWordThree)) + acc.Add(t9 * uint64(orderComplementWordTwo)) + acc.Add(t10 * uint64(orderComplementWordOne)) + acc.Add(t11 * uint64(orderComplementWordZero)) + t3 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*4). + acc.Add(t4) + acc.Add(t8) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t9 * uint64(orderComplementWordThree)) + acc.Add(t10 * uint64(orderComplementWordTwo)) + acc.Add(t11 * uint64(orderComplementWordOne)) + acc.Add(t12 * uint64(orderComplementWordZero)) + t4 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*5). + acc.Add(t5) + // acc.Add(t8 * uint64(orderComplementWordFive)) // 0 + acc.Add(t9) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t10 * uint64(orderComplementWordThree)) + acc.Add(t11 * uint64(orderComplementWordTwo)) + acc.Add(t12 * uint64(orderComplementWordOne)) + acc.Add(t13 * uint64(orderComplementWordZero)) + t5 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*6). + acc.Add(t6) + // acc.Add(t8 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t9 * uint64(orderComplementWordFive)) // 0 + acc.Add(t10) // * uint64(orderComplementWordFour)) // * 1 + acc.Add(t11 * uint64(orderComplementWordThree)) + acc.Add(t12 * uint64(orderComplementWordTwo)) + acc.Add(t13 * uint64(orderComplementWordOne)) + acc.Add(t14 * uint64(orderComplementWordZero)) + t6 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*7). + acc.Add(t7) + // acc.Add(t8 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t9 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t10 * uint64(orderComplementWordFive)) // 0 + acc.Add(t11) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t12 * uint64(orderComplementWordThree)) + acc.Add(t13 * uint64(orderComplementWordTwo)) + acc.Add(t14 * uint64(orderComplementWordOne)) + acc.Add(t15 * uint64(orderComplementWordZero)) + t7 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*8). + // acc.Add(t9 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t10 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t11 * uint64(orderComplementWordFive)) // 0 + acc.Add(t12) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t13 * uint64(orderComplementWordThree)) + acc.Add(t14 * uint64(orderComplementWordTwo)) + acc.Add(t15 * uint64(orderComplementWordOne)) + t8 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*9). + // acc.Add(t10 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t11 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t12 * uint64(orderComplementWordFive)) // 0 + acc.Add(t13) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t14 * uint64(orderComplementWordThree)) + acc.Add(t15 * uint64(orderComplementWordTwo)) + t9 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*10). + // acc.Add(t11 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t12 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t13 * uint64(orderComplementWordFive)) // 0 + acc.Add(t14) // * uint64(orderComplementWordFour) // * 1 + acc.Add(t15 * uint64(orderComplementWordThree)) + t10 = uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*11). + // acc.Add(t12 * uint64(orderComplementWordSeven)) // 0 + // acc.Add(t13 * uint64(orderComplementWordSix)) // 0 + // acc.Add(t14 * uint64(orderComplementWordFive)) // 0 + acc.Add(t15) // * uint64(orderComplementWordFour) // * 1 + t11 = uint64(acc.n[0]) + acc.Rsh32() + + // NOTE: All of the remaining multiplications for this iteration result in 0 + // as they all involve multiplying by combinations of the fifth, sixth, and + // seventh words of the two's complement of N, which are 0, so skip them. + + // Terms for 2^(32*12). + t12 = uint64(acc.n[0]) + // acc.Rsh32() // No need since not used after this. Guaranteed to be 0. + + // At this point, the result is reduced to fit within 385 bits, so reduce it + // again using the same method accordingly. + s.reduce385(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12) +} + +// Mul2 multiplies the passed two scalars together modulo the group order in +// constant time and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s3.Mul2(s, s2).AddInt(1) so that s3 = (s * s2) + 1. +func (s *ModNScalar) Mul2(val, val2 *ModNScalar) *ModNScalar { + // This could be done with for loops and an array to store the intermediate + // terms, but this unrolled version is significantly faster. + + // The overall strategy employed here is: + // 1) Calculate the 512-bit product of the two scalars using the standard + // pencil-and-paper method. + // 2) Reduce the result modulo the prime by effectively subtracting + // multiples of the group order N (actually performed by adding multiples + // of the two's complement of N to avoid implementing subtraction). + // 3) Repeat step 2 noting that each iteration reduces the required number + // of bits by 127 because the two's complement of N has 127 leading zero + // bits. + // 4) Once reduced to 256 bits, call the existing reduce method to perform + // a final reduction as needed. + // + // Note that several of the intermediate calculations require adding 64-bit + // products together which would overflow a uint64, so a 96-bit accumulator + // is used instead. + + // Terms for 2^(32*0). + var acc accumulator96 + acc.Add(uint64(val.n[0]) * uint64(val2.n[0])) + t0 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*1). + acc.Add(uint64(val.n[0]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[0])) + t1 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*2). + acc.Add(uint64(val.n[0]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[0])) + t2 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*3). + acc.Add(uint64(val.n[0]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[0])) + t3 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*4). + acc.Add(uint64(val.n[0]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[0])) + t4 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*5). + acc.Add(uint64(val.n[0]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[0])) + t5 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*6). + acc.Add(uint64(val.n[0]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[0])) + t6 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*7). + acc.Add(uint64(val.n[0]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[1]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[1])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[0])) + t7 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*8). + acc.Add(uint64(val.n[1]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[2]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[2])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[1])) + t8 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*9). + acc.Add(uint64(val.n[2]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[3]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[3])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[2])) + t9 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*10). + acc.Add(uint64(val.n[3]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[4]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[4])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[3])) + t10 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*11). + acc.Add(uint64(val.n[4]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[5]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[5])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[4])) + t11 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*12). + acc.Add(uint64(val.n[5]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[6]) * uint64(val2.n[6])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[5])) + t12 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*13). + acc.Add(uint64(val.n[6]) * uint64(val2.n[7])) + acc.Add(uint64(val.n[7]) * uint64(val2.n[6])) + t13 := uint64(acc.n[0]) + acc.Rsh32() + + // Terms for 2^(32*14). + acc.Add(uint64(val.n[7]) * uint64(val2.n[7])) + t14 := uint64(acc.n[0]) + acc.Rsh32() + + // What's left is for 2^(32*15). + t15 := uint64(acc.n[0]) + // acc.Rsh32() // No need since not used after this. Guaranteed to be 0. + + // At this point, all of the terms are grouped into their respective base + // and occupy up to 512 bits. Reduce the result accordingly. + s.reduce512(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, + t15) + return s +} + +// Mul multiplies the passed scalar with the existing one modulo the group order +// in constant time and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Mul(s2).AddInt(1) so that s = (s * s2) + 1. +func (s *ModNScalar) Mul(val *ModNScalar) *ModNScalar { + return s.Mul2(s, val) +} + +// SquareVal squares the passed scalar modulo the group order in constant time +// and stores the result in s. +// +// The scalar is returned to support chaining. This enables syntax like: +// s3.SquareVal(s).Mul(s) so that s3 = s^2 * s = s^3. +func (s *ModNScalar) SquareVal(val *ModNScalar) *ModNScalar { + // This could technically be optimized slightly to take advantage of the + // fact that many of the intermediate calculations in squaring are just + // doubling, however, benchmarking has shown that due to the need to use a + // 96-bit accumulator, any savings are essentially offset by that and + // consequently there is no real difference in performance over just + // multiplying the value by itself to justify the extra code for now. This + // can be revisited in the future if it becomes a bottleneck in practice. + + return s.Mul2(val, val) +} + +// Square squares the scalar modulo the group order in constant time. The +// existing scalar is modified. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Square().Mul(s2) so that s = s^2 * s2. +func (s *ModNScalar) Square() *ModNScalar { + return s.SquareVal(s) +} + +// NegateVal negates the passed scalar modulo the group order and stores the +// result in s in constant time. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.NegateVal(s2).AddInt(1) so that s = -s2 + 1. +func (s *ModNScalar) NegateVal(val *ModNScalar) *ModNScalar { + // Since the scalar is already in the range 0 <= val < N, where N is the + // group order, negation modulo the group order is just the group order + // minus the value. This implies that the result will always be in the + // desired range with the sole exception of 0 because N - 0 = N itself. + // + // Therefore, in order to avoid the need to reduce the result for every + // other case in order to achieve constant time, this creates a mask that is + // all 0s in the case of the scalar being negated is 0 and all 1s otherwise + // and bitwise ands that mask with each word. + // + // Finally, to simplify the carry propagation, this adds the two's + // complement of the scalar to N in order to achieve the same result. + bits := val.n[0] | val.n[1] | val.n[2] | val.n[3] | val.n[4] | val.n[5] | + val.n[6] | val.n[7] + mask := uint64(uint32Mask * constantTimeNotEq(bits, 0)) + c := uint64(orderWordZero) + (uint64(^val.n[0]) + 1) + s.n[0] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordOne) + uint64(^val.n[1]) + s.n[1] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordTwo) + uint64(^val.n[2]) + s.n[2] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordThree) + uint64(^val.n[3]) + s.n[3] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordFour) + uint64(^val.n[4]) + s.n[4] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordFive) + uint64(^val.n[5]) + s.n[5] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordSix) + uint64(^val.n[6]) + s.n[6] = uint32(c & mask) + c = (c >> 32) + uint64(orderWordSeven) + uint64(^val.n[7]) + s.n[7] = uint32(c & mask) + return s +} + +// Negate negates the scalar modulo the group order in constant time. The +// existing scalar is modified. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Negate().AddInt(1) so that s = -s + 1. +func (s *ModNScalar) Negate() *ModNScalar { + return s.NegateVal(s) +} + +// InverseValNonConst finds the modular multiplicative inverse of the passed +// scalar and stores result in s in *non-constant* time. +// +// The scalar is returned to support chaining. This enables syntax like: +// s3.InverseVal(s1).Mul(s2) so that s3 = s1^-1 * s2. +func (s *ModNScalar) InverseValNonConst(val *ModNScalar) *ModNScalar { + // This is making use of big integers for now. Ideally it will be replaced + // with an implementation that does not depend on big integers. + valBytes := val.Bytes() + bigVal := new(big.Int).SetBytes(valBytes[:]) + bigVal.ModInverse(bigVal, curveParams.N) + s.SetByteSlice(bigVal.Bytes()) + return s +} + +// InverseNonConst finds the modular multiplicative inverse of the scalar in +// *non-constant* time. The existing scalar is modified. +// +// The scalar is returned to support chaining. This enables syntax like: +// s.Inverse().Mul(s2) so that s = s^-1 * s2. +func (s *ModNScalar) InverseNonConst() *ModNScalar { + return s.InverseValNonConst(s) +} + +// IsOverHalfOrder returns whether or not the scalar exceeds the group order +// divided by 2 in constant time. +func (s *ModNScalar) IsOverHalfOrder() bool { + // The intuition here is that the scalar is greater than half of the group + // order if one of the higher individual words is greater than the + // corresponding word of the half group order and all higher words in the + // scalar are equal to their corresponding word of the half group order. + // + // Note that the words 4, 5, and 6 are all the max uint32 value, so there is + // no need to test if those individual words of the scalar exceeds them, + // hence, only equality is checked for them. + result := constantTimeGreater(s.n[7], halfOrderWordSeven) + highWordsEqual := constantTimeEq(s.n[7], halfOrderWordSeven) + highWordsEqual &= constantTimeEq(s.n[6], halfOrderWordSix) + highWordsEqual &= constantTimeEq(s.n[5], halfOrderWordFive) + highWordsEqual &= constantTimeEq(s.n[4], halfOrderWordFour) + result |= highWordsEqual & constantTimeGreater(s.n[3], halfOrderWordThree) + highWordsEqual &= constantTimeEq(s.n[3], halfOrderWordThree) + result |= highWordsEqual & constantTimeGreater(s.n[2], halfOrderWordTwo) + highWordsEqual &= constantTimeEq(s.n[2], halfOrderWordTwo) + result |= highWordsEqual & constantTimeGreater(s.n[1], halfOrderWordOne) + highWordsEqual &= constantTimeEq(s.n[1], halfOrderWordOne) + result |= highWordsEqual & constantTimeGreater(s.n[0], halfOrderWordZero) + + return result != 0 +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go new file mode 100644 index 0000000000..70a75bb81c --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go @@ -0,0 +1,263 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2024 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + "bytes" + "crypto/sha256" + "hash" +) + +// References: +// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone) +// +// [ISO/IEC 8825-1]: Information technology — ASN.1 encoding rules: +// Specification of Basic Encoding Rules (BER), Canonical Encoding Rules +// (CER) and Distinguished Encoding Rules (DER) +// +// [SEC1]: Elliptic Curve Cryptography (May 31, 2009, Version 2.0) +// https://www.secg.org/sec1-v2.pdf + +var ( + // singleZero is used during RFC6979 nonce generation. It is provided + // here to avoid the need to create it multiple times. + singleZero = []byte{0x00} + + // zeroInitializer is used during RFC6979 nonce generation. It is provided + // here to avoid the need to create it multiple times. + zeroInitializer = bytes.Repeat([]byte{0x00}, sha256.BlockSize) + + // singleOne is used during RFC6979 nonce generation. It is provided + // here to avoid the need to create it multiple times. + singleOne = []byte{0x01} + + // oneInitializer is used during RFC6979 nonce generation. It is provided + // here to avoid the need to create it multiple times. + oneInitializer = bytes.Repeat([]byte{0x01}, sha256.Size) +) + +// hmacsha256 implements a resettable version of HMAC-SHA256. +type hmacsha256 struct { + inner, outer hash.Hash + ipad, opad [sha256.BlockSize]byte +} + +// Write adds data to the running hash. +func (h *hmacsha256) Write(p []byte) { + h.inner.Write(p) +} + +// initKey initializes the HMAC-SHA256 instance to the provided key. +func (h *hmacsha256) initKey(key []byte) { + // Hash the key if it is too large. + if len(key) > sha256.BlockSize { + h.outer.Write(key) + key = h.outer.Sum(nil) + } + copy(h.ipad[:], key) + copy(h.opad[:], key) + for i := range h.ipad { + h.ipad[i] ^= 0x36 + } + for i := range h.opad { + h.opad[i] ^= 0x5c + } + h.inner.Write(h.ipad[:]) +} + +// ResetKey resets the HMAC-SHA256 to its initial state and then initializes it +// with the provided key. It is equivalent to creating a new instance with the +// provided key without allocating more memory. +func (h *hmacsha256) ResetKey(key []byte) { + h.inner.Reset() + h.outer.Reset() + copy(h.ipad[:], zeroInitializer) + copy(h.opad[:], zeroInitializer) + h.initKey(key) +} + +// Resets the HMAC-SHA256 to its initial state using the current key. +func (h *hmacsha256) Reset() { + h.inner.Reset() + h.inner.Write(h.ipad[:]) +} + +// Sum returns the hash of the written data. +func (h *hmacsha256) Sum() []byte { + h.outer.Reset() + h.outer.Write(h.opad[:]) + h.outer.Write(h.inner.Sum(nil)) + return h.outer.Sum(nil) +} + +// newHMACSHA256 returns a new HMAC-SHA256 hasher using the provided key. +func newHMACSHA256(key []byte) *hmacsha256 { + h := new(hmacsha256) + h.inner = sha256.New() + h.outer = sha256.New() + h.initKey(key) + return h +} + +// NonceRFC6979 generates a nonce deterministically according to RFC 6979 using +// HMAC-SHA256 for the hashing function. It takes a 32-byte hash as an input +// and returns a 32-byte nonce to be used for deterministic signing. The extra +// and version arguments are optional, but allow additional data to be added to +// the input of the HMAC. When provided, the extra data must be 32-bytes and +// version must be 16 bytes or they will be ignored. +// +// Finally, the extraIterations parameter provides a method to produce a stream +// of deterministic nonces to ensure the signing code is able to produce a nonce +// that results in a valid signature in the extremely unlikely event the +// original nonce produced results in an invalid signature (e.g. R == 0). +// Signing code should start with 0 and increment it if necessary. +func NonceRFC6979(privKey []byte, hash []byte, extra []byte, version []byte, extraIterations uint32) *ModNScalar { + // Input to HMAC is the 32-byte private key and the 32-byte hash. In + // addition, it may include the optional 32-byte extra data and 16-byte + // version. Create a fixed-size array to avoid extra allocs and slice it + // properly. + const ( + privKeyLen = 32 + hashLen = 32 + extraLen = 32 + versionLen = 16 + ) + var keyBuf [privKeyLen + hashLen + extraLen + versionLen]byte + + // Truncate rightmost bytes of private key and hash if they are too long and + // leave left padding of zeros when they're too short. + if len(privKey) > privKeyLen { + privKey = privKey[:privKeyLen] + } + if len(hash) > hashLen { + hash = hash[:hashLen] + } + offset := privKeyLen - len(privKey) // Zero left padding if needed. + offset += copy(keyBuf[offset:], privKey) + offset += hashLen - len(hash) // Zero left padding if needed. + offset += copy(keyBuf[offset:], hash) + if len(extra) == extraLen { + offset += copy(keyBuf[offset:], extra) + if len(version) == versionLen { + offset += copy(keyBuf[offset:], version) + } + } else if len(version) == versionLen { + // When the version was specified, but not the extra data, leave the + // extra data portion all zero. + offset += privKeyLen + offset += copy(keyBuf[offset:], version) + } + key := keyBuf[:offset] + + // Step B. + // + // V = 0x01 0x01 0x01 ... 0x01 such that the length of V, in bits, is + // equal to 8*ceil(hashLen/8). + // + // Note that since the hash length is a multiple of 8 for the chosen hash + // function in this optimized implementation, the result is just the hash + // length, so avoid the extra calculations. Also, since it isn't modified, + // start with a global value. + v := oneInitializer + + // Step C (Go zeroes all allocated memory). + // + // K = 0x00 0x00 0x00 ... 0x00 such that the length of K, in bits, is + // equal to 8*ceil(hashLen/8). + // + // As above, since the hash length is a multiple of 8 for the chosen hash + // function in this optimized implementation, the result is just the hash + // length, so avoid the extra calculations. + k := zeroInitializer[:hashLen] + + // Step D. + // + // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1)) + // + // Note that key is the "int2octets(x) || bits2octets(h1)" portion along + // with potential additional data as described by section 3.6 of the RFC. + hasher := newHMACSHA256(k) + hasher.Write(oneInitializer) + hasher.Write(singleZero) + hasher.Write(key) + k = hasher.Sum() + + // Step E. + // + // V = HMAC_K(V) + hasher.ResetKey(k) + hasher.Write(v) + v = hasher.Sum() + + // Step F. + // + // K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1)) + // + // Note that key is the "int2octets(x) || bits2octets(h1)" portion along + // with potential additional data as described by section 3.6 of the RFC. + hasher.Reset() + hasher.Write(v) + hasher.Write(singleOne) + hasher.Write(key) + k = hasher.Sum() + + // Step G. + // + // V = HMAC_K(V) + hasher.ResetKey(k) + hasher.Write(v) + v = hasher.Sum() + + // Step H. + // + // Repeat until the value is nonzero and less than the curve order. + var generated uint32 + for { + // Step H1 and H2. + // + // Set T to the empty sequence. The length of T (in bits) is denoted + // tlen; thus, at that point, tlen = 0. + // + // While tlen < qlen, do the following: + // V = HMAC_K(V) + // T = T || V + // + // Note that because the hash function output is the same length as the + // private key in this optimized implementation, there is no need to + // loop or create an intermediate T. + hasher.Reset() + hasher.Write(v) + v = hasher.Sum() + + // Step H3. + // + // k = bits2int(T) + // If k is within the range [1,q-1], return it. + // + // Otherwise, compute: + // K = HMAC_K(V || 0x00) + // V = HMAC_K(V) + var secret ModNScalar + overflow := secret.SetByteSlice(v) + if !overflow && !secret.IsZero() { + generated++ + if generated > extraIterations { + return &secret + } + } + + // K = HMAC_K(V || 0x00) + hasher.Reset() + hasher.Write(v) + hasher.Write(singleZero) + k = hasher.Sum() + + // V = HMAC_K(V) + hasher.ResetKey(k) + hasher.Write(v) + v = hasher.Sum() + } +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go new file mode 100644 index 0000000000..e6b7be3506 --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go @@ -0,0 +1,111 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2024 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +import ( + cryptorand "crypto/rand" + "io" +) + +// PrivateKey provides facilities for working with secp256k1 private keys within +// this package and includes functionality such as serializing and parsing them +// as well as computing their associated public key. +type PrivateKey struct { + Key ModNScalar +} + +// NewPrivateKey instantiates a new private key from a scalar encoded as a +// big integer. +func NewPrivateKey(key *ModNScalar) *PrivateKey { + return &PrivateKey{Key: *key} +} + +// PrivKeyFromBytes returns a private based on the provided byte slice which is +// interpreted as an unsigned 256-bit big-endian integer in the range [0, N-1], +// where N is the order of the curve. +// +// WARNING: This means passing a slice with more than 32 bytes is truncated and +// that truncated value is reduced modulo N. Further, 0 is not a valid private +// key. It is up to the caller to provide a value in the appropriate range of +// [1, N-1]. Failure to do so will either result in an invalid private key or +// potentially weak private keys that have bias that could be exploited. +// +// This function primarily exists to provide a mechanism for converting +// serialized private keys that are already known to be good. +// +// Typically callers should make use of GeneratePrivateKey or +// GeneratePrivateKeyFromRand when creating private keys since they properly +// handle generation of appropriate values. +func PrivKeyFromBytes(privKeyBytes []byte) *PrivateKey { + var privKey PrivateKey + privKey.Key.SetByteSlice(privKeyBytes) + return &privKey +} + +// generatePrivateKey generates and returns a new private key that is suitable +// for use with secp256k1 using the provided reader as a source of entropy. The +// provided reader must be a source of cryptographically secure randomness to +// avoid weak private keys. +func generatePrivateKey(rand io.Reader) (*PrivateKey, error) { + // The group order is close enough to 2^256 that there is only roughly a 1 + // in 2^128 chance of generating an invalid private key, so this loop will + // virtually never run more than a single iteration in practice. + var key PrivateKey + var b32 [32]byte + for valid := false; !valid; { + if _, err := io.ReadFull(rand, b32[:]); err != nil { + return nil, err + } + + // The private key is only valid when it is in the range [1, N-1], where + // N is the order of the curve. + overflow := key.Key.SetBytes(&b32) + valid = (key.Key.IsZeroBit() | overflow) == 0 + } + zeroArray32(&b32) + + return &key, nil +} + +// GeneratePrivateKey generates and returns a new cryptographically secure +// private key that is suitable for use with secp256k1. +func GeneratePrivateKey() (*PrivateKey, error) { + return generatePrivateKey(cryptorand.Reader) +} + +// GeneratePrivateKeyFromRand generates a private key that is suitable for use +// with secp256k1 using the provided reader as a source of entropy. The +// provided reader must be a source of cryptographically secure randomness, such +// as [crypto/rand.Reader], to avoid weak private keys. +func GeneratePrivateKeyFromRand(rand io.Reader) (*PrivateKey, error) { + return generatePrivateKey(rand) +} + +// PubKey computes and returns the public key corresponding to this private key. +func (p *PrivateKey) PubKey() *PublicKey { + var result JacobianPoint + ScalarBaseMultNonConst(&p.Key, &result) + result.ToAffine() + return NewPublicKey(&result.X, &result.Y) +} + +// Zero manually clears the memory associated with the private key. This can be +// used to explicitly clear key material from memory for enhanced security +// against memory scraping. +func (p *PrivateKey) Zero() { + p.Key.Zero() +} + +// PrivKeyBytesLen defines the length in bytes of a serialized private key. +const PrivKeyBytesLen = 32 + +// Serialize returns the private key as a 256-bit big-endian binary-encoded +// number, padded to a length of 32 bytes. +func (p PrivateKey) Serialize() []byte { + var privKeyBytes [PrivKeyBytesLen]byte + p.Key.PutBytes(&privKeyBytes) + return privKeyBytes[:] +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go new file mode 100644 index 0000000000..2f8815bedf --- /dev/null +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go @@ -0,0 +1,236 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2015-2024 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package secp256k1 + +// References: +// [SEC1] Elliptic Curve Cryptography +// https://www.secg.org/sec1-v2.pdf +// +// [SEC2] Recommended Elliptic Curve Domain Parameters +// https://www.secg.org/sec2-v2.pdf +// +// [ANSI X9.62-1998] Public Key Cryptography For The Financial Services +// Industry: The Elliptic Curve Digital Signature Algorithm (ECDSA) + +import ( + "fmt" +) + +const ( + // PubKeyBytesLenCompressed is the number of bytes of a serialized + // compressed public key. + PubKeyBytesLenCompressed = 33 + + // PubKeyBytesLenUncompressed is the number of bytes of a serialized + // uncompressed public key. + PubKeyBytesLenUncompressed = 65 + + // PubKeyFormatCompressedEven is the identifier prefix byte for a public key + // whose Y coordinate is even when serialized in the compressed format per + // section 2.3.4 of [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.4). + PubKeyFormatCompressedEven byte = 0x02 + + // PubKeyFormatCompressedOdd is the identifier prefix byte for a public key + // whose Y coordinate is odd when serialized in the compressed format per + // section 2.3.4 of [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.4). + PubKeyFormatCompressedOdd byte = 0x03 + + // PubKeyFormatUncompressed is the identifier prefix byte for a public key + // when serialized according in the uncompressed format per section 2.3.3 of + // [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.3). + PubKeyFormatUncompressed byte = 0x04 + + // PubKeyFormatHybridEven is the identifier prefix byte for a public key + // whose Y coordinate is even when serialized according to the hybrid format + // per section 4.3.6 of [ANSI X9.62-1998]. + // + // NOTE: This format makes little sense in practice an therefore this + // package will not produce public keys serialized in this format. However, + // it will parse them since they exist in the wild. + PubKeyFormatHybridEven byte = 0x06 + + // PubKeyFormatHybridOdd is the identifier prefix byte for a public key + // whose Y coordingate is odd when serialized according to the hybrid format + // per section 4.3.6 of [ANSI X9.62-1998]. + // + // NOTE: This format makes little sense in practice an therefore this + // package will not produce public keys serialized in this format. However, + // it will parse them since they exist in the wild. + PubKeyFormatHybridOdd byte = 0x07 +) + +// PublicKey provides facilities for efficiently working with secp256k1 public +// keys within this package and includes functions to serialize in both +// uncompressed and compressed SEC (Standards for Efficient Cryptography) +// formats. +type PublicKey struct { + x FieldVal + y FieldVal +} + +// NewPublicKey instantiates a new public key with the given x and y +// coordinates. +// +// It should be noted that, unlike ParsePubKey, since this accepts arbitrary x +// and y coordinates, it allows creation of public keys that are not valid +// points on the secp256k1 curve. The IsOnCurve method of the returned instance +// can be used to determine validity. +func NewPublicKey(x, y *FieldVal) *PublicKey { + var pubKey PublicKey + pubKey.x.Set(x) + pubKey.y.Set(y) + return &pubKey +} + +// ParsePubKey parses a secp256k1 public key encoded according to the format +// specified by ANSI X9.62-1998, which means it is also compatible with the +// SEC (Standards for Efficient Cryptography) specification which is a subset of +// the former. In other words, it supports the uncompressed, compressed, and +// hybrid formats as follows: +// +// Compressed: +// +// <32-byte X coordinate> +// +// Uncompressed: +// +// <32-byte X coordinate><32-byte Y coordinate> +// +// Hybrid: +// +// <32-byte X coordinate><32-byte Y coordinate> +// +// NOTE: The hybrid format makes little sense in practice an therefore this +// package will not produce public keys serialized in this format. However, +// this function will properly parse them since they exist in the wild. +func ParsePubKey(serialized []byte) (key *PublicKey, err error) { + var x, y FieldVal + switch len(serialized) { + case PubKeyBytesLenUncompressed: + // Reject unsupported public key formats for the given length. + format := serialized[0] + switch format { + case PubKeyFormatUncompressed: + case PubKeyFormatHybridEven, PubKeyFormatHybridOdd: + default: + str := fmt.Sprintf("invalid public key: unsupported format: %x", + format) + return nil, makeError(ErrPubKeyInvalidFormat, str) + } + + // Parse the x and y coordinates while ensuring that they are in the + // allowed range. + if overflow := x.SetByteSlice(serialized[1:33]); overflow { + str := "invalid public key: x >= field prime" + return nil, makeError(ErrPubKeyXTooBig, str) + } + if overflow := y.SetByteSlice(serialized[33:]); overflow { + str := "invalid public key: y >= field prime" + return nil, makeError(ErrPubKeyYTooBig, str) + } + + // Ensure the oddness of the y coordinate matches the specified format + // for hybrid public keys. + if format == PubKeyFormatHybridEven || format == PubKeyFormatHybridOdd { + wantOddY := format == PubKeyFormatHybridOdd + if y.IsOdd() != wantOddY { + str := fmt.Sprintf("invalid public key: y oddness does not "+ + "match specified value of %v", wantOddY) + return nil, makeError(ErrPubKeyMismatchedOddness, str) + } + } + + // Reject public keys that are not on the secp256k1 curve. + if !isOnCurve(&x, &y) { + str := fmt.Sprintf("invalid public key: [%v,%v] not on secp256k1 "+ + "curve", x, y) + return nil, makeError(ErrPubKeyNotOnCurve, str) + } + + case PubKeyBytesLenCompressed: + // Reject unsupported public key formats for the given length. + format := serialized[0] + switch format { + case PubKeyFormatCompressedEven, PubKeyFormatCompressedOdd: + default: + str := fmt.Sprintf("invalid public key: unsupported format: %x", + format) + return nil, makeError(ErrPubKeyInvalidFormat, str) + } + + // Parse the x coordinate while ensuring that it is in the allowed + // range. + if overflow := x.SetByteSlice(serialized[1:33]); overflow { + str := "invalid public key: x >= field prime" + return nil, makeError(ErrPubKeyXTooBig, str) + } + + // Attempt to calculate the y coordinate for the given x coordinate such + // that the result pair is a point on the secp256k1 curve and the + // solution with desired oddness is chosen. + wantOddY := format == PubKeyFormatCompressedOdd + if !DecompressY(&x, wantOddY, &y) { + str := fmt.Sprintf("invalid public key: x coordinate %v is not on "+ + "the secp256k1 curve", x) + return nil, makeError(ErrPubKeyNotOnCurve, str) + } + + default: + str := fmt.Sprintf("malformed public key: invalid length: %d", + len(serialized)) + return nil, makeError(ErrPubKeyInvalidLen, str) + } + + return NewPublicKey(&x, &y), nil +} + +// SerializeUncompressed serializes a public key in the 65-byte uncompressed +// format. +func (p PublicKey) SerializeUncompressed() []byte { + // 0x04 || 32-byte x coordinate || 32-byte y coordinate + var b [PubKeyBytesLenUncompressed]byte + b[0] = PubKeyFormatUncompressed + p.x.PutBytesUnchecked(b[1:33]) + p.y.PutBytesUnchecked(b[33:65]) + return b[:] +} + +// SerializeCompressed serializes a public key in the 33-byte compressed format. +func (p PublicKey) SerializeCompressed() []byte { + // Choose the format byte depending on the oddness of the Y coordinate. + format := PubKeyFormatCompressedEven + if p.y.IsOdd() { + format = PubKeyFormatCompressedOdd + } + + // 0x02 or 0x03 || 32-byte x coordinate + var b [PubKeyBytesLenCompressed]byte + b[0] = format + p.x.PutBytesUnchecked(b[1:33]) + return b[:] +} + +// IsEqual compares this public key instance to the one passed, returning true +// if both public keys are equivalent. A public key is equivalent to another, +// if they both have the same X and Y coordinates. +func (p *PublicKey) IsEqual(otherPubKey *PublicKey) bool { + return p.x.Equals(&otherPubKey.x) && p.y.Equals(&otherPubKey.y) +} + +// AsJacobian converts the public key into a Jacobian point with Z=1 and stores +// the result in the provided result param. This allows the public key to be +// treated a Jacobian point in the secp256k1 group in calculations. +func (p *PublicKey) AsJacobian(result *JacobianPoint) { + result.X.Set(&p.x) + result.Y.Set(&p.y) + result.Z.SetInt(1) +} + +// IsOnCurve returns whether or not the public key represents a point on the +// secp256k1 curve. +func (p *PublicKey) IsOnCurve() bool { + return isOnCurve(&p.x, &p.y) +} diff --git a/vendor/github.com/docker/cli/AUTHORS b/vendor/github.com/docker/cli/AUTHORS index c5a480b5e5..57af08b204 100644 --- a/vendor/github.com/docker/cli/AUTHORS +++ b/vendor/github.com/docker/cli/AUTHORS @@ -63,6 +63,7 @@ Andreas Köhler Andres G. Aragoneses Andres Leon Rangel Andrew France +Andrew He Andrew Hsu Andrew Macpherson Andrew McDonnell @@ -86,11 +87,12 @@ Archimedes Trajano Arko Dasgupta Arnaud Porterie Arnaud Rebillout +Arthur Flageul Arthur Peka Ashly Mathew Ashwini Oruganti Aslam Ahemad -Austin Vazquez +Austin Vazquez Azat Khuyiyakhmetov Bardia Keyoumarsi Barnaby Gray @@ -135,10 +137,12 @@ Cao Weiwei Carlo Mion Carlos Alexandro Becker Carlos de Paula +carsontham Carston Schilds Casey Korver Ce Gao Cedric Davies +Cesar Talledo Cezar Sa Espinola Chad Faragher Chao Wang @@ -220,7 +224,7 @@ David Alvarez David Beitey David Calavera David Cramer -David Dooling +David Dooling David Gageot David Karlsson David le Blanc @@ -265,6 +269,7 @@ Eli Uriegas Eli Uriegas Elias Faxö Elliot Luo <956941328@qq.com> +Eng Zer Jun Eric Bode Eric Curtin Eric Engestrom @@ -345,6 +350,7 @@ Henning Sprang Henry N Hernan Garcia Hongbin Lu +Hossein Abbasi <16090309+hsnabszhdn@users.noreply.github.com> Hu Keping Huayi Zhang Hugo Chastel @@ -595,6 +601,7 @@ Michael Prokop Michael Scharf Michael Spetsiotis Michael Steinert +Michael Tews Michael West Michal Minář Michał Czeraszkiewicz @@ -896,6 +903,7 @@ Wenlong Zhang Wenzhi Liang Wes Morgan Wewang Xiaorenfine +Will Wang William Henry Xianglin Gao Xiaodong Liu diff --git a/vendor/github.com/docker/cli/cli/config/config.go b/vendor/github.com/docker/cli/cli/config/config.go index cbb34486a6..5a63780509 100644 --- a/vendor/github.com/docker/cli/cli/config/config.go +++ b/vendor/github.com/docker/cli/cli/config/config.go @@ -13,7 +13,6 @@ import ( "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/credentials" "github.com/docker/cli/cli/config/types" - "github.com/pkg/errors" ) const ( @@ -101,7 +100,7 @@ func SetDir(dir string) { func Path(p ...string) (string, error) { path := filepath.Join(append([]string{Dir()}, p...)...) if !strings.HasPrefix(path, Dir()+string(filepath.Separator)) { - return "", errors.Errorf("path %q is outside of root config directory %q", path, Dir()) + return "", fmt.Errorf("path %q is outside of root config directory %q", path, Dir()) } return path, nil } @@ -143,12 +142,12 @@ func load(configDir string) (*configfile.ConfigFile, error) { return configFile, nil } // Any other error happening when failing to read the file must be returned. - return configFile, errors.Wrap(err, "loading config file") + return configFile, fmt.Errorf("loading config file: %w", err) } - defer file.Close() + defer func() { _ = file.Close() }() err = configFile.LoadFromReader(file) if err != nil { - err = errors.Wrapf(err, "parsing config file (%s)", filename) + err = fmt.Errorf("parsing config file (%s): %w", filename, err) } return configFile, err } diff --git a/vendor/github.com/docker/cli/cli/config/configfile/file.go b/vendor/github.com/docker/cli/cli/config/configfile/file.go index 24969ef698..fab3ed4cba 100644 --- a/vendor/github.com/docker/cli/cli/config/configfile/file.go +++ b/vendor/github.com/docker/cli/cli/config/configfile/file.go @@ -3,14 +3,16 @@ package configfile import ( "encoding/base64" "encoding/json" + "errors" + "fmt" "io" "os" "path/filepath" "strings" "github.com/docker/cli/cli/config/credentials" + "github.com/docker/cli/cli/config/memorystore" "github.com/docker/cli/cli/config/types" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -41,11 +43,33 @@ type ConfigFile struct { Plugins map[string]map[string]string `json:"plugins,omitempty"` Aliases map[string]string `json:"aliases,omitempty"` Features map[string]string `json:"features,omitempty"` +} + +type configEnvAuth struct { + Auth string `json:"auth"` +} - // Deprecated: experimental CLI features are always enabled and this field is no longer used. Use [Features] instead for optional features. This field will be removed in a future release. - Experimental string `json:"experimental,omitempty"` +type configEnv struct { + AuthConfigs map[string]configEnvAuth `json:"auths"` } +// DockerEnvConfigKey is an environment variable that contains a JSON encoded +// credential config. It only supports storing the credentials as a base64 +// encoded string in the format base64("username:pat"). +// +// Adding additional fields will produce a parsing error. +// +// Example: +// +// { +// "auths": { +// "example.test": { +// "auth": base64-encoded-username-pat +// } +// } +// } +const DockerEnvConfigKey = "DOCKER_AUTH_CONFIG" + // ProxyConfig contains proxy configuration settings type ProxyConfig struct { HTTPProxy string `json:"httpProxy,omitempty"` @@ -140,7 +164,7 @@ func (configFile *ConfigFile) SaveToWriter(writer io.Writer) error { // Save encodes and writes out all the authorization information func (configFile *ConfigFile) Save() (retErr error) { if configFile.Filename == "" { - return errors.Errorf("Can't save config with empty filename") + return errors.New("can't save config with empty filename") } dir := filepath.Dir(configFile.Filename) @@ -167,7 +191,7 @@ func (configFile *ConfigFile) Save() (retErr error) { } if err := temp.Close(); err != nil { - return errors.Wrap(err, "error closing temp file") + return fmt.Errorf("error closing temp file: %w", err) } // Handle situation where the configfile is a symlink, and allow for dangling symlinks @@ -251,11 +275,11 @@ func decodeAuth(authStr string) (string, string, error) { return "", "", err } if n > decLen { - return "", "", errors.Errorf("Something went wrong decoding auth config") + return "", "", errors.New("something went wrong decoding auth config") } userName, password, ok := strings.Cut(string(decoded), ":") if !ok || userName == "" { - return "", "", errors.Errorf("Invalid auth configuration file") + return "", "", errors.New("invalid auth configuration file") } return userName, strings.Trim(password, "\x00"), nil } @@ -263,10 +287,64 @@ func decodeAuth(authStr string) (string, string, error) { // GetCredentialsStore returns a new credentials store from the settings in the // configuration file func (configFile *ConfigFile) GetCredentialsStore(registryHostname string) credentials.Store { + store := credentials.NewFileStore(configFile) + if helper := getConfiguredCredentialStore(configFile, registryHostname); helper != "" { - return newNativeStore(configFile, helper) + store = newNativeStore(configFile, helper) + } + + envConfig := os.Getenv(DockerEnvConfigKey) + if envConfig == "" { + return store + } + + authConfig, err := parseEnvConfig(envConfig) + if err != nil { + _, _ = fmt.Fprintln(os.Stderr, "Failed to create credential store from DOCKER_AUTH_CONFIG: ", err) + return store + } + + // use DOCKER_AUTH_CONFIG if set + // it uses the native or file store as a fallback to fetch and store credentials + envStore, err := memorystore.New( + memorystore.WithAuthConfig(authConfig), + memorystore.WithFallbackStore(store), + ) + if err != nil { + _, _ = fmt.Fprintln(os.Stderr, "Failed to create credential store from DOCKER_AUTH_CONFIG: ", err) + return store + } + + return envStore +} + +func parseEnvConfig(v string) (map[string]types.AuthConfig, error) { + envConfig := &configEnv{} + decoder := json.NewDecoder(strings.NewReader(v)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(envConfig); err != nil && !errors.Is(err, io.EOF) { + return nil, err + } + if decoder.More() { + return nil, errors.New("DOCKER_AUTH_CONFIG does not support more than one JSON object") + } + + authConfigs := make(map[string]types.AuthConfig) + for addr, envAuth := range envConfig.AuthConfigs { + if envAuth.Auth == "" { + return nil, fmt.Errorf("DOCKER_AUTH_CONFIG environment variable is missing key `auth` for %s", addr) + } + username, password, err := decodeAuth(envAuth.Auth) + if err != nil { + return nil, err + } + authConfigs[addr] = types.AuthConfig{ + Username: username, + Password: password, + ServerAddress: addr, + } } - return credentials.NewFileStore(configFile) + return authConfigs, nil } // var for unit testing. diff --git a/vendor/github.com/docker/cli/cli/config/memorystore/store.go b/vendor/github.com/docker/cli/cli/config/memorystore/store.go new file mode 100644 index 0000000000..f8ec62b95a --- /dev/null +++ b/vendor/github.com/docker/cli/cli/config/memorystore/store.go @@ -0,0 +1,131 @@ +// FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16: +//go:build go1.24 + +package memorystore + +import ( + "fmt" + "maps" + "os" + "sync" + + "github.com/docker/cli/cli/config/credentials" + "github.com/docker/cli/cli/config/types" +) + +// notFoundErr is the error returned when a plugin could not be found. +type notFoundErr string + +func (notFoundErr) NotFound() {} + +func (e notFoundErr) Error() string { + return string(e) +} + +var errValueNotFound notFoundErr = "value not found" + +type Config struct { + lock sync.RWMutex + memoryCredentials map[string]types.AuthConfig + fallbackStore credentials.Store +} + +func (e *Config) Erase(serverAddress string) error { + e.lock.Lock() + defer e.lock.Unlock() + delete(e.memoryCredentials, serverAddress) + + if e.fallbackStore != nil { + err := e.fallbackStore.Erase(serverAddress) + if err != nil { + _, _ = fmt.Fprintln(os.Stderr, "memorystore: ", err) + } + } + + return nil +} + +func (e *Config) Get(serverAddress string) (types.AuthConfig, error) { + e.lock.RLock() + defer e.lock.RUnlock() + authConfig, ok := e.memoryCredentials[serverAddress] + if !ok { + if e.fallbackStore != nil { + return e.fallbackStore.Get(serverAddress) + } + return types.AuthConfig{}, errValueNotFound + } + return authConfig, nil +} + +func (e *Config) GetAll() (map[string]types.AuthConfig, error) { + e.lock.RLock() + defer e.lock.RUnlock() + creds := make(map[string]types.AuthConfig) + + if e.fallbackStore != nil { + fileCredentials, err := e.fallbackStore.GetAll() + if err != nil { + _, _ = fmt.Fprintln(os.Stderr, "memorystore: ", err) + } else { + creds = fileCredentials + } + } + + maps.Copy(creds, e.memoryCredentials) + return creds, nil +} + +func (e *Config) Store(authConfig types.AuthConfig) error { + e.lock.Lock() + defer e.lock.Unlock() + e.memoryCredentials[authConfig.ServerAddress] = authConfig + + if e.fallbackStore != nil { + return e.fallbackStore.Store(authConfig) + } + return nil +} + +// WithFallbackStore sets a fallback store. +// +// Write operations will be performed on both the memory store and the +// fallback store. +// +// Read operations will first check the memory store, and if the credential +// is not found, it will then check the fallback store. +// +// Retrieving all credentials will return from both the memory store and the +// fallback store, merging the results from both stores into a single map. +// +// Data stored in the memory store will take precedence over data in the +// fallback store. +func WithFallbackStore(store credentials.Store) Options { + return func(s *Config) error { + s.fallbackStore = store + return nil + } +} + +// WithAuthConfig allows to set the initial credentials in the memory store. +func WithAuthConfig(config map[string]types.AuthConfig) Options { + return func(s *Config) error { + s.memoryCredentials = config + return nil + } +} + +type Options func(*Config) error + +// New creates a new in memory credential store +func New(opts ...Options) (credentials.Store, error) { + m := &Config{ + memoryCredentials: make(map[string]types.AuthConfig), + } + for _, opt := range opts { + if err := opt(m); err != nil { + return nil, err + } + } + return m, nil +} diff --git a/vendor/github.com/docker/cli/cli/config/types/authconfig.go b/vendor/github.com/docker/cli/cli/config/types/authconfig.go index 056af6b842..9fe90003b1 100644 --- a/vendor/github.com/docker/cli/cli/config/types/authconfig.go +++ b/vendor/github.com/docker/cli/cli/config/types/authconfig.go @@ -6,11 +6,6 @@ type AuthConfig struct { Password string `json:"password,omitempty"` Auth string `json:"auth,omitempty"` - // Email is an optional value associated with the username. - // This field is deprecated and will be removed in a later - // version of docker. - Email string `json:"email,omitempty"` - ServerAddress string `json:"serveraddress,omitempty"` // IdentityToken is used to authenticate the user and get diff --git a/vendor/github.com/emicklei/proto/CHANGES.md b/vendor/github.com/emicklei/proto/CHANGES.md index d586b94230..fa8f7b7e98 100644 --- a/vendor/github.com/emicklei/proto/CHANGES.md +++ b/vendor/github.com/emicklei/proto/CHANGES.md @@ -1,3 +1,15 @@ +## v1.14.2 (2025-06-18) + +- fix parsing options for extensions (ISSUE #150) + +## v1.14.1 (2025-04-29) + +- fix option name with brackets (ISSUE #148) + +## v1.14.0 (2024-12-18) + +- parse edition element (PR #147, ISSUE #145) + ## v1.13.4 (2024-12-17) - fixed handling identifiers known as numbers by scanner (PR #146) diff --git a/vendor/github.com/emicklei/proto/README.md b/vendor/github.com/emicklei/proto/README.md index c99a320b85..644721ea26 100644 --- a/vendor/github.com/emicklei/proto/README.md +++ b/vendor/github.com/emicklei/proto/README.md @@ -1,14 +1,15 @@ # proto +[![Go](https://github.com/emicklei/proto/actions/workflows/go.yml/badge.svg)](https://github.com/emicklei/proto/actions/workflows/go.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/emicklei/proto)](https://goreportcard.com/report/github.com/emicklei/proto) [![GoDoc](https://pkg.go.dev/badge/github.com/emicklei/proto)](https://pkg.go.dev/github.com/emicklei/proto) [![codecov](https://codecov.io/gh/emicklei/proto/branch/master/graph/badge.svg)](https://codecov.io/gh/emicklei/proto) -Package in Go for parsing Google Protocol Buffers [.proto files version 2 + 3](https://developers.google.com/protocol-buffers/docs/reference/proto3-spec) +Package in Go for parsing Google Protocol Buffers [.proto files version 2 + 3, editions](https://developers.google.com/protocol-buffers/docs/reference/proto3-spec) ### install - go get -u -v github.com/emicklei/proto + go get github.com/emicklei/proto ### usage @@ -57,11 +58,11 @@ Package in Go for parsing Google Protocol Buffers [.proto files version 2 + 3](h Current parser implementation is not completely validating `.proto` definitions. In many but not all cases, the parser will report syntax errors when reading unexpected charaters or tokens. -Use some linting tools (e.g. https://github.com/uber/prototool) or `protoc` for full validation. +Use some linting tools or `protoc` for full validation. ### contributions See [proto-contrib](https://github.com/emicklei/proto-contrib) for other contributions on top of this package such as protofmt, proto2xsd and proto2gql. [protobuf2map](https://github.com/emicklei/protobuf2map) is a small package for inspecting serialized protobuf messages using its `.proto` definition. -© 2017-2022, [ernestmicklei.com](http://ernestmicklei.com). MIT License. Contributions welcome. +© 2017-2025, [ernestmicklei.com](http://ernestmicklei.com). MIT License. Contributions welcome. diff --git a/vendor/github.com/emicklei/proto/edition.go b/vendor/github.com/emicklei/proto/edition.go new file mode 100644 index 0000000000..279d733d16 --- /dev/null +++ b/vendor/github.com/emicklei/proto/edition.go @@ -0,0 +1,65 @@ +// Copyright (c) 2024 Ernest Micklei +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package proto + +import ( + "text/scanner" +) + +type Edition struct { + Position scanner.Position + Comment *Comment + Value string + InlineComment *Comment + Parent Visitee +} + +func (e *Edition) parse(p *Parser) error { + if _, tok, lit := p.next(); tok != tEQUALS { + return p.unexpected(lit, "edition =", e) + } + _, _, lit := p.next() + if !isString(lit) { + return p.unexpected(lit, "edition string constant", e) + } + e.Value, _ = unQuote(lit) + return nil +} + +// Accept dispatches the call to the visitor. +func (e *Edition) Accept(v Visitor) { + // v.VisitEdition(e) in v2 +} + +// Doc is part of Documented +func (e *Edition) Doc() *Comment { + return e.Comment +} + +// inlineComment is part of commentInliner. +func (e *Edition) inlineComment(c *Comment) { + e.InlineComment = c +} + +func (e *Edition) parent(v Visitee) { e.Parent = v } diff --git a/vendor/github.com/emicklei/proto/extensions.go b/vendor/github.com/emicklei/proto/extensions.go index 5c615b6fd2..a4a023477e 100644 --- a/vendor/github.com/emicklei/proto/extensions.go +++ b/vendor/github.com/emicklei/proto/extensions.go @@ -35,6 +35,7 @@ type Extensions struct { Ranges []Range InlineComment *Comment Parent Visitee + Options []*Option } // inlineComment is part of commentInliner. @@ -54,6 +55,33 @@ func (e *Extensions) parse(p *Parser) error { return err } e.Ranges = list + + // see if there are options + pos, tok, lit := p.next() + if tLEFTSQUARE != tok { + p.nextPut(pos, tok, lit) + return nil + } + // consume options (copied from normal field parsing) + for { + o := new(Option) + o.Position = pos + o.IsEmbedded = true + o.parent(e) + err := o.parse(p) + if err != nil { + return err + } + e.Options = append(e.Options, o) + + pos, tok, lit = p.next() + if tRIGHTSQUARE == tok { + break + } + if tCOMMA != tok { + return p.unexpected(lit, "option ,", o) + } + } return nil } diff --git a/vendor/github.com/emicklei/proto/literals.go b/vendor/github.com/emicklei/proto/literals.go new file mode 100644 index 0000000000..e07ca73ada --- /dev/null +++ b/vendor/github.com/emicklei/proto/literals.go @@ -0,0 +1,301 @@ +// Copyright (c) 2025 Ernest Micklei +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package proto + +import ( + "bytes" + "sort" + "text/scanner" +) + +// Literal represents intLit,floatLit,strLit or boolLit or a nested structure thereof. +type Literal struct { + Position scanner.Position + Source string + IsString bool + + // It not nil then the entry is actually a comment with line(s) + // modelled this way because Literal is not an elementContainer + Comment *Comment + + // The rune use to delimit the string value (only valid iff IsString) + QuoteRune rune + + // literal value can be an array literal value (even nested) + Array []*Literal + + // literal value can be a map of literals (even nested) + // DEPRECATED: use OrderedMap instead + Map map[string]*Literal + + // literal value can be a map of literals (even nested) + // this is done as pairs of name keys and literal values so the original ordering is preserved + OrderedMap LiteralMap +} + +var emptyRune rune + +// LiteralMap is like a map of *Literal but preserved the ordering. +// Can be iterated yielding *NamedLiteral values. +type LiteralMap []*NamedLiteral + +// Get returns a Literal from the map. +func (m LiteralMap) Get(key string) (*Literal, bool) { + for _, each := range m { + if each.Name == key { + // exit on the first match + return each.Literal, true + } + } + return new(Literal), false +} + +// SourceRepresentation returns the source (use the same rune that was used to delimit the string). +func (l Literal) SourceRepresentation() string { + var buf bytes.Buffer + if l.IsString { + if l.QuoteRune == emptyRune { + buf.WriteRune('"') + } else { + buf.WriteRune(l.QuoteRune) + } + } + buf.WriteString(l.Source) + if l.IsString { + if l.QuoteRune == emptyRune { + buf.WriteRune('"') + } else { + buf.WriteRune(l.QuoteRune) + } + } + return buf.String() +} + +// parse expects to read a literal constant after =. +func (l *Literal) parse(p *Parser) error { + pos, tok, lit := p.next() + // handle special element inside literal, a comment line + if isComment(lit) { + nc := newComment(pos, lit) + if l.Comment == nil { + l.Comment = nc + } else { + l.Comment.Merge(nc) + } + // continue with remaining entries + return l.parse(p) + } + if tok == tLEFTSQUARE { + // collect array elements + array := []*Literal{} + + // if it's an empty array, consume the close bracket, set the Array to + // an empty array, and return + r := p.peekNonWhitespace() + if r == ']' { + pos, _, _ := p.next() + l.Array = array + l.IsString = false + l.Position = pos + return nil + } + for { + e := new(Literal) + if err := e.parse(p); err != nil { + return err + } + array = append(array, e) + _, tok, lit := p.next() + if tok == tCOMMA { + continue + } + if tok == tRIGHTSQUARE { + break + } + return p.unexpected(lit, ", or ]", l) + } + l.Array = array + l.IsString = false + l.Position = pos + return nil + } + if tLEFTCURLY == tok { + l.Position, l.Source, l.IsString = pos, "", false + constants, err := parseAggregateConstants(p, l) + if err != nil { + return nil + } + l.OrderedMap = LiteralMap(constants) + return nil + } + if "-" == lit { + // negative number + if err := l.parse(p); err != nil { + return err + } + // modify source and position + l.Position, l.Source = pos, "-"+l.Source + return nil + } + source := lit + iss := isString(lit) + if iss { + source, l.QuoteRune = unQuote(source) + } + l.Position, l.Source, l.IsString = pos, source, iss + + // peek for multiline strings + for { + pos, tok, lit := p.next() + if isString(lit) { + line, _ := unQuote(lit) + l.Source += line + } else { + p.nextPut(pos, tok, lit) + break + } + } + return nil +} + +// NamedLiteral associates a name with a Literal +type NamedLiteral struct { + *Literal + Name string + // PrintsColon is true when the Name must be printed with a colon suffix + PrintsColon bool +} + +// flatten the maps of each literal, recursively +// this func exists for deprecated Option.AggregatedConstants. +func collectAggregatedConstants(m map[string]*Literal) (list []*NamedLiteral) { + for k, v := range m { + if v.Map != nil { + sublist := collectAggregatedConstants(v.Map) + for _, each := range sublist { + list = append(list, &NamedLiteral{ + Name: k + "." + each.Name, + PrintsColon: true, + Literal: each.Literal, + }) + } + } else { + list = append(list, &NamedLiteral{ + Name: k, + PrintsColon: true, + Literal: v, + }) + } + } + // sort list by position of literal + sort.Sort(byPosition(list)) + return +} + +type byPosition []*NamedLiteral + +func (b byPosition) Less(i, j int) bool { + return b[i].Literal.Position.Line < b[j].Literal.Position.Line +} +func (b byPosition) Len() int { return len(b) } +func (b byPosition) Swap(i, j int) { b[i], b[j] = b[j], b[i] } + +func parseAggregateConstants(p *Parser, container interface{}) (list []*NamedLiteral, err error) { + for { + _, tok, lit := p.nextMessageLiteralFieldName() + // if tRIGHTSQUARE == tok { + // p.nextPut(pos, tok, lit) + // // caller has checked for open square ; will consume rightsquare, rightcurly and semicolon + // return + // } + if tRIGHTCURLY == tok { + return + } + if tSEMICOLON == tok { + // just consume it + continue + //return + } + if tCOMMENT == tok { + // assign to last parsed literal + // TODO: see TestUseOfSemicolonsInAggregatedConstants + continue + } + if tCOMMA == tok { + if len(list) == 0 { + err = p.unexpected(lit, "non-empty option aggregate key", container) + return + } + continue + } + if tIDENT != tok && !isKeyword(tok) { + err = p.unexpected(lit, "option aggregate key", container) + return + } + // workaround issue #59 TODO + if isString(lit) && len(list) > 0 { + // concatenate with previous constant + s, _ := unQuote(lit) + list[len(list)-1].Source += s + continue + } + key := lit + printsColon := false + // expect colon, aggregate or plain literal + pos, tok, lit := p.next() + if tCOLON == tok { + // consume it + printsColon = true + pos, tok, lit = p.next() + } + // see if nested aggregate is started + if tLEFTCURLY == tok { + nested, fault := parseAggregateConstants(p, container) + if fault != nil { + err = fault + return + } + + // create the map + m := map[string]*Literal{} + for _, each := range nested { + m[each.Name] = each.Literal + } + list = append(list, &NamedLiteral{ + Name: key, + PrintsColon: printsColon, + Literal: &Literal{Map: m, OrderedMap: LiteralMap(nested)}}) + continue + } + // no aggregate, put back token + p.nextPut(pos, tok, lit) + // now we see plain literal + l := new(Literal) + l.Position = pos + if err = l.parse(p); err != nil { + return + } + list = append(list, &NamedLiteral{Name: key, Literal: l, PrintsColon: printsColon}) + } +} diff --git a/vendor/github.com/emicklei/proto/noop_visitor.go b/vendor/github.com/emicklei/proto/noop_visitor.go index df4cf8df27..ffb1ac8f6f 100644 --- a/vendor/github.com/emicklei/proto/noop_visitor.go +++ b/vendor/github.com/emicklei/proto/noop_visitor.go @@ -23,6 +23,8 @@ package proto +var _ Visitor = NoopVisitor{} + // NoopVisitor is a no-operation visitor that can be used when creating your own visitor that is interested in only one or a few types. // It implements the Visitor interface. type NoopVisitor struct{} @@ -36,6 +38,9 @@ func (n NoopVisitor) VisitService(v *Service) {} // VisitSyntax is part of Visitor interface func (n NoopVisitor) VisitSyntax(s *Syntax) {} +// VisitSyntax is part of Visitor interface +func (n NoopVisitor) VisitEdition(e *Edition) {} + // VisitPackage is part of Visitor interface func (n NoopVisitor) VisitPackage(p *Package) {} diff --git a/vendor/github.com/emicklei/proto/option.go b/vendor/github.com/emicklei/proto/option.go index 65897b888c..8a439b115f 100644 --- a/vendor/github.com/emicklei/proto/option.go +++ b/vendor/github.com/emicklei/proto/option.go @@ -24,9 +24,7 @@ package proto import ( - "bytes" "fmt" - "sort" "text/scanner" ) @@ -47,49 +45,22 @@ type Option struct { // ( ident | //... | "(" fullIdent ")" ) { "." ident } "=" constant ";" func (o *Option) parse(p *Parser) error { consumeOptionComments(o, p) - pos, tok, lit := p.nextIdentifier() - if tLEFTPAREN == tok { - pos, tok, lit = p.nextIdentifier() - if tok != tIDENT { - if !isKeyword(tok) { - return p.unexpected(lit, "option full identifier", o) - } - } - pos, tok, _ = p.next() - if tok != tRIGHTPAREN { - return p.unexpected(lit, "option full identifier closing )", o) - } - o.Name = fmt.Sprintf("(%s)", lit) - } else { - // non full ident - if tIDENT != tok { - if !isKeyword(tok) { - return p.unexpected(lit, "option identifier", o) - } - } - o.Name = lit - } - pos, tok, lit = p.next() - if tDOT == tok { - // extend identifier - pos, tok, lit = p.nextIdent(true) // keyword allowed as start - if tok != tIDENT { - if !isKeyword(tok) { - return p.unexpected(lit, "option postfix identifier", o) - } - } - o.Name = fmt.Sprintf("%s.%s", o.Name, lit) - pos, tok, lit = p.next() + + if err := o.parseOptionName(p); err != nil { + return err } + // check for = + pos, tok, lit := p.next() if tEQUALS != tok { return p.unexpected(lit, "option value assignment =", o) } + // parse value r := p.peekNonWhitespace() var err error // values of an option can have illegal escape sequences // for the standard Go scanner used by this package. p.ignoreIllegalEscapesWhile(func() { - if '{' == r { + if r == '{' { // aggregate p.next() // consume { err = o.parseAggregate(p) @@ -107,6 +78,44 @@ func (o *Option) parse(p *Parser) error { return err } +// https://protobuf.dev/reference/protobuf/proto3-spec/#option +func (o *Option) parseOptionName(p *Parser) error { + name := "" + for { + pos, tok, lit := p.nextIdent(true) + switch tok { + case tDOT: + name += "." + case tIDENT: + name += lit + case tLEFTPAREN: + // check for dot + dot := "" // none + if p.peekNonWhitespace() == '.' { + p.next() // consume dot + dot = "." + } + _, tok, lit = p.nextFullIdent(true) + if tok != tIDENT { + return p.unexpected(lit, "option name", o) + } + // check for closing parenthesis + _, tok, _ = p.next() + if tok != tRIGHTPAREN { + return p.unexpected(lit, "option full identifier closing )", o) + } + name = fmt.Sprintf("%s(%s%s)", name, dot, lit) + default: + // put it back + p.nextPut(pos, tok, lit) + goto done + } + } +done: + o.Name = name + return nil +} + // inlineComment is part of commentInliner. func (o *Option) inlineComment(c *Comment) { o.InlineComment = c @@ -122,164 +131,6 @@ func (o *Option) Doc() *Comment { return o.Comment } -// Literal represents intLit,floatLit,strLit or boolLit or a nested structure thereof. -type Literal struct { - Position scanner.Position - Source string - IsString bool - - // It not nil then the entry is actually a comment with line(s) - // modelled this way because Literal is not an elementContainer - Comment *Comment - - // The rune use to delimit the string value (only valid iff IsString) - QuoteRune rune - - // literal value can be an array literal value (even nested) - Array []*Literal - - // literal value can be a map of literals (even nested) - // DEPRECATED: use OrderedMap instead - Map map[string]*Literal - - // literal value can be a map of literals (even nested) - // this is done as pairs of name keys and literal values so the original ordering is preserved - OrderedMap LiteralMap -} - -var emptyRune rune - -// LiteralMap is like a map of *Literal but preserved the ordering. -// Can be iterated yielding *NamedLiteral values. -type LiteralMap []*NamedLiteral - -// Get returns a Literal from the map. -func (m LiteralMap) Get(key string) (*Literal, bool) { - for _, each := range m { - if each.Name == key { - // exit on the first match - return each.Literal, true - } - } - return new(Literal), false -} - -// SourceRepresentation returns the source (use the same rune that was used to delimit the string). -func (l Literal) SourceRepresentation() string { - var buf bytes.Buffer - if l.IsString { - if l.QuoteRune == emptyRune { - buf.WriteRune('"') - } else { - buf.WriteRune(l.QuoteRune) - } - } - buf.WriteString(l.Source) - if l.IsString { - if l.QuoteRune == emptyRune { - buf.WriteRune('"') - } else { - buf.WriteRune(l.QuoteRune) - } - } - return buf.String() -} - -// parse expects to read a literal constant after =. -func (l *Literal) parse(p *Parser) error { - pos, tok, lit := p.next() - // handle special element inside literal, a comment line - if isComment(lit) { - nc := newComment(pos, lit) - if l.Comment == nil { - l.Comment = nc - } else { - l.Comment.Merge(nc) - } - // continue with remaining entries - return l.parse(p) - } - if tok == tLEFTSQUARE { - // collect array elements - array := []*Literal{} - - // if it's an empty array, consume the close bracket, set the Array to - // an empty array, and return - r := p.peekNonWhitespace() - if r == ']' { - pos, _, _ := p.next() - l.Array = array - l.IsString = false - l.Position = pos - return nil - } - for { - e := new(Literal) - if err := e.parse(p); err != nil { - return err - } - array = append(array, e) - _, tok, lit := p.next() - if tok == tCOMMA { - continue - } - if tok == tRIGHTSQUARE { - break - } - return p.unexpected(lit, ", or ]", l) - } - l.Array = array - l.IsString = false - l.Position = pos - return nil - } - if tLEFTCURLY == tok { - l.Position, l.Source, l.IsString = pos, "", false - constants, err := parseAggregateConstants(p, l) - if err != nil { - return nil - } - l.OrderedMap = LiteralMap(constants) - return nil - } - if "-" == lit { - // negative number - if err := l.parse(p); err != nil { - return err - } - // modify source and position - l.Position, l.Source = pos, "-"+l.Source - return nil - } - source := lit - iss := isString(lit) - if iss { - source, l.QuoteRune = unQuote(source) - } - l.Position, l.Source, l.IsString = pos, source, iss - - // peek for multiline strings - for { - pos, tok, lit := p.next() - if isString(lit) { - line, _ := unQuote(lit) - l.Source += line - } else { - p.nextPut(pos, tok, lit) - break - } - } - return nil -} - -// NamedLiteral associates a name with a Literal -type NamedLiteral struct { - *Literal - Name string - // PrintsColon is true when the Name must be printed with a colon suffix - PrintsColon bool -} - // parseAggregate reads options written using aggregate syntax. // tLEFTCURLY { has been consumed func (o *Option) parseAggregate(p *Parser) error { @@ -295,117 +146,4 @@ func (o *Option) parseAggregate(p *Parser) error { return err } -// flatten the maps of each literal, recursively -// this func exists for deprecated Option.AggregatedConstants. -func collectAggregatedConstants(m map[string]*Literal) (list []*NamedLiteral) { - for k, v := range m { - if v.Map != nil { - sublist := collectAggregatedConstants(v.Map) - for _, each := range sublist { - list = append(list, &NamedLiteral{ - Name: k + "." + each.Name, - PrintsColon: true, - Literal: each.Literal, - }) - } - } else { - list = append(list, &NamedLiteral{ - Name: k, - PrintsColon: true, - Literal: v, - }) - } - } - // sort list by position of literal - sort.Sort(byPosition(list)) - return -} - -type byPosition []*NamedLiteral - -func (b byPosition) Less(i, j int) bool { - return b[i].Literal.Position.Line < b[j].Literal.Position.Line -} -func (b byPosition) Len() int { return len(b) } -func (b byPosition) Swap(i, j int) { b[i], b[j] = b[j], b[i] } - -func parseAggregateConstants(p *Parser, container interface{}) (list []*NamedLiteral, err error) { - for { - _, tok, lit := p.nextMessageLiteralFieldName() - // if tRIGHTSQUARE == tok { - // p.nextPut(pos, tok, lit) - // // caller has checked for open square ; will consume rightsquare, rightcurly and semicolon - // return - // } - if tRIGHTCURLY == tok { - return - } - if tSEMICOLON == tok { - // just consume it - continue - //return - } - if tCOMMENT == tok { - // assign to last parsed literal - // TODO: see TestUseOfSemicolonsInAggregatedConstants - continue - } - if tCOMMA == tok { - if len(list) == 0 { - err = p.unexpected(lit, "non-empty option aggregate key", container) - return - } - continue - } - if tIDENT != tok && !isKeyword(tok) { - err = p.unexpected(lit, "option aggregate key", container) - return - } - // workaround issue #59 TODO - if isString(lit) && len(list) > 0 { - // concatenate with previous constant - s, _ := unQuote(lit) - list[len(list)-1].Source += s - continue - } - key := lit - printsColon := false - // expect colon, aggregate or plain literal - pos, tok, lit := p.next() - if tCOLON == tok { - // consume it - printsColon = true - pos, tok, lit = p.next() - } - // see if nested aggregate is started - if tLEFTCURLY == tok { - nested, fault := parseAggregateConstants(p, container) - if fault != nil { - err = fault - return - } - - // create the map - m := map[string]*Literal{} - for _, each := range nested { - m[each.Name] = each.Literal - } - list = append(list, &NamedLiteral{ - Name: key, - PrintsColon: printsColon, - Literal: &Literal{Map: m, OrderedMap: LiteralMap(nested)}}) - continue - } - // no aggregate, put back token - p.nextPut(pos, tok, lit) - // now we see plain literal - l := new(Literal) - l.Position = pos - if err = l.parse(p); err != nil { - return - } - list = append(list, &NamedLiteral{Name: key, Literal: l, PrintsColon: printsColon}) - } -} - func (o *Option) parent(v Visitee) { o.Parent = v } diff --git a/vendor/github.com/emicklei/proto/parent_accessor.go b/vendor/github.com/emicklei/proto/parent_accessor.go index f85eb5e272..8f3130bd64 100644 --- a/vendor/github.com/emicklei/proto/parent_accessor.go +++ b/vendor/github.com/emicklei/proto/parent_accessor.go @@ -85,4 +85,7 @@ func (p *parentAccessor) VisitGroup(g *Group) { func (p *parentAccessor) VisitExtensions(e *Extensions) { p.parent = e.Parent } +func (p *parentAccessor) VisitEdition(e *Edition) { + p.parent = e.Parent +} func (p *parentAccessor) VisitProto(*Proto) {} diff --git a/vendor/github.com/emicklei/proto/parser.go b/vendor/github.com/emicklei/proto/parser.go index 0f338ee183..41ed461da9 100644 --- a/vendor/github.com/emicklei/proto/parser.go +++ b/vendor/github.com/emicklei/proto/parser.go @@ -265,16 +265,17 @@ func (p *Parser) nextIdent(keywordStartAllowed bool) (pos scanner.Position, tok // see if identifier is namespaced for { r := p.peekNonWhitespace() - if '.' != r { + if r != '.' { break } p.next() // consume dot + fullLit += "." pos, tok, lit := p.next() if tIDENT != tok && !isKeyword(tok) { p.nextPut(pos, tok, lit) break } - fullLit = fmt.Sprintf("%s.%s", fullLit, lit) + fullLit += lit } return startPos, tIDENT, fullLit } @@ -291,3 +292,30 @@ func (p *Parser) peekNonWhitespace() rune { } return r } + +// https://protobuf.dev/reference/protobuf/proto3-spec/ +func (p *Parser) nextFullIdent(keywordStartAllowed bool) (pos scanner.Position, tok token, lit string) { + pos, tok, lit = p.next() + if tIDENT != tok { + // can be keyword + if !(isKeyword(tok) && keywordStartAllowed) { + return + } + // proceed with keyword as first literal + } + fullIdent := lit + for { + r := p.peekNonWhitespace() + if r != '.' { + break + } + p.next() // consume dot + pos, tok, lit = p.nextFullIdent(true) + if tok != tIDENT { + p.nextPut(pos, tok, lit) + break + } + fullIdent = fmt.Sprintf("%s.%s", fullIdent, lit) + } + return pos, tIDENT, fullIdent +} diff --git a/vendor/github.com/emicklei/proto/proto.go b/vendor/github.com/emicklei/proto/proto.go index 2bbdb2932a..95d52ed2c7 100644 --- a/vendor/github.com/emicklei/proto/proto.go +++ b/vendor/github.com/emicklei/proto/proto.go @@ -81,6 +81,14 @@ func (proto *Proto) parse(p *Parser) error { return err } proto.addElement(s) + case tEDITION == tok: + s := new(Edition) + s.Position = pos + s.Comment, proto.Elements = takeLastCommentIfEndsOnLine(proto.Elements, pos.Line-1) + if err := s.parse(p); err != nil { + return err + } + proto.addElement(s) case tIMPORT == tok: im := new(Import) im.Position = pos diff --git a/vendor/github.com/emicklei/proto/range.go b/vendor/github.com/emicklei/proto/range.go index 5d4aae090f..c38c54deab 100644 --- a/vendor/github.com/emicklei/proto/range.go +++ b/vendor/github.com/emicklei/proto/range.go @@ -60,8 +60,8 @@ func parseRanges(p *Parser, n Visitee) (list []Range, err error) { case ",": case "to": seenTo = true - case ";": - p.nextPut(pos, tok, lit) // allow for inline comment parsing + case ";", "[": + p.nextPut(pos, tok, lit) // allow for inline comment parsing or options goto done case "max": if !seenTo { diff --git a/vendor/github.com/emicklei/proto/token.go b/vendor/github.com/emicklei/proto/token.go index d1f59c9752..65907c25b2 100644 --- a/vendor/github.com/emicklei/proto/token.go +++ b/vendor/github.com/emicklei/proto/token.go @@ -60,6 +60,7 @@ const ( // Keywords keywordsStart + tEDITION tSYNTAX tSERVICE tRPC @@ -192,6 +193,8 @@ func asToken(literal string) token { // words case "syntax": return tSYNTAX + case "edition": + return tEDITION case "service": return tSERVICE case "rpc": diff --git a/vendor/github.com/emicklei/proto/visitor.go b/vendor/github.com/emicklei/proto/visitor.go index be0850a375..e62c56a79a 100644 --- a/vendor/github.com/emicklei/proto/visitor.go +++ b/vendor/github.com/emicklei/proto/visitor.go @@ -25,7 +25,6 @@ package proto // Visitor is for dispatching Proto elements. type Visitor interface { - //VisitProto(p *Proto) VisitMessage(m *Message) VisitService(v *Service) VisitSyntax(s *Syntax) @@ -44,6 +43,8 @@ type Visitor interface { // proto2 VisitGroup(g *Group) VisitExtensions(e *Extensions) + // edition (proto3+), v2 + // VisitEdition(e *Edition) } // Visitee is implemented by all Proto elements. diff --git a/vendor/github.com/go-chi/chi/.travis.yml b/vendor/github.com/go-chi/chi/.travis.yml deleted file mode 100644 index 7b8e26bcee..0000000000 --- a/vendor/github.com/go-chi/chi/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -language: go - -go: - - 1.10.x - - 1.11.x - - 1.12.x - - 1.13.x - - 1.14.x - -script: - - go get -d -t ./... - - go vet ./... - - go test ./... - - > - go_version=$(go version); - if [ ${go_version:13:4} = "1.12" ]; then - go get -u golang.org/x/tools/cmd/goimports; - goimports -d -e ./ | grep '.*' && { echo; echo "Aborting due to non-empty goimports output."; exit 1; } || :; - fi - diff --git a/vendor/github.com/go-chi/chi/middleware/content_type.go b/vendor/github.com/go-chi/chi/middleware/content_type.go deleted file mode 100644 index ee4957874f..0000000000 --- a/vendor/github.com/go-chi/chi/middleware/content_type.go +++ /dev/null @@ -1,51 +0,0 @@ -package middleware - -import ( - "net/http" - "strings" -) - -// SetHeader is a convenience handler to set a response header key/value -func SetHeader(key, value string) func(next http.Handler) http.Handler { - return func(next http.Handler) http.Handler { - fn := func(w http.ResponseWriter, r *http.Request) { - w.Header().Set(key, value) - next.ServeHTTP(w, r) - } - return http.HandlerFunc(fn) - } -} - -// AllowContentType enforces a whitelist of request Content-Types otherwise responds -// with a 415 Unsupported Media Type status. -func AllowContentType(contentTypes ...string) func(next http.Handler) http.Handler { - cT := []string{} - for _, t := range contentTypes { - cT = append(cT, strings.ToLower(t)) - } - - return func(next http.Handler) http.Handler { - fn := func(w http.ResponseWriter, r *http.Request) { - if r.ContentLength == 0 { - // skip check for empty content body - next.ServeHTTP(w, r) - return - } - - s := strings.ToLower(strings.TrimSpace(r.Header.Get("Content-Type"))) - if i := strings.Index(s, ";"); i > -1 { - s = s[0:i] - } - - for _, t := range cT { - if t == s { - next.ServeHTTP(w, r) - return - } - } - - w.WriteHeader(http.StatusUnsupportedMediaType) - } - return http.HandlerFunc(fn) - } -} diff --git a/vendor/github.com/go-chi/chi/middleware/profiler.go b/vendor/github.com/go-chi/chi/middleware/profiler.go deleted file mode 100644 index 1d44b8259a..0000000000 --- a/vendor/github.com/go-chi/chi/middleware/profiler.go +++ /dev/null @@ -1,55 +0,0 @@ -package middleware - -import ( - "expvar" - "fmt" - "net/http" - "net/http/pprof" - - "github.com/go-chi/chi" -) - -// Profiler is a convenient subrouter used for mounting net/http/pprof. ie. -// -// func MyService() http.Handler { -// r := chi.NewRouter() -// // ..middlewares -// r.Mount("/debug", middleware.Profiler()) -// // ..routes -// return r -// } -func Profiler() http.Handler { - r := chi.NewRouter() - r.Use(NoCache) - - r.Get("/", func(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, r.RequestURI+"/pprof/", 301) - }) - r.HandleFunc("/pprof", func(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, r.RequestURI+"/", 301) - }) - - r.HandleFunc("/pprof/*", pprof.Index) - r.HandleFunc("/pprof/cmdline", pprof.Cmdline) - r.HandleFunc("/pprof/profile", pprof.Profile) - r.HandleFunc("/pprof/symbol", pprof.Symbol) - r.HandleFunc("/pprof/trace", pprof.Trace) - r.HandleFunc("/vars", expVars) - - return r -} - -// Replicated from expvar.go as not public. -func expVars(w http.ResponseWriter, r *http.Request) { - first := true - w.Header().Set("Content-Type", "application/json") - fmt.Fprintf(w, "{\n") - expvar.Do(func(kv expvar.KeyValue) { - if !first { - fmt.Fprintf(w, ",\n") - } - first = false - fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value) - }) - fmt.Fprintf(w, "\n}\n") -} diff --git a/vendor/github.com/go-chi/chi/.gitignore b/vendor/github.com/go-chi/chi/v5/.gitignore similarity index 100% rename from vendor/github.com/go-chi/chi/.gitignore rename to vendor/github.com/go-chi/chi/v5/.gitignore diff --git a/vendor/github.com/go-chi/chi/CHANGELOG.md b/vendor/github.com/go-chi/chi/v5/CHANGELOG.md similarity index 51% rename from vendor/github.com/go-chi/chi/CHANGELOG.md rename to vendor/github.com/go-chi/chi/v5/CHANGELOG.md index 9a64a72eec..25b45b9743 100644 --- a/vendor/github.com/go-chi/chi/CHANGELOG.md +++ b/vendor/github.com/go-chi/chi/v5/CHANGELOG.md @@ -1,5 +1,157 @@ # Changelog +## v5.0.12 (2024-02-16) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.11...v5.0.12 + + +## v5.0.11 (2023-12-19) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.10...v5.0.11 + + +## v5.0.10 (2023-07-13) + +- Fixed small edge case in tests of v5.0.9 for older Go versions +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.9...v5.0.10 + + +## v5.0.9 (2023-07-13) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.8...v5.0.9 + + +## v5.0.8 (2022-12-07) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.7...v5.0.8 + + +## v5.0.7 (2021-11-18) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.6...v5.0.7 + + +## v5.0.6 (2021-11-15) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.5...v5.0.6 + + +## v5.0.5 (2021-10-27) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.4...v5.0.5 + + +## v5.0.4 (2021-08-29) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.3...v5.0.4 + + +## v5.0.3 (2021-04-29) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.2...v5.0.3 + + +## v5.0.2 (2021-03-25) + +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.1...v5.0.2 + + +## v5.0.1 (2021-03-10) + +- Small improvements +- History of changes: see https://github.com/go-chi/chi/compare/v5.0.0...v5.0.1 + + +## v5.0.0 (2021-02-27) + +- chi v5, `github.com/go-chi/chi/v5` introduces the adoption of Go's SIV to adhere to the current state-of-the-tools in Go. +- chi v1.5.x did not work out as planned, as the Go tooling is too powerful and chi's adoption is too wide. + The most responsible thing to do for everyone's benefit is to just release v5 with SIV, so I present to you all, + chi v5 at `github.com/go-chi/chi/v5`. I hope someday the developer experience and ergonomics I've been seeking + will still come to fruition in some form, see https://github.com/golang/go/issues/44550 +- History of changes: see https://github.com/go-chi/chi/compare/v1.5.4...v5.0.0 + + +## v1.5.4 (2021-02-27) + +- Undo prior retraction in v1.5.3 as we prepare for v5.0.0 release +- History of changes: see https://github.com/go-chi/chi/compare/v1.5.3...v1.5.4 + + +## v1.5.3 (2021-02-21) + +- Update go.mod to go 1.16 with new retract directive marking all versions without prior go.mod support +- History of changes: see https://github.com/go-chi/chi/compare/v1.5.2...v1.5.3 + + +## v1.5.2 (2021-02-10) + +- Reverting allocation optimization as a precaution as go test -race fails. +- Minor improvements, see history below +- History of changes: see https://github.com/go-chi/chi/compare/v1.5.1...v1.5.2 + + +## v1.5.1 (2020-12-06) + +- Performance improvement: removing 1 allocation by foregoing context.WithValue, thank you @bouk for + your contribution (https://github.com/go-chi/chi/pull/555). Note: new benchmarks posted in README. +- `middleware.CleanPath`: new middleware that clean's request path of double slashes +- deprecate & remove `chi.ServerBaseContext` in favour of stdlib `http.Server#BaseContext` +- plus other tiny improvements, see full commit history below +- History of changes: see https://github.com/go-chi/chi/compare/v4.1.2...v1.5.1 + + +## v1.5.0 (2020-11-12) - now with go.mod support + +`chi` dates back to 2016 with it's original implementation as one of the first routers to adopt the newly introduced +context.Context api to the stdlib -- set out to design a router that is faster, more modular and simpler than anything +else out there -- while not introducing any custom handler types or dependencies. Today, `chi` still has zero dependencies, +and in many ways is future proofed from changes, given it's minimal nature. Between versions, chi's iterations have been very +incremental, with the architecture and api being the same today as it was originally designed in 2016. For this reason it +makes chi a pretty easy project to maintain, as well thanks to the many amazing community contributions over the years +to who all help make chi better (total of 86 contributors to date -- thanks all!). + +Chi has been a labour of love, art and engineering, with the goals to offer beautiful ergonomics, flexibility, performance +and simplicity when building HTTP services with Go. I've strived to keep the router very minimal in surface area / code size, +and always improving the code wherever possible -- and as of today the `chi` package is just 1082 lines of code (not counting +middlewares, which are all optional). As well, I don't have the exact metrics, but from my analysis and email exchanges from +companies and developers, chi is used by thousands of projects around the world -- thank you all as there is no better form of +joy for me than to have art I had started be helpful and enjoyed by others. And of course I use chi in all of my own projects too :) + +For me, the aesthetics of chi's code and usage are very important. With the introduction of Go's module support +(which I'm a big fan of), chi's past versioning scheme choice to v2, v3 and v4 would mean I'd require the import path +of "github.com/go-chi/chi/v4", leading to the lengthy discussion at https://github.com/go-chi/chi/issues/462. +Haha, to some, you may be scratching your head why I've spent > 1 year stalling to adopt "/vXX" convention in the import +path -- which isn't horrible in general -- but for chi, I'm unable to accept it as I strive for perfection in it's API design, +aesthetics and simplicity. It just doesn't feel good to me given chi's simple nature -- I do not foresee a "v5" or "v6", +and upgrading between versions in the future will also be just incremental. + +I do understand versioning is a part of the API design as well, which is why the solution for a while has been to "do nothing", +as Go supports both old and new import paths with/out go.mod. However, now that Go module support has had time to iron out kinks and +is adopted everywhere, it's time for chi to get with the times. Luckily, I've discovered a path forward that will make me happy, +while also not breaking anyone's app who adopted a prior versioning from tags in v2/v3/v4. I've made an experimental release of +v1.5.0 with go.mod silently, and tested it with new and old projects, to ensure the developer experience is preserved, and it's +largely unnoticed. Fortunately, Go's toolchain will check the tags of a repo and consider the "latest" tag the one with go.mod. +However, you can still request a specific older tag such as v4.1.2, and everything will "just work". But new users can just +`go get github.com/go-chi/chi` or `go get github.com/go-chi/chi@latest` and they will get the latest version which contains +go.mod support, which is v1.5.0+. `chi` will not change very much over the years, just like it hasn't changed much from 4 years ago. +Therefore, we will stay on v1.x from here on, starting from v1.5.0. Any breaking changes will bump a "minor" release and +backwards-compatible improvements/fixes will bump a "tiny" release. + +For existing projects who want to upgrade to the latest go.mod version, run: `go get -u github.com/go-chi/chi@v1.5.0`, +which will get you on the go.mod version line (as Go's mod cache may still remember v4.x). Brand new systems can run +`go get -u github.com/go-chi/chi` or `go get -u github.com/go-chi/chi@latest` to install chi, which will install v1.5.0+ +built with go.mod support. + +My apologies to the developers who will disagree with the decisions above, but, hope you'll try it and see it's a very +minor request which is backwards compatible and won't break your existing installations. + +Cheers all, happy coding! + + +--- + + ## v4.1.2 (2020-06-02) - fix that handles MethodNotAllowed with path variables, thank you @caseyhadden for your contribution @@ -23,7 +175,6 @@ - middleware.Recoverer: a bit prettier - History of changes: see https://github.com/go-chi/chi/compare/v4.0.4...v4.1.0 - ## v4.0.4 (2020-03-24) - middleware.Recoverer: new pretty stack trace printing (https://github.com/go-chi/chi/pull/496) @@ -159,13 +310,13 @@ ## v2.0.0-rc1 (2016-07-26) -- Huge update! chi v2 is a large refactor targetting Go 1.7+. As of Go 1.7, the popular +- Huge update! chi v2 is a large refactor targeting Go 1.7+. As of Go 1.7, the popular community `"net/context"` package has been included in the standard library as `"context"` and utilized by `"net/http"` and `http.Request` to managing deadlines, cancelation signals and other request-scoped values. We're very excited about the new context addition and are proud to introduce chi v2, a minimal and powerful routing package for building large HTTP services, with zero external dependencies. Chi focuses on idiomatic design and encourages the use of - stdlib HTTP handlers and middlwares. + stdlib HTTP handlers and middlewares. - chi v2 deprecates its `chi.Handler` interface and requires `http.Handler` or `http.HandlerFunc` - chi v2 stores URL routing parameters and patterns in the standard request context: `r.Context()` - chi v2 lower-level routing context is accessible by `chi.RouteContext(r.Context()) *chi.Context`, diff --git a/vendor/github.com/go-chi/chi/CONTRIBUTING.md b/vendor/github.com/go-chi/chi/v5/CONTRIBUTING.md similarity index 58% rename from vendor/github.com/go-chi/chi/CONTRIBUTING.md rename to vendor/github.com/go-chi/chi/v5/CONTRIBUTING.md index c0ac2dfe85..b4a6268d57 100644 --- a/vendor/github.com/go-chi/chi/CONTRIBUTING.md +++ b/vendor/github.com/go-chi/chi/v5/CONTRIBUTING.md @@ -14,7 +14,7 @@ A typical workflow is: -1. [Fork the repository.][fork] [This tip maybe also helpful.][go-fork-tip] +1. [Fork the repository.][fork] 2. [Create a topic branch.][branch] 3. Add tests for your change. 4. Run `go test`. If your tests pass, return to the step 3. @@ -24,8 +24,8 @@ A typical workflow is: 8. [Submit a pull request.][pull-req] [go-install]: https://golang.org/doc/install -[go-fork-tip]: http://blog.campoy.cat/2014/03/github-and-go-forking-pull-requests-and.html -[fork]: https://help.github.com/articles/fork-a-repo -[branch]: http://learn.github.com/p/branching.html -[git-help]: https://guides.github.com -[pull-req]: https://help.github.com/articles/using-pull-requests +[fork]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo +[branch]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches +[git-help]: https://docs.github.com/en +[pull-req]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests + diff --git a/vendor/github.com/go-chi/chi/LICENSE b/vendor/github.com/go-chi/chi/v5/LICENSE similarity index 100% rename from vendor/github.com/go-chi/chi/LICENSE rename to vendor/github.com/go-chi/chi/v5/LICENSE diff --git a/vendor/github.com/go-chi/chi/v5/Makefile b/vendor/github.com/go-chi/chi/v5/Makefile new file mode 100644 index 0000000000..e0f18c7da2 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/Makefile @@ -0,0 +1,22 @@ +.PHONY: all +all: + @echo "**********************************************************" + @echo "** chi build tool **" + @echo "**********************************************************" + + +.PHONY: test +test: + go clean -testcache && $(MAKE) test-router && $(MAKE) test-middleware + +.PHONY: test-router +test-router: + go test -race -v . + +.PHONY: test-middleware +test-middleware: + go test -race -v ./middleware + +.PHONY: docs +docs: + npx docsify-cli serve ./docs diff --git a/vendor/github.com/go-chi/chi/README.md b/vendor/github.com/go-chi/chi/v5/README.md similarity index 61% rename from vendor/github.com/go-chi/chi/README.md rename to vendor/github.com/go-chi/chi/v5/README.md index 5a8fc9d096..c58a0e20ce 100644 --- a/vendor/github.com/go-chi/chi/README.md +++ b/vendor/github.com/go-chi/chi/v5/README.md @@ -1,7 +1,7 @@ # chi -[![GoDoc Widget]][GoDoc] [![Travis Widget]][Travis] +[![GoDoc Widget]][GoDoc] `chi` is a lightweight, idiomatic and composable router for building Go HTTP services. It's especially good at helping you write large REST API services that are kept maintainable as your @@ -15,11 +15,14 @@ public API service, which in turn powers all of our client-side applications. The key considerations of chi's design are: project structure, maintainability, standard http handlers (stdlib-only), developer productivity, and deconstructing a large system into many small parts. The core router `github.com/go-chi/chi` is quite small (less than 1000 LOC), but we've also -included some useful/optional subpackages: [middleware](/middleware), [render](https://github.com/go-chi/render) and [docgen](https://github.com/go-chi/docgen). We hope you enjoy it too! +included some useful/optional subpackages: [middleware](/middleware), [render](https://github.com/go-chi/render) +and [docgen](https://github.com/go-chi/docgen). We hope you enjoy it too! ## Install -`go get -u github.com/go-chi/chi` +```sh +go get -u github.com/go-chi/chi/v5 +``` ## Features @@ -27,10 +30,11 @@ included some useful/optional subpackages: [middleware](/middleware), [render](h * **Lightweight** - cloc'd in ~1000 LOC for the chi router * **Fast** - yes, see [benchmarks](#benchmarks) * **100% compatible with net/http** - use any http or middleware pkg in the ecosystem that is also compatible with `net/http` -* **Designed for modular/composable APIs** - middlewares, inline middlewares, route groups and subrouter mounting +* **Designed for modular/composable APIs** - middlewares, inline middlewares, route groups and sub-router mounting * **Context control** - built on new `context` package, providing value chaining, cancellations and timeouts -* **Robust** - in production at Pressly, CloudFlare, Heroku, 99Designs, and many others (see [discussion](https://github.com/go-chi/chi/issues/91)) +* **Robust** - in production at Pressly, Cloudflare, Heroku, 99Designs, and many others (see [discussion](https://github.com/go-chi/chi/issues/91)) * **Doc generation** - `docgen` auto-generates routing documentation from your source to JSON or Markdown +* **Go.mod support** - as of v5, go.mod support (see [CHANGELOG](https://github.com/go-chi/chi/blob/master/CHANGELOG.md)) * **No external dependencies** - plain ol' Go stdlib + net/http @@ -47,8 +51,8 @@ package main import ( "net/http" - "github.com/go-chi/chi" - "github.com/go-chi/chi/middleware" + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" ) func main() { @@ -63,7 +67,7 @@ func main() { **REST Preview:** -Here is a little preview of how routing looks like with chi. Also take a look at the generated routing docs +Here is a little preview of what routing looks like with chi. Also take a look at the generated routing docs in JSON ([routes.json](https://github.com/go-chi/chi/blob/master/_examples/rest/routes.json)) and in Markdown ([routes.md](https://github.com/go-chi/chi/blob/master/_examples/rest/routes.md)). @@ -74,8 +78,8 @@ above, they will show you all the features of chi and serve as a good form of do import ( //... "context" - "github.com/go-chi/chi" - "github.com/go-chi/chi/middleware" + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" ) func main() { @@ -168,7 +172,7 @@ func AdminOnly(next http.Handler) http.Handler { ``` -## Router design +## Router interface chi's router is based on a kind of [Patricia Radix trie](https://en.wikipedia.org/wiki/Radix_tree). The router is fully compatible with `net/http`. @@ -192,7 +196,7 @@ type Router interface { // path, with a fresh middleware stack for the inline-Router. Group(fn func(r Router)) Router - // Route mounts a sub-Router along a `pattern`` string. + // Route mounts a sub-Router along a `pattern` string. Route(pattern string, fn func(r Router)) Router // Mount attaches another http.Handler along ./pattern/* @@ -257,15 +261,24 @@ about them, which means the router and all the tooling is designed to be compati friendly with any middleware in the community. This offers much better extensibility and reuse of packages and is at the heart of chi's purpose. -Here is an example of a standard net/http middleware handler using the new request context -available in Go. This middleware sets a hypothetical user identifier on the request +Here is an example of a standard net/http middleware where we assign a context key `"user"` +the value of `"123"`. This middleware sets a hypothetical user identifier on the request context and calls the next handler in the chain. ```go // HTTP middleware setting a value on the request context func MyMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // create new context from `r` request context, and assign key `"user"` + // to value of `"123"` ctx := context.WithValue(r.Context(), "user", "123") + + // call the next handler in the chain, passing the response writer and + // the updated request object with the new context value. + // + // note: context.Context values are nested, so any previously set + // values will be accessible as well, and the new `"user"` key + // will be accessible from this point forward. next.ServeHTTP(w, r.WithContext(ctx)) }) } @@ -281,7 +294,11 @@ the user sending an authenticated request, validated+set by a previous middlewar ```go // HTTP handler accessing data from the request context. func MyRequestHandler(w http.ResponseWriter, r *http.Request) { + // here we read from the request context and fetch out `"user"` key set in + // the MyMiddleware example above. user := r.Context().Value("user").(string) + + // respond to the client w.Write([]byte(fmt.Sprintf("hi %s", user))) } ``` @@ -296,11 +313,15 @@ are able to access the same information. ```go // HTTP handler accessing the url routing parameters. func MyRequestHandler(w http.ResponseWriter, r *http.Request) { - userID := chi.URLParam(r, "userID") // from a route like /users/{userID} + // fetch the url parameter `"userID"` from the request of a matching + // routing pattern. An example routing pattern could be: /users/{userID} + userID := chi.URLParam(r, "userID") + // fetch `"key"` from the request context ctx := r.Context() key := ctx.Value("key").(string) + // respond to the client w.Write([]byte(fmt.Sprintf("hi %v, %v", userID, key))) } ``` @@ -314,28 +335,72 @@ with `net/http` can be used with chi's mux. ### Core middlewares ------------------------------------------------------------------------------------------------------------ -| chi/middleware Handler | description | -|:----------------------|:--------------------------------------------------------------------------------- -| AllowContentType | Explicit whitelist of accepted request Content-Types | -| BasicAuth | Basic HTTP authentication | -| Compress | Gzip compression for clients that accept compressed responses | -| GetHead | Automatically route undefined HEAD requests to GET handlers | -| Heartbeat | Monitoring endpoint to check the servers pulse | -| Logger | Logs the start and end of each request with the elapsed processing time | -| NoCache | Sets response headers to prevent clients from caching | -| Profiler | Easily attach net/http/pprof to your routers | -| RealIP | Sets a http.Request's RemoteAddr to either X-Forwarded-For or X-Real-IP | -| Recoverer | Gracefully absorb panics and prints the stack trace | -| RequestID | Injects a request ID into the context of each request | -| RedirectSlashes | Redirect slashes on routing paths | -| SetHeader | Short-hand middleware to set a response header key/value | -| StripSlashes | Strip slashes on routing paths | -| Throttle | Puts a ceiling on the number of concurrent requests | -| Timeout | Signals to the request context when the timeout deadline is reached | -| URLFormat | Parse extension from url and put it on request context | -| WithValue | Short-hand middleware to set a key/value on the request context | ------------------------------------------------------------------------------------------------------------ +---------------------------------------------------------------------------------------------------- +| chi/middleware Handler | description | +| :--------------------- | :---------------------------------------------------------------------- | +| [AllowContentEncoding] | Enforces a whitelist of request Content-Encoding headers | +| [AllowContentType] | Explicit whitelist of accepted request Content-Types | +| [BasicAuth] | Basic HTTP authentication | +| [Compress] | Gzip compression for clients that accept compressed responses | +| [ContentCharset] | Ensure charset for Content-Type request headers | +| [CleanPath] | Clean double slashes from request path | +| [GetHead] | Automatically route undefined HEAD requests to GET handlers | +| [Heartbeat] | Monitoring endpoint to check the servers pulse | +| [Logger] | Logs the start and end of each request with the elapsed processing time | +| [NoCache] | Sets response headers to prevent clients from caching | +| [Profiler] | Easily attach net/http/pprof to your routers | +| [RealIP] | Sets a http.Request's RemoteAddr to either X-Real-IP or X-Forwarded-For | +| [Recoverer] | Gracefully absorb panics and prints the stack trace | +| [RequestID] | Injects a request ID into the context of each request | +| [RedirectSlashes] | Redirect slashes on routing paths | +| [RouteHeaders] | Route handling for request headers | +| [SetHeader] | Short-hand middleware to set a response header key/value | +| [StripSlashes] | Strip slashes on routing paths | +| [Sunset] | Sunset set Deprecation/Sunset header to response | +| [Throttle] | Puts a ceiling on the number of concurrent requests | +| [Timeout] | Signals to the request context when the timeout deadline is reached | +| [URLFormat] | Parse extension from url and put it on request context | +| [WithValue] | Short-hand middleware to set a key/value on the request context | +---------------------------------------------------------------------------------------------------- + +[AllowContentEncoding]: https://pkg.go.dev/github.com/go-chi/chi/middleware#AllowContentEncoding +[AllowContentType]: https://pkg.go.dev/github.com/go-chi/chi/middleware#AllowContentType +[BasicAuth]: https://pkg.go.dev/github.com/go-chi/chi/middleware#BasicAuth +[Compress]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Compress +[ContentCharset]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ContentCharset +[CleanPath]: https://pkg.go.dev/github.com/go-chi/chi/middleware#CleanPath +[GetHead]: https://pkg.go.dev/github.com/go-chi/chi/middleware#GetHead +[GetReqID]: https://pkg.go.dev/github.com/go-chi/chi/middleware#GetReqID +[Heartbeat]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Heartbeat +[Logger]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Logger +[NoCache]: https://pkg.go.dev/github.com/go-chi/chi/middleware#NoCache +[Profiler]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Profiler +[RealIP]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RealIP +[Recoverer]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Recoverer +[RedirectSlashes]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RedirectSlashes +[RequestLogger]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RequestLogger +[RequestID]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RequestID +[RouteHeaders]: https://pkg.go.dev/github.com/go-chi/chi/middleware#RouteHeaders +[SetHeader]: https://pkg.go.dev/github.com/go-chi/chi/middleware#SetHeader +[StripSlashes]: https://pkg.go.dev/github.com/go-chi/chi/middleware#StripSlashes +[Sunset]: https://pkg.go.dev/github.com/go-chi/chi/v5/middleware#Sunset +[Throttle]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Throttle +[ThrottleBacklog]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ThrottleBacklog +[ThrottleWithOpts]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ThrottleWithOpts +[Timeout]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Timeout +[URLFormat]: https://pkg.go.dev/github.com/go-chi/chi/middleware#URLFormat +[WithLogEntry]: https://pkg.go.dev/github.com/go-chi/chi/middleware#WithLogEntry +[WithValue]: https://pkg.go.dev/github.com/go-chi/chi/middleware#WithValue +[Compressor]: https://pkg.go.dev/github.com/go-chi/chi/middleware#Compressor +[DefaultLogFormatter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#DefaultLogFormatter +[EncoderFunc]: https://pkg.go.dev/github.com/go-chi/chi/middleware#EncoderFunc +[HeaderRoute]: https://pkg.go.dev/github.com/go-chi/chi/middleware#HeaderRoute +[HeaderRouter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#HeaderRouter +[LogEntry]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LogEntry +[LogFormatter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LogFormatter +[LoggerInterface]: https://pkg.go.dev/github.com/go-chi/chi/middleware#LoggerInterface +[ThrottleOpts]: https://pkg.go.dev/github.com/go-chi/chi/middleware#ThrottleOpts +[WrapResponseWriter]: https://pkg.go.dev/github.com/go-chi/chi/middleware#WrapResponseWriter ### Extra middlewares & packages @@ -355,8 +420,6 @@ Please see https://github.com/go-chi for additional packages. | [stampede](https://github.com/go-chi/stampede) | HTTP request coalescer | -------------------------------------------------------------------------------------------------------------------- -please [submit a PR](./CONTRIBUTING.md) if you'd like to include a link to a chi-compatible middleware - ## context? @@ -375,25 +438,25 @@ and.. The benchmark suite: https://github.com/pkieltyka/go-http-routing-benchmark -Results as of Jan 9, 2019 with Go 1.11.4 on Linux X1 Carbon laptop +Results as of Nov 29, 2020 with Go 1.15.5 on Linux AMD 3950x ```shell -BenchmarkChi_Param 3000000 475 ns/op 432 B/op 3 allocs/op -BenchmarkChi_Param5 2000000 696 ns/op 432 B/op 3 allocs/op -BenchmarkChi_Param20 1000000 1275 ns/op 432 B/op 3 allocs/op -BenchmarkChi_ParamWrite 3000000 505 ns/op 432 B/op 3 allocs/op -BenchmarkChi_GithubStatic 3000000 508 ns/op 432 B/op 3 allocs/op -BenchmarkChi_GithubParam 2000000 669 ns/op 432 B/op 3 allocs/op -BenchmarkChi_GithubAll 10000 134627 ns/op 87699 B/op 609 allocs/op -BenchmarkChi_GPlusStatic 3000000 402 ns/op 432 B/op 3 allocs/op -BenchmarkChi_GPlusParam 3000000 500 ns/op 432 B/op 3 allocs/op -BenchmarkChi_GPlus2Params 3000000 586 ns/op 432 B/op 3 allocs/op -BenchmarkChi_GPlusAll 200000 7237 ns/op 5616 B/op 39 allocs/op -BenchmarkChi_ParseStatic 3000000 408 ns/op 432 B/op 3 allocs/op -BenchmarkChi_ParseParam 3000000 488 ns/op 432 B/op 3 allocs/op -BenchmarkChi_Parse2Params 3000000 551 ns/op 432 B/op 3 allocs/op -BenchmarkChi_ParseAll 100000 13508 ns/op 11232 B/op 78 allocs/op -BenchmarkChi_StaticAll 20000 81933 ns/op 67826 B/op 471 allocs/op +BenchmarkChi_Param 3075895 384 ns/op 400 B/op 2 allocs/op +BenchmarkChi_Param5 2116603 566 ns/op 400 B/op 2 allocs/op +BenchmarkChi_Param20 964117 1227 ns/op 400 B/op 2 allocs/op +BenchmarkChi_ParamWrite 2863413 420 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GithubStatic 3045488 395 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GithubParam 2204115 540 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GithubAll 10000 113811 ns/op 81203 B/op 406 allocs/op +BenchmarkChi_GPlusStatic 3337485 359 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GPlusParam 2825853 423 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GPlus2Params 2471697 483 ns/op 400 B/op 2 allocs/op +BenchmarkChi_GPlusAll 194220 5950 ns/op 5200 B/op 26 allocs/op +BenchmarkChi_ParseStatic 3365324 356 ns/op 400 B/op 2 allocs/op +BenchmarkChi_ParseParam 2976614 404 ns/op 400 B/op 2 allocs/op +BenchmarkChi_Parse2Params 2638084 439 ns/op 400 B/op 2 allocs/op +BenchmarkChi_ParseAll 109567 11295 ns/op 10400 B/op 52 allocs/op +BenchmarkChi_StaticAll 16846 71308 ns/op 62802 B/op 314 allocs/op ``` Comparison with other routers: https://gist.github.com/pkieltyka/123032f12052520aaccab752bd3e78cc @@ -408,7 +471,8 @@ how setting context on a request in Go works. * Carl Jackson for https://github.com/zenazn/goji * Parts of chi's thinking comes from goji, and chi's middleware package - sources from goji. + sources from [goji](https://github.com/zenazn/goji/tree/master/web/middleware). + * Please see goji's [LICENSE](https://github.com/zenazn/goji/blob/master/LICENSE) (MIT) * Armon Dadgar for https://github.com/armon/go-radix * Contributions: [@VojtechVitek](https://github.com/VojtechVitek) @@ -435,7 +499,7 @@ Copyright (c) 2015-present [Peter Kieltyka](https://github.com/pkieltyka) Licensed under [MIT License](./LICENSE) -[GoDoc]: https://godoc.org/github.com/go-chi/chi +[GoDoc]: https://pkg.go.dev/github.com/go-chi/chi/v5 [GoDoc Widget]: https://godoc.org/github.com/go-chi/chi?status.svg [Travis]: https://travis-ci.org/go-chi/chi [Travis Widget]: https://travis-ci.org/go-chi/chi.svg?branch=master diff --git a/vendor/github.com/go-chi/chi/v5/SECURITY.md b/vendor/github.com/go-chi/chi/v5/SECURITY.md new file mode 100644 index 0000000000..7e937f87f3 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/SECURITY.md @@ -0,0 +1,5 @@ +# Reporting Security Issues + +We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions. + +To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/go-chi/chi/security/advisories/new) tab. diff --git a/vendor/github.com/go-chi/chi/chain.go b/vendor/github.com/go-chi/chi/v5/chain.go similarity index 94% rename from vendor/github.com/go-chi/chi/chain.go rename to vendor/github.com/go-chi/chi/v5/chain.go index 88e6846138..a2278414f4 100644 --- a/vendor/github.com/go-chi/chi/chain.go +++ b/vendor/github.com/go-chi/chi/v5/chain.go @@ -10,21 +10,21 @@ func Chain(middlewares ...func(http.Handler) http.Handler) Middlewares { // Handler builds and returns a http.Handler from the chain of middlewares, // with `h http.Handler` as the final handler. func (mws Middlewares) Handler(h http.Handler) http.Handler { - return &ChainHandler{mws, h, chain(mws, h)} + return &ChainHandler{h, chain(mws, h), mws} } // HandlerFunc builds and returns a http.Handler from the chain of middlewares, // with `h http.Handler` as the final handler. func (mws Middlewares) HandlerFunc(h http.HandlerFunc) http.Handler { - return &ChainHandler{mws, h, chain(mws, h)} + return &ChainHandler{h, chain(mws, h), mws} } // ChainHandler is a http.Handler with support for handler composition and // execution. type ChainHandler struct { - Middlewares Middlewares Endpoint http.Handler chain http.Handler + Middlewares Middlewares } func (c *ChainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { diff --git a/vendor/github.com/go-chi/chi/chi.go b/vendor/github.com/go-chi/chi/v5/chi.go similarity index 80% rename from vendor/github.com/go-chi/chi/chi.go rename to vendor/github.com/go-chi/chi/v5/chi.go index b7063dc297..2b6ebd337c 100644 --- a/vendor/github.com/go-chi/chi/chi.go +++ b/vendor/github.com/go-chi/chi/v5/chi.go @@ -1,29 +1,29 @@ -// // Package chi is a small, idiomatic and composable router for building HTTP services. // -// chi requires Go 1.10 or newer. +// chi requires Go 1.14 or newer. // // Example: -// package main // -// import ( -// "net/http" +// package main +// +// import ( +// "net/http" // -// "github.com/go-chi/chi" -// "github.com/go-chi/chi/middleware" -// ) +// "github.com/go-chi/chi/v5" +// "github.com/go-chi/chi/v5/middleware" +// ) // -// func main() { -// r := chi.NewRouter() -// r.Use(middleware.Logger) -// r.Use(middleware.Recoverer) +// func main() { +// r := chi.NewRouter() +// r.Use(middleware.Logger) +// r.Use(middleware.Recoverer) // -// r.Get("/", func(w http.ResponseWriter, r *http.Request) { -// w.Write([]byte("root.")) -// }) +// r.Get("/", func(w http.ResponseWriter, r *http.Request) { +// w.Write([]byte("root.")) +// }) // -// http.ListenAndServe(":3333", r) -// } +// http.ListenAndServe(":3333", r) +// } // // See github.com/go-chi/chi/_examples/ for more in-depth examples. // @@ -37,8 +37,7 @@ // // A placeholder with a name followed by a colon allows a regular // expression match, for example {number:\\d+}. The regular expression -// syntax is Go's normal regexp RE2 syntax, except that regular expressions -// including { or } are not supported, and / will never be +// syntax is Go's normal regexp RE2 syntax, except that / will never be // matched. An anonymous regexp pattern is allowed, using an empty string // before the colon in the placeholder, such as {:\\d+} // @@ -47,12 +46,12 @@ // placeholder which will match / characters. // // Examples: -// "/user/{name}" matches "/user/jsmith" but not "/user/jsmith/info" or "/user/jsmith/" -// "/user/{name}/info" matches "/user/jsmith/info" -// "/page/*" matches "/page/intro/latest" -// "/page/*/index" also matches "/page/intro/latest" -// "/date/{yyyy:\\d\\d\\d\\d}/{mm:\\d\\d}/{dd:\\d\\d}" matches "/date/2017/04/01" // +// "/user/{name}" matches "/user/jsmith" but not "/user/jsmith/info" or "/user/jsmith/" +// "/user/{name}/info" matches "/user/jsmith/info" +// "/page/*" matches "/page/intro/latest" +// "/page/{other}/latest" also matches "/page/intro/latest" +// "/date/{yyyy:\\d\\d\\d\\d}/{mm:\\d\\d}/{dd:\\d\\d}" matches "/date/2017/04/01" package chi import "net/http" @@ -127,6 +126,10 @@ type Routes interface { // the method/path - similar to routing a http request, but without // executing the handler thereafter. Match(rctx *Context, method, path string) bool + + // Find searches the routing tree for the pattern that matches + // the method/path. + Find(rctx *Context, method, path string) string } // Middlewares type is a slice of standard middleware handlers with methods diff --git a/vendor/github.com/go-chi/chi/context.go b/vendor/github.com/go-chi/chi/v5/context.go similarity index 73% rename from vendor/github.com/go-chi/chi/context.go rename to vendor/github.com/go-chi/chi/v5/context.go index 26c609ea2c..82220730e9 100644 --- a/vendor/github.com/go-chi/chi/context.go +++ b/vendor/github.com/go-chi/chi/v5/context.go @@ -2,7 +2,6 @@ package chi import ( "context" - "net" "net/http" "strings" ) @@ -30,26 +29,6 @@ func RouteContext(ctx context.Context) *Context { return val } -// ServerBaseContext wraps an http.Handler to set the request context to the -// `baseCtx`. -func ServerBaseContext(baseCtx context.Context, h http.Handler) http.Handler { - fn := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - baseCtx := baseCtx - - // Copy over default net/http server context keys - if v, ok := ctx.Value(http.ServerContextKey).(*http.Server); ok { - baseCtx = context.WithValue(baseCtx, http.ServerContextKey, v) - } - if v, ok := ctx.Value(http.LocalAddrContextKey).(net.Addr); ok { - baseCtx = context.WithValue(baseCtx, http.LocalAddrContextKey, v) - } - - h.ServeHTTP(w, r.WithContext(baseCtx)) - }) - return fn -} - // NewRouteContext returns a new routing Context object. func NewRouteContext() *Context { return &Context{} @@ -66,31 +45,36 @@ var ( type Context struct { Routes Routes + // parentCtx is the parent of this one, for using Context as a + // context.Context directly. This is an optimization that saves + // 1 allocation. + parentCtx context.Context + // Routing path/method override used during the route search. // See Mux#routeHTTP method. RoutePath string RouteMethod string - // Routing pattern stack throughout the lifecycle of the request, - // across all connected routers. It is a record of all matching - // patterns across a stack of sub-routers. - RoutePatterns []string - // URLParams are the stack of routeParams captured during the // routing lifecycle across a stack of sub-routers. URLParams RouteParams + // Route parameters matched for the current sub-router. It is + // intentionally unexported so it can't be tampered. + routeParams RouteParams + // The endpoint routing pattern that matched the request URI path // or `RoutePath` of the current sub-router. This value will update // during the lifecycle of a request passing through a stack of // sub-routers. routePattern string - // Route parameters matched for the current sub-router. It is - // intentionally unexported so it cant be tampered. - routeParams RouteParams + // Routing pattern stack throughout the lifecycle of the request, + // across all connected routers. It is a record of all matching + // patterns across a stack of sub-routers. + RoutePatterns []string - // methodNotAllowed hint + methodsAllowed []methodTyp // allowed methods in case of a 405 methodNotAllowed bool } @@ -107,6 +91,8 @@ func (x *Context) Reset() { x.routeParams.Keys = x.routeParams.Keys[:0] x.routeParams.Values = x.routeParams.Values[:0] x.methodNotAllowed = false + x.methodsAllowed = x.methodsAllowed[:0] + x.parentCtx = nil } // URLParam returns the corresponding URL parameter value from the request @@ -123,29 +109,37 @@ func (x *Context) URLParam(key string) string { // RoutePattern builds the routing pattern string for the particular // request, at the particular point during routing. This means, the value // will change throughout the execution of a request in a router. That is -// why its advised to only use this value after calling the next handler. +// why it's advised to only use this value after calling the next handler. // // For example, // -// func Instrument(next http.Handler) http.Handler { -// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { -// next.ServeHTTP(w, r) -// routePattern := chi.RouteContext(r.Context()).RoutePattern() -// measure(w, r, routePattern) -// }) -// } +// func Instrument(next http.Handler) http.Handler { +// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { +// next.ServeHTTP(w, r) +// routePattern := chi.RouteContext(r.Context()).RoutePattern() +// measure(w, r, routePattern) +// }) +// } func (x *Context) RoutePattern() string { + if x == nil { + return "" + } routePattern := strings.Join(x.RoutePatterns, "") - return replaceWildcards(routePattern) + routePattern = replaceWildcards(routePattern) + if routePattern != "/" { + routePattern = strings.TrimSuffix(routePattern, "//") + routePattern = strings.TrimSuffix(routePattern, "/") + } + return routePattern } -// replaceWildcards takes a route pattern and recursively replaces all -// occurrences of "/*/" to "/". +// replaceWildcards takes a route pattern and replaces all occurrences of +// "/*/" with "/". It iteratively runs until no wildcards remain to +// correctly handle consecutive wildcards. func replaceWildcards(p string) string { - if strings.Contains(p, "/*/") { - return replaceWildcards(strings.Replace(p, "/*/", "/", -1)) + for strings.Contains(p, "/*/") { + p = strings.ReplaceAll(p, "/*/", "/") } - return p } diff --git a/vendor/github.com/go-chi/chi/middleware/basic_auth.go b/vendor/github.com/go-chi/chi/v5/middleware/basic_auth.go similarity index 87% rename from vendor/github.com/go-chi/chi/middleware/basic_auth.go rename to vendor/github.com/go-chi/chi/v5/middleware/basic_auth.go index 87b2641a6a..a546c9e9e8 100644 --- a/vendor/github.com/go-chi/chi/middleware/basic_auth.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/basic_auth.go @@ -1,6 +1,7 @@ package middleware import ( + "crypto/subtle" "fmt" "net/http" ) @@ -16,7 +17,7 @@ func BasicAuth(realm string, creds map[string]string) func(next http.Handler) ht } credPass, credUserOk := creds[user] - if !credUserOk || pass != credPass { + if !credUserOk || subtle.ConstantTimeCompare([]byte(pass), []byte(credPass)) != 1 { basicAuthFailed(w, realm) return } diff --git a/vendor/github.com/go-chi/chi/v5/middleware/clean_path.go b/vendor/github.com/go-chi/chi/v5/middleware/clean_path.go new file mode 100644 index 0000000000..adeba42951 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/middleware/clean_path.go @@ -0,0 +1,28 @@ +package middleware + +import ( + "net/http" + "path" + + "github.com/go-chi/chi/v5" +) + +// CleanPath middleware will clean out double slash mistakes from a user's request path. +// For example, if a user requests /users//1 or //users////1 will both be treated as: /users/1 +func CleanPath(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + rctx := chi.RouteContext(r.Context()) + + routePath := rctx.RoutePath + if routePath == "" { + if r.URL.RawPath != "" { + routePath = r.URL.RawPath + } else { + routePath = r.URL.Path + } + rctx.RoutePath = path.Clean(routePath) + } + + next.ServeHTTP(w, r) + }) +} diff --git a/vendor/github.com/go-chi/chi/middleware/compress.go b/vendor/github.com/go-chi/chi/v5/middleware/compress.go similarity index 87% rename from vendor/github.com/go-chi/chi/middleware/compress.go rename to vendor/github.com/go-chi/chi/v5/middleware/compress.go index 2f40cc15af..9c64bd48dc 100644 --- a/vendor/github.com/go-chi/chi/middleware/compress.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/compress.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "strings" @@ -45,7 +44,6 @@ func Compress(level int, types ...string) func(next http.Handler) http.Handler { // Compressor represents a set of encoding configurations. type Compressor struct { - level int // The compression level. // The mapping of encoder names to encoder functions. encoders map[string]EncoderFunc // The mapping of pooled encoders to pools. @@ -55,6 +53,7 @@ type Compressor struct { allowedWildcards map[string]struct{} // The list of encoders in order of decreasing precedence. encodingPrecedence []string + level int // The compression level. } // NewCompressor creates a new Compressor that will handle encoding responses. @@ -115,7 +114,7 @@ func NewCompressor(level int, types ...string) *Compressor { // https://web.archive.org/web/20120321182910/http://www.vervestudios.co/projects/compression-tests/results // // That's why we prefer gzip over deflate. It's just more reliable - // and not significantly slower than gzip. + // and not significantly slower than deflate. c.SetEncoder("deflate", encoderDeflate) // TODO: Exception for old MSIE browsers that can't handle non-HTML? @@ -135,16 +134,16 @@ func NewCompressor(level int, types ...string) *Compressor { // The encoding should be a standardised identifier. See: // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding // -// For example, add the Brotli algortithm: +// For example, add the Brotli algorithm: // -// import brotli_enc "gopkg.in/kothar/brotli-go.v0/enc" +// import brotli_enc "gopkg.in/kothar/brotli-go.v0/enc" // -// compressor := middleware.NewCompressor(5, "text/html") -// compressor.SetEncoder("br", func(w http.ResponseWriter, level int) io.Writer { -// params := brotli_enc.NewBrotliParams() -// params.SetQuality(level) -// return brotli_enc.NewBrotliWriter(params, w) -// }) +// compressor := middleware.NewCompressor(5, "text/html") +// compressor.SetEncoder("br", func(w io.Writer, level int) io.Writer { +// params := brotli_enc.NewBrotliParams() +// params.SetQuality(level) +// return brotli_enc.NewBrotliWriter(params, w) +// }) func (c *Compressor) SetEncoder(encoding string, fn EncoderFunc) { encoding = strings.ToLower(encoding) if encoding == "" { @@ -156,24 +155,18 @@ func (c *Compressor) SetEncoder(encoding string, fn EncoderFunc) { // If we are adding a new encoder that is already registered, we have to // clear that one out first. - if _, ok := c.pooledEncoders[encoding]; ok { - delete(c.pooledEncoders, encoding) - } - if _, ok := c.encoders[encoding]; ok { - delete(c.encoders, encoding) - } + delete(c.pooledEncoders, encoding) + delete(c.encoders, encoding) // If the encoder supports Resetting (IoReseterWriter), then it can be pooled. - encoder := fn(ioutil.Discard, c.level) - if encoder != nil { - if _, ok := encoder.(ioResetterWriter); ok { - pool := &sync.Pool{ - New: func() interface{} { - return fn(ioutil.Discard, c.level) - }, - } - c.pooledEncoders[encoding] = pool + encoder := fn(io.Discard, c.level) + if _, ok := encoder.(ioResetterWriter); ok { + pool := &sync.Pool{ + New: func() interface{} { + return fn(io.Discard, c.level) + }, } + c.pooledEncoders[encoding] = pool } // If the encoder is not in the pooledEncoders, add it to the normal encoders. if _, ok := c.pooledEncoders[encoding]; !ok { @@ -201,7 +194,7 @@ func (c *Compressor) Handler(next http.Handler) http.Handler { contentTypes: c.allowedTypes, contentWildcards: c.allowedWildcards, encoding: encoding, - compressable: false, // determined in post-handler + compressible: false, // determined in post-handler } if encoder != nil { cw.w = encoder @@ -271,26 +264,23 @@ type compressResponseWriter struct { // The streaming encoder writer to be used if there is one. Otherwise, // this is just the normal writer. w io.Writer - encoding string contentTypes map[string]struct{} contentWildcards map[string]struct{} + encoding string wroteHeader bool - compressable bool + compressible bool } -func (cw *compressResponseWriter) isCompressable() bool { +func (cw *compressResponseWriter) isCompressible() bool { // Parse the first part of the Content-Type response header. contentType := cw.Header().Get("Content-Type") - if idx := strings.Index(contentType, ";"); idx >= 0 { - contentType = contentType[0:idx] - } + contentType, _, _ = strings.Cut(contentType, ";") - // Is the content type compressable? + // Is the content type compressible? if _, ok := cw.contentTypes[contentType]; ok { return true } - if idx := strings.Index(contentType, "/"); idx > 0 { - contentType = contentType[0:idx] + if contentType, _, hadSlash := strings.Cut(contentType, "/"); hadSlash { _, ok := cw.contentWildcards[contentType] return ok } @@ -310,15 +300,15 @@ func (cw *compressResponseWriter) WriteHeader(code int) { return } - if !cw.isCompressable() { - cw.compressable = false + if !cw.isCompressible() { + cw.compressible = false return } if cw.encoding != "" { - cw.compressable = true + cw.compressible = true cw.Header().Set("Content-Encoding", cw.encoding) - cw.Header().Set("Vary", "Accept-Encoding") + cw.Header().Add("Vary", "Accept-Encoding") // The content-length after compression is unknown cw.Header().Del("Content-Length") @@ -334,11 +324,10 @@ func (cw *compressResponseWriter) Write(p []byte) (int, error) { } func (cw *compressResponseWriter) writer() io.Writer { - if cw.compressable { + if cw.compressible { return cw.w - } else { - return cw.ResponseWriter } + return cw.ResponseWriter } type compressFlusher interface { @@ -382,6 +371,10 @@ func (cw *compressResponseWriter) Close() error { return errors.New("chi/middleware: io.WriteCloser is unavailable on the writer") } +func (cw *compressResponseWriter) Unwrap() http.ResponseWriter { + return cw.ResponseWriter +} + func encoderGzip(w io.Writer, level int) io.Writer { gw, err := gzip.NewWriterLevel(w, level) if err != nil { diff --git a/vendor/github.com/go-chi/chi/middleware/content_charset.go b/vendor/github.com/go-chi/chi/v5/middleware/content_charset.go similarity index 88% rename from vendor/github.com/go-chi/chi/middleware/content_charset.go rename to vendor/github.com/go-chi/chi/v5/middleware/content_charset.go index 07b5ce6f66..07bff9f2e3 100644 --- a/vendor/github.com/go-chi/chi/middleware/content_charset.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/content_charset.go @@ -40,11 +40,10 @@ func contentEncoding(ce string, charsets ...string) bool { // Split a string in two parts, cleaning any whitespace. func split(str, sep string) (string, string) { - var a, b string - var parts = strings.SplitN(str, sep, 2) - a = strings.TrimSpace(parts[0]) - if len(parts) == 2 { - b = strings.TrimSpace(parts[1]) + a, b, found := strings.Cut(str, sep) + a = strings.TrimSpace(a) + if found { + b = strings.TrimSpace(b) } return a, b diff --git a/vendor/github.com/go-chi/chi/middleware/content_encoding.go b/vendor/github.com/go-chi/chi/v5/middleware/content_encoding.go similarity index 100% rename from vendor/github.com/go-chi/chi/middleware/content_encoding.go rename to vendor/github.com/go-chi/chi/v5/middleware/content_encoding.go diff --git a/vendor/github.com/go-chi/chi/v5/middleware/content_type.go b/vendor/github.com/go-chi/chi/v5/middleware/content_type.go new file mode 100644 index 0000000000..cdfc21eec5 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/middleware/content_type.go @@ -0,0 +1,45 @@ +package middleware + +import ( + "net/http" + "strings" +) + +// SetHeader is a convenience handler to set a response header key/value +func SetHeader(key, value string) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set(key, value) + next.ServeHTTP(w, r) + }) + } +} + +// AllowContentType enforces a whitelist of request Content-Types otherwise responds +// with a 415 Unsupported Media Type status. +func AllowContentType(contentTypes ...string) func(http.Handler) http.Handler { + allowedContentTypes := make(map[string]struct{}, len(contentTypes)) + for _, ctype := range contentTypes { + allowedContentTypes[strings.TrimSpace(strings.ToLower(ctype))] = struct{}{} + } + + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.ContentLength == 0 { + // Skip check for empty content body + next.ServeHTTP(w, r) + return + } + + s, _, _ := strings.Cut(r.Header.Get("Content-Type"), ";") + s = strings.ToLower(strings.TrimSpace(s)) + + if _, ok := allowedContentTypes[s]; ok { + next.ServeHTTP(w, r) + return + } + + w.WriteHeader(http.StatusUnsupportedMediaType) + }) + } +} diff --git a/vendor/github.com/go-chi/chi/middleware/get_head.go b/vendor/github.com/go-chi/chi/v5/middleware/get_head.go similarity index 97% rename from vendor/github.com/go-chi/chi/middleware/get_head.go rename to vendor/github.com/go-chi/chi/v5/middleware/get_head.go index 86068a96db..d4606d8be6 100644 --- a/vendor/github.com/go-chi/chi/middleware/get_head.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/get_head.go @@ -3,7 +3,7 @@ package middleware import ( "net/http" - "github.com/go-chi/chi" + "github.com/go-chi/chi/v5" ) // GetHead automatically route undefined HEAD requests to GET handlers. diff --git a/vendor/github.com/go-chi/chi/middleware/heartbeat.go b/vendor/github.com/go-chi/chi/v5/middleware/heartbeat.go similarity index 87% rename from vendor/github.com/go-chi/chi/middleware/heartbeat.go rename to vendor/github.com/go-chi/chi/v5/middleware/heartbeat.go index fe822fb536..f36e8ccf24 100644 --- a/vendor/github.com/go-chi/chi/middleware/heartbeat.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/heartbeat.go @@ -12,7 +12,7 @@ import ( func Heartbeat(endpoint string) func(http.Handler) http.Handler { f := func(h http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { - if r.Method == "GET" && strings.EqualFold(r.URL.Path, endpoint) { + if (r.Method == "GET" || r.Method == "HEAD") && strings.EqualFold(r.URL.Path, endpoint) { w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusOK) w.Write([]byte(".")) diff --git a/vendor/github.com/go-chi/chi/middleware/logger.go b/vendor/github.com/go-chi/chi/v5/middleware/logger.go similarity index 89% rename from vendor/github.com/go-chi/chi/middleware/logger.go rename to vendor/github.com/go-chi/chi/v5/middleware/logger.go index 158a6a3905..cff9bd2062 100644 --- a/vendor/github.com/go-chi/chi/middleware/logger.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/logger.go @@ -6,6 +6,7 @@ import ( "log" "net/http" "os" + "runtime" "time" ) @@ -16,7 +17,7 @@ var ( // DefaultLogger is called by the Logger middleware handler to log each request. // Its made a package-level variable so that it can be reconfigured for custom // logging configurations. - DefaultLogger = RequestLogger(&DefaultLogFormatter{Logger: log.New(os.Stdout, "", log.LstdFlags), NoColor: false}) + DefaultLogger func(next http.Handler) http.Handler ) // Logger is a middleware that logs the start and end of each request, along @@ -27,6 +28,14 @@ var ( // // Alternatively, look at https://github.com/goware/httplog for a more in-depth // http logger with structured logging support. +// +// IMPORTANT NOTE: Logger should go before any other middleware that may change +// the response, such as middleware.Recoverer. Example: +// +// r := chi.NewRouter() +// r.Use(middleware.Logger) // <--<< Logger should come before Recoverer +// r.Use(middleware.Recoverer) +// r.Get("/", handler) func Logger(next http.Handler) http.Handler { return DefaultLogger(next) } @@ -153,3 +162,11 @@ func (l *defaultLogEntry) Write(status, bytes int, header http.Header, elapsed t func (l *defaultLogEntry) Panic(v interface{}, stack []byte) { PrintPrettyStack(v) } + +func init() { + color := true + if runtime.GOOS == "windows" { + color = false + } + DefaultLogger = RequestLogger(&DefaultLogFormatter{Logger: log.New(os.Stdout, "", log.LstdFlags), NoColor: !color}) +} diff --git a/vendor/github.com/go-chi/chi/v5/middleware/maybe.go b/vendor/github.com/go-chi/chi/v5/middleware/maybe.go new file mode 100644 index 0000000000..eabca005a6 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/middleware/maybe.go @@ -0,0 +1,18 @@ +package middleware + +import "net/http" + +// Maybe middleware will allow you to change the flow of the middleware stack execution depending on return +// value of maybeFn(request). This is useful for example if you'd like to skip a middleware handler if +// a request does not satisfy the maybeFn logic. +func Maybe(mw func(http.Handler) http.Handler, maybeFn func(r *http.Request) bool) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if maybeFn(r) { + mw(next).ServeHTTP(w, r) + } else { + next.ServeHTTP(w, r) + } + }) + } +} diff --git a/vendor/github.com/go-chi/chi/middleware/middleware.go b/vendor/github.com/go-chi/chi/v5/middleware/middleware.go similarity index 100% rename from vendor/github.com/go-chi/chi/middleware/middleware.go rename to vendor/github.com/go-chi/chi/v5/middleware/middleware.go diff --git a/vendor/github.com/go-chi/chi/middleware/nocache.go b/vendor/github.com/go-chi/chi/v5/middleware/nocache.go similarity index 83% rename from vendor/github.com/go-chi/chi/middleware/nocache.go rename to vendor/github.com/go-chi/chi/v5/middleware/nocache.go index 2412829e1b..9308d40d73 100644 --- a/vendor/github.com/go-chi/chi/middleware/nocache.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/nocache.go @@ -9,7 +9,7 @@ import ( ) // Unix epoch time -var epoch = time.Unix(0, 0).Format(time.RFC1123) +var epoch = time.Unix(0, 0).UTC().Format(http.TimeFormat) // Taken from https://github.com/mytrile/nocache var noCacheHeaders = map[string]string{ @@ -32,10 +32,11 @@ var etagHeaders = []string{ // a router (or subrouter) from being cached by an upstream proxy and/or client. // // As per http://wiki.nginx.org/HttpProxyModule - NoCache sets: -// Expires: Thu, 01 Jan 1970 00:00:00 UTC -// Cache-Control: no-cache, private, max-age=0 -// X-Accel-Expires: 0 -// Pragma: no-cache (for HTTP/1.0 proxies/clients) +// +// Expires: Thu, 01 Jan 1970 00:00:00 UTC +// Cache-Control: no-cache, private, max-age=0 +// X-Accel-Expires: 0 +// Pragma: no-cache (for HTTP/1.0 proxies/clients) func NoCache(h http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { diff --git a/vendor/github.com/go-chi/chi/v5/middleware/page_route.go b/vendor/github.com/go-chi/chi/v5/middleware/page_route.go new file mode 100644 index 0000000000..32871b7e40 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/middleware/page_route.go @@ -0,0 +1,20 @@ +package middleware + +import ( + "net/http" + "strings" +) + +// PageRoute is a simple middleware which allows you to route a static GET request +// at the middleware stack level. +func PageRoute(path string, handler http.Handler) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method == "GET" && strings.EqualFold(r.URL.Path, path) { + handler.ServeHTTP(w, r) + return + } + next.ServeHTTP(w, r) + }) + } +} diff --git a/vendor/github.com/go-chi/chi/v5/middleware/path_rewrite.go b/vendor/github.com/go-chi/chi/v5/middleware/path_rewrite.go new file mode 100644 index 0000000000..99af62c0c3 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/middleware/path_rewrite.go @@ -0,0 +1,16 @@ +package middleware + +import ( + "net/http" + "strings" +) + +// PathRewrite is a simple middleware which allows you to rewrite the request URL path. +func PathRewrite(old, new string) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + r.URL.Path = strings.Replace(r.URL.Path, old, new, 1) + next.ServeHTTP(w, r) + }) + } +} diff --git a/vendor/github.com/go-chi/chi/v5/middleware/profiler.go b/vendor/github.com/go-chi/chi/v5/middleware/profiler.go new file mode 100644 index 0000000000..0ad6a996bc --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/middleware/profiler.go @@ -0,0 +1,49 @@ +//go:build !tinygo +// +build !tinygo + +package middleware + +import ( + "expvar" + "net/http" + "net/http/pprof" + + "github.com/go-chi/chi/v5" +) + +// Profiler is a convenient subrouter used for mounting net/http/pprof. ie. +// +// func MyService() http.Handler { +// r := chi.NewRouter() +// // ..middlewares +// r.Mount("/debug", middleware.Profiler()) +// // ..routes +// return r +// } +func Profiler() http.Handler { + r := chi.NewRouter() + r.Use(NoCache) + + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, r.RequestURI+"/pprof/", http.StatusMovedPermanently) + }) + r.HandleFunc("/pprof", func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, r.RequestURI+"/", http.StatusMovedPermanently) + }) + + r.HandleFunc("/pprof/*", pprof.Index) + r.HandleFunc("/pprof/cmdline", pprof.Cmdline) + r.HandleFunc("/pprof/profile", pprof.Profile) + r.HandleFunc("/pprof/symbol", pprof.Symbol) + r.HandleFunc("/pprof/trace", pprof.Trace) + r.Handle("/vars", expvar.Handler()) + + r.Handle("/pprof/goroutine", pprof.Handler("goroutine")) + r.Handle("/pprof/threadcreate", pprof.Handler("threadcreate")) + r.Handle("/pprof/mutex", pprof.Handler("mutex")) + r.Handle("/pprof/heap", pprof.Handler("heap")) + r.Handle("/pprof/block", pprof.Handler("block")) + r.Handle("/pprof/allocs", pprof.Handler("allocs")) + + return r +} diff --git a/vendor/github.com/go-chi/chi/middleware/realip.go b/vendor/github.com/go-chi/chi/v5/middleware/realip.go similarity index 74% rename from vendor/github.com/go-chi/chi/middleware/realip.go rename to vendor/github.com/go-chi/chi/v5/middleware/realip.go index 72db6ca9f5..afcb79e201 100644 --- a/vendor/github.com/go-chi/chi/middleware/realip.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/realip.go @@ -4,23 +4,25 @@ package middleware // https://github.com/zenazn/goji/tree/master/web/middleware import ( + "net" "net/http" "strings" ) +var trueClientIP = http.CanonicalHeaderKey("True-Client-IP") var xForwardedFor = http.CanonicalHeaderKey("X-Forwarded-For") var xRealIP = http.CanonicalHeaderKey("X-Real-IP") // RealIP is a middleware that sets a http.Request's RemoteAddr to the results -// of parsing either the X-Forwarded-For header or the X-Real-IP header (in that -// order). +// of parsing either the True-Client-IP, X-Real-IP or the X-Forwarded-For headers +// (in that order). // // This middleware should be inserted fairly early in the middleware stack to // ensure that subsequent layers (e.g., request loggers) which examine the // RemoteAddr will see the intended value. // // You should only use this middleware if you can trust the headers passed to -// you (in particular, the two headers this middleware uses), for example +// you (in particular, the three headers this middleware uses), for example // because you have placed a reverse proxy like HAProxy or nginx in front of // chi. If your reverse proxies are configured to pass along arbitrary header // values from the client, or if you use this middleware without a reverse @@ -40,15 +42,15 @@ func RealIP(h http.Handler) http.Handler { func realIP(r *http.Request) string { var ip string - if xrip := r.Header.Get(xRealIP); xrip != "" { + if tcip := r.Header.Get(trueClientIP); tcip != "" { + ip = tcip + } else if xrip := r.Header.Get(xRealIP); xrip != "" { ip = xrip } else if xff := r.Header.Get(xForwardedFor); xff != "" { - i := strings.Index(xff, ", ") - if i == -1 { - i = len(xff) - } - ip = xff[:i] + ip, _, _ = strings.Cut(xff, ",") + } + if ip == "" || net.ParseIP(ip) == nil { + return "" } - return ip } diff --git a/vendor/github.com/go-chi/chi/middleware/recoverer.go b/vendor/github.com/go-chi/chi/v5/middleware/recoverer.go similarity index 78% rename from vendor/github.com/go-chi/chi/middleware/recoverer.go rename to vendor/github.com/go-chi/chi/v5/middleware/recoverer.go index 785b18c52b..81342dfa7d 100644 --- a/vendor/github.com/go-chi/chi/middleware/recoverer.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/recoverer.go @@ -7,6 +7,7 @@ import ( "bytes" "errors" "fmt" + "io" "net/http" "os" "runtime/debug" @@ -17,11 +18,16 @@ import ( // backtrace), and returns a HTTP 500 (Internal Server Error) status if // possible. Recoverer prints a request ID if one is provided. // -// Alternatively, look at https://github.com/pressly/lg middleware pkgs. +// Alternatively, look at https://github.com/go-chi/httplog middleware pkgs. func Recoverer(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { defer func() { - if rvr := recover(); rvr != nil && rvr != http.ErrAbortHandler { + if rvr := recover(); rvr != nil { + if rvr == http.ErrAbortHandler { + // we don't recover http.ErrAbortHandler so the response + // to the client is aborted, this should not be logged + panic(rvr) + } logEntry := GetLogEntry(r) if logEntry != nil { @@ -30,7 +36,9 @@ func Recoverer(next http.Handler) http.Handler { PrintPrettyStack(rvr) } - w.WriteHeader(http.StatusInternalServerError) + if r.Header.Get("Connection") != "Upgrade" { + w.WriteHeader(http.StatusInternalServerError) + } } }() @@ -40,12 +48,15 @@ func Recoverer(next http.Handler) http.Handler { return http.HandlerFunc(fn) } +// for ability to test the PrintPrettyStack function +var recovererErrorWriter io.Writer = os.Stderr + func PrintPrettyStack(rvr interface{}) { debugStack := debug.Stack() s := prettyStack{} out, err := s.parse(debugStack, rvr) if err == nil { - os.Stderr.Write(out) + recovererErrorWriter.Write(out) } else { // print stdlib output as a fallback os.Stderr.Write(debugStack) @@ -72,7 +83,7 @@ func (s prettyStack) parse(debugStack []byte, rvr interface{}) ([]byte, error) { // locate panic line, as we may have nested panics for i := len(stack) - 1; i > 0; i-- { lines = append(lines, stack[i]) - if strings.HasPrefix(stack[i], "panic(0x") { + if strings.HasPrefix(stack[i], "panic(") { lines = lines[0 : len(lines)-2] // remove boilerplate break } @@ -102,15 +113,14 @@ func (s prettyStack) decorateLine(line string, useColor bool, num int) (string, line = strings.TrimSpace(line) if strings.HasPrefix(line, "\t") || strings.Contains(line, ".go:") { return s.decorateSourceLine(line, useColor, num) - } else if strings.HasSuffix(line, ")") { + } + if strings.HasSuffix(line, ")") { return s.decorateFuncCallLine(line, useColor, num) - } else { - if strings.HasPrefix(line, "\t") { - return strings.Replace(line, "\t", " ", 1), nil - } else { - return fmt.Sprintf(" %s\n", line), nil - } } + if strings.HasPrefix(line, "\t") { + return strings.Replace(line, "\t", " ", 1), nil + } + return fmt.Sprintf(" %s\n", line), nil } func (s prettyStack) decorateFuncCallLine(line string, useColor bool, num int) (string, error) { @@ -124,17 +134,18 @@ func (s prettyStack) decorateFuncCallLine(line string, useColor bool, num int) ( // addr := line[idx:] method := "" - idx = strings.LastIndex(pkg, string(os.PathSeparator)) - if idx < 0 { - idx = strings.Index(pkg, ".") - method = pkg[idx:] - pkg = pkg[0:idx] + if idx := strings.LastIndex(pkg, string(os.PathSeparator)); idx < 0 { + if idx := strings.Index(pkg, "."); idx > 0 { + method = pkg[idx:] + pkg = pkg[0:idx] + } } else { method = pkg[idx+1:] pkg = pkg[0 : idx+1] - idx = strings.Index(method, ".") - pkg += method[0:idx] - method = method[idx:] + if idx := strings.Index(method, "."); idx > 0 { + pkg += method[0:idx] + method = method[idx:] + } } pkgColor := nYellow methodColor := bGreen diff --git a/vendor/github.com/go-chi/chi/middleware/request_id.go b/vendor/github.com/go-chi/chi/v5/middleware/request_id.go similarity index 100% rename from vendor/github.com/go-chi/chi/middleware/request_id.go rename to vendor/github.com/go-chi/chi/v5/middleware/request_id.go diff --git a/vendor/github.com/go-chi/chi/v5/middleware/request_size.go b/vendor/github.com/go-chi/chi/v5/middleware/request_size.go new file mode 100644 index 0000000000..678248c461 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/middleware/request_size.go @@ -0,0 +1,18 @@ +package middleware + +import ( + "net/http" +) + +// RequestSize is a middleware that will limit request sizes to a specified +// number of bytes. It uses MaxBytesReader to do so. +func RequestSize(bytes int64) func(http.Handler) http.Handler { + f := func(h http.Handler) http.Handler { + fn := func(w http.ResponseWriter, r *http.Request) { + r.Body = http.MaxBytesReader(w, r.Body, bytes) + h.ServeHTTP(w, r) + } + return http.HandlerFunc(fn) + } + return f +} diff --git a/vendor/github.com/go-chi/chi/middleware/route_headers.go b/vendor/github.com/go-chi/chi/v5/middleware/route_headers.go similarity index 67% rename from vendor/github.com/go-chi/chi/middleware/route_headers.go rename to vendor/github.com/go-chi/chi/v5/middleware/route_headers.go index 7ee30c8773..88743769a7 100644 --- a/vendor/github.com/go-chi/chi/middleware/route_headers.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/route_headers.go @@ -11,46 +11,41 @@ import ( // For example, lets say you'd like to setup multiple routers depending on the // request Host header, you could then do something as so: // -// r := chi.NewRouter() -// rSubdomain := chi.NewRouter() -// -// r.Use(middleware.RouteHeaders(). -// Route("Host", "example.com", middleware.New(r)). -// Route("Host", "*.example.com", middleware.New(rSubdomain)). -// Handler) -// -// r.Get("/", h) -// rSubdomain.Get("/", h2) -// +// r := chi.NewRouter() +// rSubdomain := chi.NewRouter() +// r.Use(middleware.RouteHeaders(). +// Route("Host", "example.com", middleware.New(r)). +// Route("Host", "*.example.com", middleware.New(rSubdomain)). +// Handler) +// r.Get("/", h) +// rSubdomain.Get("/", h2) // // Another example, imagine you want to setup multiple CORS handlers, where for // your origin servers you allow authorized requests, but for third-party public // requests, authorization is disabled. // -// r := chi.NewRouter() -// -// r.Use(middleware.RouteHeaders(). -// Route("Origin", "https://app.skyweaver.net", cors.Handler(cors.Options{ -// AllowedOrigins: []string{"https://api.skyweaver.net"}, -// AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, -// AllowedHeaders: []string{"Accept", "Authorization", "Content-Type"}, -// AllowCredentials: true, // <----------<<< allow credentials -// })). -// Route("Origin", "*", cors.Handler(cors.Options{ -// AllowedOrigins: []string{"*"}, -// AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, -// AllowedHeaders: []string{"Accept", "Content-Type"}, -// AllowCredentials: false, // <----------<<< do not allow credentials -// })). -// Handler) -// +// r := chi.NewRouter() +// r.Use(middleware.RouteHeaders(). +// Route("Origin", "https://app.skyweaver.net", cors.Handler(cors.Options{ +// AllowedOrigins: []string{"https://api.skyweaver.net"}, +// AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, +// AllowedHeaders: []string{"Accept", "Authorization", "Content-Type"}, +// AllowCredentials: true, // <----------<<< allow credentials +// })). +// Route("Origin", "*", cors.Handler(cors.Options{ +// AllowedOrigins: []string{"*"}, +// AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, +// AllowedHeaders: []string{"Accept", "Content-Type"}, +// AllowCredentials: false, // <----------<<< do not allow credentials +// })). +// Handler) func RouteHeaders() HeaderRouter { return HeaderRouter{} } type HeaderRouter map[string][]HeaderRoute -func (hr HeaderRouter) Route(header string, match string, middlewareHandler func(next http.Handler) http.Handler) HeaderRouter { +func (hr HeaderRouter) Route(header, match string, middlewareHandler func(next http.Handler) http.Handler) HeaderRouter { header = strings.ToLower(header) k := hr[header] if k == nil { @@ -112,9 +107,9 @@ func (hr HeaderRouter) Handler(next http.Handler) http.Handler { } type HeaderRoute struct { - MatchAny []Pattern - MatchOne Pattern Middleware func(next http.Handler) http.Handler + MatchOne Pattern + MatchAny []Pattern } func (r HeaderRoute) IsMatch(value string) bool { @@ -138,23 +133,13 @@ type Pattern struct { func NewPattern(value string) Pattern { p := Pattern{} - if i := strings.IndexByte(value, '*'); i >= 0 { - p.wildcard = true - p.prefix = value[0:i] - p.suffix = value[i+1:] - } else { - p.prefix = value - } + p.prefix, p.suffix, p.wildcard = strings.Cut(value, "*") return p } func (p Pattern) Match(v string) bool { if !p.wildcard { - if p.prefix == v { - return true - } else { - return false - } + return p.prefix == v } return len(v) >= len(p.prefix+p.suffix) && strings.HasPrefix(v, p.prefix) && strings.HasSuffix(v, p.suffix) } diff --git a/vendor/github.com/go-chi/chi/middleware/strip.go b/vendor/github.com/go-chi/chi/v5/middleware/strip.go similarity index 64% rename from vendor/github.com/go-chi/chi/middleware/strip.go rename to vendor/github.com/go-chi/chi/v5/middleware/strip.go index 2b8b1842ab..17aa9bf32a 100644 --- a/vendor/github.com/go-chi/chi/middleware/strip.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/strip.go @@ -3,8 +3,9 @@ package middleware import ( "fmt" "net/http" + "strings" - "github.com/go-chi/chi" + "github.com/go-chi/chi/v5" ) // StripSlashes is a middleware that will match request paths with a trailing @@ -14,13 +15,18 @@ func StripSlashes(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { var path string rctx := chi.RouteContext(r.Context()) - if rctx.RoutePath != "" { + if rctx != nil && rctx.RoutePath != "" { path = rctx.RoutePath } else { path = r.URL.Path } if len(path) > 1 && path[len(path)-1] == '/' { - rctx.RoutePath = path[:len(path)-1] + newPath := path[:len(path)-1] + if rctx == nil { + r.URL.Path = newPath + } else { + rctx.RoutePath = newPath + } } next.ServeHTTP(w, r) } @@ -36,16 +42,16 @@ func RedirectSlashes(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { var path string rctx := chi.RouteContext(r.Context()) - if rctx.RoutePath != "" { + if rctx != nil && rctx.RoutePath != "" { path = rctx.RoutePath } else { path = r.URL.Path } if len(path) > 1 && path[len(path)-1] == '/' { + // Trim all leading and trailing slashes (e.g., "//evil.com", "/some/path//") + path = "/" + strings.Trim(path, "/") if r.URL.RawQuery != "" { - path = fmt.Sprintf("%s?%s", path[:len(path)-1], r.URL.RawQuery) - } else { - path = path[:len(path)-1] + path = fmt.Sprintf("%s?%s", path, r.URL.RawQuery) } http.Redirect(w, r, path, 301) return @@ -54,3 +60,11 @@ func RedirectSlashes(next http.Handler) http.Handler { } return http.HandlerFunc(fn) } + +// StripPrefix is a middleware that will strip the provided prefix from the +// request path before handing the request over to the next handler. +func StripPrefix(prefix string) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.StripPrefix(prefix, next) + } +} diff --git a/vendor/github.com/go-chi/chi/v5/middleware/sunset.go b/vendor/github.com/go-chi/chi/v5/middleware/sunset.go new file mode 100644 index 0000000000..18815d585d --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/middleware/sunset.go @@ -0,0 +1,25 @@ +package middleware + +import ( + "net/http" + "time" +) + +// Sunset set Deprecation/Sunset header to response +// This can be used to enable Sunset in a route or a route group +// For more: https://www.rfc-editor.org/rfc/rfc8594.html +func Sunset(sunsetAt time.Time, links ...string) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if !sunsetAt.IsZero() { + w.Header().Set("Sunset", sunsetAt.Format(http.TimeFormat)) + w.Header().Set("Deprecation", sunsetAt.Format(http.TimeFormat)) + + for _, link := range links { + w.Header().Add("Link", link) + } + } + next.ServeHTTP(w, r) + }) + } +} diff --git a/vendor/github.com/go-chi/chi/v5/middleware/supress_notfound.go b/vendor/github.com/go-chi/chi/v5/middleware/supress_notfound.go new file mode 100644 index 0000000000..83a8a87215 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/middleware/supress_notfound.go @@ -0,0 +1,27 @@ +package middleware + +import ( + "net/http" + + "github.com/go-chi/chi/v5" +) + +// SupressNotFound will quickly respond with a 404 if the route is not found +// and will not continue to the next middleware handler. +// +// This is handy to put at the top of your middleware stack to avoid unnecessary +// processing of requests that are not going to match any routes anyway. For +// example its super annoying to see a bunch of 404's in your logs from bots. +func SupressNotFound(router *chi.Mux) func(next http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + rctx := chi.RouteContext(r.Context()) + match := rctx.Routes.Match(rctx, r.Method, r.URL.Path) + if !match { + router.NotFoundHandler().ServeHTTP(w, r) + return + } + next.ServeHTTP(w, r) + }) + } +} diff --git a/vendor/github.com/go-chi/chi/middleware/terminal.go b/vendor/github.com/go-chi/chi/v5/middleware/terminal.go similarity index 100% rename from vendor/github.com/go-chi/chi/middleware/terminal.go rename to vendor/github.com/go-chi/chi/v5/middleware/terminal.go diff --git a/vendor/github.com/go-chi/chi/middleware/throttle.go b/vendor/github.com/go-chi/chi/v5/middleware/throttle.go similarity index 80% rename from vendor/github.com/go-chi/chi/middleware/throttle.go rename to vendor/github.com/go-chi/chi/v5/middleware/throttle.go index fdedd3c127..7ea482b91d 100644 --- a/vendor/github.com/go-chi/chi/middleware/throttle.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/throttle.go @@ -18,15 +18,16 @@ var ( // ThrottleOpts represents a set of throttling options. type ThrottleOpts struct { + RetryAfterFn func(ctxDone bool) time.Duration Limit int BacklogLimit int BacklogTimeout time.Duration - RetryAfterFn func(ctxDone bool) time.Duration + StatusCode int } // Throttle is a middleware that limits number of currently processed requests // at a time across all users. Note: Throttle is not a rate-limiter per user, -// instead it just puts a ceiling on the number of currentl in-flight requests +// instead it just puts a ceiling on the number of current in-flight requests // being processed from the point from where the Throttle middleware is mounted. func Throttle(limit int) func(http.Handler) http.Handler { return ThrottleWithOpts(ThrottleOpts{Limit: limit, BacklogTimeout: defaultBacklogTimeout}) @@ -35,7 +36,7 @@ func Throttle(limit int) func(http.Handler) http.Handler { // ThrottleBacklog is a middleware that limits number of currently processed // requests at a time and provides a backlog for holding a finite number of // pending requests. -func ThrottleBacklog(limit int, backlogLimit int, backlogTimeout time.Duration) func(http.Handler) http.Handler { +func ThrottleBacklog(limit, backlogLimit int, backlogTimeout time.Duration) func(http.Handler) http.Handler { return ThrottleWithOpts(ThrottleOpts{Limit: limit, BacklogLimit: backlogLimit, BacklogTimeout: backlogTimeout}) } @@ -49,10 +50,16 @@ func ThrottleWithOpts(opts ThrottleOpts) func(http.Handler) http.Handler { panic("chi/middleware: Throttle expects backlogLimit to be positive") } + statusCode := opts.StatusCode + if statusCode == 0 { + statusCode = http.StatusTooManyRequests + } + t := throttler{ tokens: make(chan token, opts.Limit), backlogTokens: make(chan token, opts.Limit+opts.BacklogLimit), backlogTimeout: opts.BacklogTimeout, + statusCode: statusCode, retryAfterFn: opts.RetryAfterFn, } @@ -72,25 +79,36 @@ func ThrottleWithOpts(opts ThrottleOpts) func(http.Handler) http.Handler { case <-ctx.Done(): t.setRetryAfterHeaderIfNeeded(w, true) - http.Error(w, errContextCanceled, http.StatusServiceUnavailable) + http.Error(w, errContextCanceled, t.statusCode) return case btok := <-t.backlogTokens: - timer := time.NewTimer(t.backlogTimeout) - defer func() { t.backlogTokens <- btok }() + // Try to get a processing token immediately first + select { + case tok := <-t.tokens: + defer func() { + t.tokens <- tok + }() + next.ServeHTTP(w, r) + return + default: + // No immediate token available, need to wait with timer + } + + timer := time.NewTimer(t.backlogTimeout) select { case <-timer.C: t.setRetryAfterHeaderIfNeeded(w, false) - http.Error(w, errTimedOut, http.StatusServiceUnavailable) + http.Error(w, errTimedOut, t.statusCode) return case <-ctx.Done(): timer.Stop() t.setRetryAfterHeaderIfNeeded(w, true) - http.Error(w, errContextCanceled, http.StatusServiceUnavailable) + http.Error(w, errContextCanceled, t.statusCode) return case tok := <-t.tokens: defer func() { @@ -103,7 +121,7 @@ func ThrottleWithOpts(opts ThrottleOpts) func(http.Handler) http.Handler { default: t.setRetryAfterHeaderIfNeeded(w, false) - http.Error(w, errCapacityExceeded, http.StatusServiceUnavailable) + http.Error(w, errCapacityExceeded, t.statusCode) return } } @@ -119,8 +137,9 @@ type token struct{} type throttler struct { tokens chan token backlogTokens chan token - backlogTimeout time.Duration retryAfterFn func(ctxDone bool) time.Duration + backlogTimeout time.Duration + statusCode int } // setRetryAfterHeaderIfNeeded sets Retry-After HTTP header if corresponding retryAfterFn option of throttler is initialized. diff --git a/vendor/github.com/go-chi/chi/middleware/timeout.go b/vendor/github.com/go-chi/chi/v5/middleware/timeout.go similarity index 72% rename from vendor/github.com/go-chi/chi/middleware/timeout.go rename to vendor/github.com/go-chi/chi/v5/middleware/timeout.go index 8e373536cf..add596d69a 100644 --- a/vendor/github.com/go-chi/chi/middleware/timeout.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/timeout.go @@ -15,21 +15,20 @@ import ( // // ie. a route/handler may look like: // -// r.Get("/long", func(w http.ResponseWriter, r *http.Request) { -// ctx := r.Context() -// processTime := time.Duration(rand.Intn(4)+1) * time.Second +// r.Get("/long", func(w http.ResponseWriter, r *http.Request) { +// ctx := r.Context() +// processTime := time.Duration(rand.Intn(4)+1) * time.Second // -// select { -// case <-ctx.Done(): -// return +// select { +// case <-ctx.Done(): +// return // -// case <-time.After(processTime): -// // The above channel simulates some hard work. -// } -// -// w.Write([]byte("done")) -// }) +// case <-time.After(processTime): +// // The above channel simulates some hard work. +// } // +// w.Write([]byte("done")) +// }) func Timeout(timeout time.Duration) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { diff --git a/vendor/github.com/go-chi/chi/middleware/url_format.go b/vendor/github.com/go-chi/chi/v5/middleware/url_format.go similarity index 55% rename from vendor/github.com/go-chi/chi/middleware/url_format.go rename to vendor/github.com/go-chi/chi/v5/middleware/url_format.go index 5749e4f32b..2ec6657e18 100644 --- a/vendor/github.com/go-chi/chi/middleware/url_format.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/url_format.go @@ -5,7 +5,7 @@ import ( "net/http" "strings" - "github.com/go-chi/chi" + "github.com/go-chi/chi/v5" ) var ( @@ -20,30 +20,29 @@ var ( // // Routers should not include a url parameter for the suffix when using this middleware. // -// Sample usage.. for url paths: `/articles/1`, `/articles/1.json` and `/articles/1.xml` +// Sample usage for url paths `/articles/1`, `/articles/1.json` and `/articles/1.xml`: // -// func routes() http.Handler { -// r := chi.NewRouter() -// r.Use(middleware.URLFormat) +// func routes() http.Handler { +// r := chi.NewRouter() +// r.Use(middleware.URLFormat) // -// r.Get("/articles/{id}", ListArticles) +// r.Get("/articles/{id}", ListArticles) // -// return r -// } +// return r +// } // -// func ListArticles(w http.ResponseWriter, r *http.Request) { -// urlFormat, _ := r.Context().Value(middleware.URLFormatCtxKey).(string) -// -// switch urlFormat { -// case "json": -// render.JSON(w, r, articles) -// case "xml:" -// render.XML(w, r, articles) -// default: -// render.JSON(w, r, articles) -// } -// } +// func ListArticles(w http.ResponseWriter, r *http.Request) { +// urlFormat, _ := r.Context().Value(middleware.URLFormatCtxKey).(string) // +// switch urlFormat { +// case "json": +// render.JSON(w, r, articles) +// case "xml:" +// render.XML(w, r, articles) +// default: +// render.JSON(w, r, articles) +// } +// } func URLFormat(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { ctx := r.Context() @@ -51,16 +50,22 @@ func URLFormat(next http.Handler) http.Handler { var format string path := r.URL.Path + rctx := chi.RouteContext(r.Context()) + if rctx != nil && rctx.RoutePath != "" { + path = rctx.RoutePath + } + if strings.Index(path, ".") > 0 { base := strings.LastIndex(path, "/") - idx := strings.Index(path[base:], ".") + idx := strings.LastIndex(path[base:], ".") if idx > 0 { idx += base format = path[idx+1:] - rctx := chi.RouteContext(r.Context()) - rctx.RoutePath = path[:idx] + if rctx != nil { + rctx.RoutePath = path[:idx] + } } } diff --git a/vendor/github.com/go-chi/chi/middleware/value.go b/vendor/github.com/go-chi/chi/v5/middleware/value.go similarity index 80% rename from vendor/github.com/go-chi/chi/middleware/value.go rename to vendor/github.com/go-chi/chi/v5/middleware/value.go index fbbd0393fb..a9dfd4345d 100644 --- a/vendor/github.com/go-chi/chi/middleware/value.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/value.go @@ -6,7 +6,7 @@ import ( ) // WithValue is a middleware that sets a given key/value in a context chain. -func WithValue(key interface{}, val interface{}) func(next http.Handler) http.Handler { +func WithValue(key, val interface{}) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { r = r.WithContext(context.WithValue(r.Context(), key, val)) diff --git a/vendor/github.com/go-chi/chi/middleware/wrap_writer.go b/vendor/github.com/go-chi/chi/v5/middleware/wrap_writer.go similarity index 71% rename from vendor/github.com/go-chi/chi/middleware/wrap_writer.go rename to vendor/github.com/go-chi/chi/v5/middleware/wrap_writer.go index 382a523e48..367e0fcd92 100644 --- a/vendor/github.com/go-chi/chi/middleware/wrap_writer.go +++ b/vendor/github.com/go-chi/chi/v5/middleware/wrap_writer.go @@ -28,7 +28,14 @@ func NewWrapResponseWriter(w http.ResponseWriter, protoMajor int) WrapResponseWr if fl && hj && rf { return &httpFancyWriter{bw} } + if fl && hj { + return &flushHijackWriter{bw} + } + if hj { + return &hijackWriter{bw} + } } + if fl { return &flushWriter{bw} } @@ -54,35 +61,53 @@ type WrapResponseWriter interface { Tee(io.Writer) // Unwrap returns the original proxied target. Unwrap() http.ResponseWriter + // Discard causes all writes to the original ResponseWriter be discarded, + // instead writing only to the tee'd writer if it's set. + // The caller is responsible for calling WriteHeader and Write on the + // original ResponseWriter once the processing is done. + Discard() } // basicWriter wraps a http.ResponseWriter that implements the minimal // http.ResponseWriter interface. type basicWriter struct { http.ResponseWriter - wroteHeader bool + tee io.Writer code int bytes int - tee io.Writer + wroteHeader bool + discard bool } func (b *basicWriter) WriteHeader(code int) { - if !b.wroteHeader { + if code >= 100 && code <= 199 && code != http.StatusSwitchingProtocols { + if !b.discard { + b.ResponseWriter.WriteHeader(code) + } + } else if !b.wroteHeader { b.code = code b.wroteHeader = true - b.ResponseWriter.WriteHeader(code) + if !b.discard { + b.ResponseWriter.WriteHeader(code) + } } } -func (b *basicWriter) Write(buf []byte) (int, error) { +func (b *basicWriter) Write(buf []byte) (n int, err error) { b.maybeWriteHeader() - n, err := b.ResponseWriter.Write(buf) - if b.tee != nil { - _, err2 := b.tee.Write(buf[:n]) - // Prefer errors generated by the proxied writer. - if err == nil { - err = err2 + if !b.discard { + n, err = b.ResponseWriter.Write(buf) + if b.tee != nil { + _, err2 := b.tee.Write(buf[:n]) + // Prefer errors generated by the proxied writer. + if err == nil { + err = err2 + } } + } else if b.tee != nil { + n, err = b.tee.Write(buf) + } else { + n, err = io.Discard.Write(buf) } b.bytes += n return n, err @@ -110,6 +135,11 @@ func (b *basicWriter) Unwrap() http.ResponseWriter { return b.ResponseWriter } +func (b *basicWriter) Discard() { + b.discard = true +} + +// flushWriter ... type flushWriter struct { basicWriter } @@ -122,6 +152,37 @@ func (f *flushWriter) Flush() { var _ http.Flusher = &flushWriter{} +// hijackWriter ... +type hijackWriter struct { + basicWriter +} + +func (f *hijackWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + hj := f.basicWriter.ResponseWriter.(http.Hijacker) + return hj.Hijack() +} + +var _ http.Hijacker = &hijackWriter{} + +// flushHijackWriter ... +type flushHijackWriter struct { + basicWriter +} + +func (f *flushHijackWriter) Flush() { + f.wroteHeader = true + fl := f.basicWriter.ResponseWriter.(http.Flusher) + fl.Flush() +} + +func (f *flushHijackWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + hj := f.basicWriter.ResponseWriter.(http.Hijacker) + return hj.Hijack() +} + +var _ http.Flusher = &flushHijackWriter{} +var _ http.Hijacker = &flushHijackWriter{} + // httpFancyWriter is a HTTP writer that additionally satisfies // http.Flusher, http.Hijacker, and io.ReaderFrom. It exists for the common case // of wrapping the http.ResponseWriter that package http gives you, in order to diff --git a/vendor/github.com/go-chi/chi/mux.go b/vendor/github.com/go-chi/chi/v5/mux.go similarity index 83% rename from vendor/github.com/go-chi/chi/mux.go rename to vendor/github.com/go-chi/chi/v5/mux.go index 52950e97b5..ad66bba91c 100644 --- a/vendor/github.com/go-chi/chi/mux.go +++ b/vendor/github.com/go-chi/chi/v5/mux.go @@ -19,29 +19,32 @@ var _ Router = &Mux{} // particularly useful for writing large REST API services that break a handler // into many smaller parts composed of middlewares and end handlers. type Mux struct { + // The computed mux handler made of the chained middleware stack and + // the tree router + handler http.Handler + // The radix trie router tree *node - // The middleware stack - middlewares []func(http.Handler) http.Handler + // Custom method not allowed handler + methodNotAllowedHandler http.HandlerFunc - // Controls the behaviour of middleware chain generation when a mux - // is registered as an inline group inside another mux. - inline bool + // A reference to the parent mux used by subrouters when mounting + // to a parent mux parent *Mux - // The computed mux handler made of the chained middleware stack and - // the tree router - handler http.Handler - // Routing context pool pool *sync.Pool // Custom route not found handler notFoundHandler http.HandlerFunc - // Custom method not allowed handler - methodNotAllowedHandler http.HandlerFunc + // The middleware stack + middlewares []func(http.Handler) http.Handler + + // Controls the behaviour of middleware chain generation when a mux + // is registered as an inline group inside another mux. + inline bool } // NewMux returns a newly initialized Mux object that implements the Router @@ -78,6 +81,7 @@ func (mx *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) { rctx = mx.pool.Get().(*Context) rctx.Reset() rctx.Routes = mx + rctx.parentCtx = r.Context() // NOTE: r.WithContext() causes 2 allocations and context.WithValue() causes 1 allocation r = r.WithContext(context.WithValue(r.Context(), RouteCtxKey, rctx)) @@ -103,13 +107,19 @@ func (mx *Mux) Use(middlewares ...func(http.Handler) http.Handler) { // Handle adds the route `pattern` that matches any http method to // execute the `handler` http.Handler. func (mx *Mux) Handle(pattern string, handler http.Handler) { + if i := strings.IndexAny(pattern, " \t"); i >= 0 { + method, rest := pattern[:i], strings.TrimLeft(pattern[i+1:], " \t") + mx.Method(method, rest, handler) + return + } + mx.handle(mALL, pattern, handler) } // HandleFunc adds the route `pattern` that matches any http method to // execute the `handlerFn` http.HandlerFunc. func (mx *Mux) HandleFunc(pattern string, handlerFn http.HandlerFunc) { - mx.handle(mALL, pattern, handlerFn) + mx.Handle(pattern, handlerFn) } // Method adds the route `pattern` that matches `method` http method to @@ -152,7 +162,7 @@ func (mx *Mux) Head(pattern string, handlerFn http.HandlerFunc) { mx.handle(mHEAD, pattern, handlerFn) } -// Options adds the route `pattern` that matches a OPTIONS http method to +// Options adds the route `pattern` that matches an OPTIONS http method to // execute the `handlerFn` http.HandlerFunc. func (mx *Mux) Options(pattern string, handlerFn http.HandlerFunc) { mx.handle(mOPTIONS, pattern, handlerFn) @@ -227,7 +237,7 @@ func (mx *Mux) With(middlewares ...func(http.Handler) http.Handler) Router { // Similarly as in handle(), we must build the mux handler once additional // middleware registration isn't allowed for this stack, like now. if !mx.inline && mx.handler == nil { - mx.buildRouteHandler() + mx.updateRouteHandler() } // Copy middlewares from parent inline muxs @@ -246,25 +256,25 @@ func (mx *Mux) With(middlewares ...func(http.Handler) http.Handler) Router { return im } -// Group creates a new inline-Mux with a fresh middleware stack. It's useful +// Group creates a new inline-Mux with a copy of middleware stack. It's useful // for a group of handlers along the same routing path that use an additional // set of middlewares. See _examples/. func (mx *Mux) Group(fn func(r Router)) Router { - im := mx.With().(*Mux) + im := mx.With() if fn != nil { fn(im) } return im } -// Route creates a new Mux with a fresh middleware stack and mounts it -// along the `pattern` as a subrouter. Effectively, this is a short-hand -// call to Mount. See _examples/. +// Route creates a new Mux and mounts it along the `pattern` as a subrouter. +// Effectively, this is a short-hand call to Mount. See _examples/. func (mx *Mux) Route(pattern string, fn func(r Router)) Router { - subRouter := NewRouter() - if fn != nil { - fn(subRouter) + if fn == nil { + panic(fmt.Sprintf("chi: attempting to Route() a nil subrouter on '%s'", pattern)) } + subRouter := NewRouter() + fn(subRouter) mx.Mount(pattern, subRouter) return subRouter } @@ -277,6 +287,10 @@ func (mx *Mux) Route(pattern string, fn func(r Router)) Router { // routing at the `handler`, which in most cases is another chi.Router. As a result, // if you define two Mount() routes on the exact same pattern the mount will panic. func (mx *Mux) Mount(pattern string, handler http.Handler) { + if handler == nil { + panic(fmt.Sprintf("chi: attempting to Mount() a nil handler on '%s'", pattern)) + } + // Provide runtime safety for ensuring a pattern isn't mounted on an existing // routing pattern. if mx.tree.findPattern(pattern+"*") || mx.tree.findPattern(pattern+"/*") { @@ -294,7 +308,16 @@ func (mx *Mux) Mount(pattern string, handler http.Handler) { mountHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { rctx := RouteContext(r.Context()) + + // shift the url path past the previous subrouter rctx.RoutePath = mx.nextRoutePath(rctx) + + // reset the wildcard URLParam which connects the subrouter + n := len(rctx.URLParams.Keys) - 1 + if n >= 0 && rctx.URLParams.Keys[n] == "*" && len(rctx.URLParams.Values) > n { + rctx.URLParams.Values[n] = "" + } + handler.ServeHTTP(w, r) }) @@ -334,19 +357,40 @@ func (mx *Mux) Middlewares() Middlewares { // Note: the *Context state is updated during execution, so manage // the state carefully or make a NewRouteContext(). func (mx *Mux) Match(rctx *Context, method, path string) bool { + return mx.Find(rctx, method, path) != "" +} + +// Find searches the routing tree for the pattern that matches +// the method/path. +// +// Note: the *Context state is updated during execution, so manage +// the state carefully or make a NewRouteContext(). +func (mx *Mux) Find(rctx *Context, method, path string) string { m, ok := methodMap[method] if !ok { - return false + return "" } - node, _, h := mx.tree.FindRoute(rctx, m, path) + node, _, _ := mx.tree.FindRoute(rctx, m, path) + pattern := rctx.routePattern + + if node != nil { + if node.subroutes == nil { + e := node.endpoints[m] + return e.pattern + } - if node != nil && node.subroutes != nil { rctx.RoutePath = mx.nextRoutePath(rctx) - return node.subroutes.Match(rctx, method, rctx.RoutePath) + subPattern := node.subroutes.Find(rctx, method, rctx.RoutePath) + if subPattern == "" { + return "" + } + + pattern = strings.TrimSuffix(pattern, "/*") + pattern += subPattern } - return h != nil + return pattern } // NotFoundHandler returns the default Mux 404 responder whenever a route @@ -360,19 +404,11 @@ func (mx *Mux) NotFoundHandler() http.HandlerFunc { // MethodNotAllowedHandler returns the default Mux 405 responder whenever // a method cannot be resolved for a route. -func (mx *Mux) MethodNotAllowedHandler() http.HandlerFunc { +func (mx *Mux) MethodNotAllowedHandler(methodsAllowed ...methodTyp) http.HandlerFunc { if mx.methodNotAllowedHandler != nil { return mx.methodNotAllowedHandler } - return methodNotAllowedHandler -} - -// buildRouteHandler builds the single mux handler that is a chain of the middleware -// stack, as defined by calls to Use(), and the tree router (Mux) itself. After this -// point, no other middlewares can be registered on this Mux's stack. But you can still -// compose additional middlewares via Group()'s or using a chained middleware handler. -func (mx *Mux) buildRouteHandler() { - mx.handler = chain(mx.middlewares, http.HandlerFunc(mx.routeHTTP)) + return methodNotAllowedHandler(methodsAllowed...) } // handle registers a http.Handler in the routing tree for a particular http method @@ -384,7 +420,7 @@ func (mx *Mux) handle(method methodTyp, pattern string, handler http.Handler) *n // Build the computed routing handler for this routing pattern. if !mx.inline && mx.handler == nil { - mx.buildRouteHandler() + mx.updateRouteHandler() } // Build endpoint handler with inline middlewares for the route @@ -414,6 +450,9 @@ func (mx *Mux) routeHTTP(w http.ResponseWriter, r *http.Request) { } else { routePath = r.URL.Path } + if routePath == "" { + routePath = "/" + } } // Check if method is supported by chi @@ -428,11 +467,18 @@ func (mx *Mux) routeHTTP(w http.ResponseWriter, r *http.Request) { // Find the route if _, _, h := mx.tree.FindRoute(rctx, method, routePath); h != nil { + if supportsPathValue { + setPathValue(rctx, r) + } + if supportsPattern { + setPattern(rctx, r) + } + h.ServeHTTP(w, r) return } if rctx.methodNotAllowed { - mx.MethodNotAllowedHandler().ServeHTTP(w, r) + mx.MethodNotAllowedHandler(rctx.methodsAllowed...).ServeHTTP(w, r) } else { mx.NotFoundHandler().ServeHTTP(w, r) } @@ -458,9 +504,23 @@ func (mx *Mux) updateSubRoutes(fn func(subMux *Mux)) { } } +// updateRouteHandler builds the single mux handler that is a chain of the middleware +// stack, as defined by calls to Use(), and the tree router (Mux) itself. After this +// point, no other middlewares can be registered on this Mux's stack. But you can still +// compose additional middlewares via Group()'s or using a chained middleware handler. +func (mx *Mux) updateRouteHandler() { + mx.handler = chain(mx.middlewares, http.HandlerFunc(mx.routeHTTP)) +} + // methodNotAllowedHandler is a helper function to respond with a 405, -// method not allowed. -func methodNotAllowedHandler(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(405) - w.Write(nil) +// method not allowed. It sets the Allow header with the list of allowed +// methods for the route. +func methodNotAllowedHandler(methodsAllowed ...methodTyp) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + for _, m := range methodsAllowed { + w.Header().Add("Allow", reverseMethodMap[m]) + } + w.WriteHeader(405) + w.Write(nil) + } } diff --git a/vendor/github.com/go-chi/chi/v5/path_value.go b/vendor/github.com/go-chi/chi/v5/path_value.go new file mode 100644 index 0000000000..77c840f019 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/path_value.go @@ -0,0 +1,21 @@ +//go:build go1.22 && !tinygo +// +build go1.22,!tinygo + + +package chi + +import "net/http" + +// supportsPathValue is true if the Go version is 1.22 and above. +// +// If this is true, `net/http.Request` has methods `SetPathValue` and `PathValue`. +const supportsPathValue = true + +// setPathValue sets the path values in the Request value +// based on the provided request context. +func setPathValue(rctx *Context, r *http.Request) { + for i, key := range rctx.URLParams.Keys { + value := rctx.URLParams.Values[i] + r.SetPathValue(key, value) + } +} diff --git a/vendor/github.com/go-chi/chi/v5/path_value_fallback.go b/vendor/github.com/go-chi/chi/v5/path_value_fallback.go new file mode 100644 index 0000000000..749a8520a7 --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/path_value_fallback.go @@ -0,0 +1,19 @@ +//go:build !go1.22 || tinygo +// +build !go1.22 tinygo + +package chi + +import "net/http" + +// supportsPathValue is true if the Go version is 1.22 and above. +// +// If this is true, `net/http.Request` has methods `SetPathValue` and `PathValue`. +const supportsPathValue = false + +// setPathValue sets the path values in the Request value +// based on the provided request context. +// +// setPathValue is only supported in Go 1.22 and above so +// this is just a blank function so that it compiles. +func setPathValue(rctx *Context, r *http.Request) { +} diff --git a/vendor/github.com/go-chi/chi/v5/pattern.go b/vendor/github.com/go-chi/chi/v5/pattern.go new file mode 100644 index 0000000000..890a2c217f --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/pattern.go @@ -0,0 +1,16 @@ +//go:build go1.23 && !tinygo +// +build go1.23,!tinygo + +package chi + +import "net/http" + +// supportsPattern is true if the Go version is 1.23 and above. +// +// If this is true, `net/http.Request` has field `Pattern`. +const supportsPattern = true + +// setPattern sets the mux matched pattern in the http Request. +func setPattern(rctx *Context, r *http.Request) { + r.Pattern = rctx.routePattern +} diff --git a/vendor/github.com/go-chi/chi/v5/pattern_fallback.go b/vendor/github.com/go-chi/chi/v5/pattern_fallback.go new file mode 100644 index 0000000000..48a94ef82d --- /dev/null +++ b/vendor/github.com/go-chi/chi/v5/pattern_fallback.go @@ -0,0 +1,17 @@ +//go:build !go1.23 || tinygo +// +build !go1.23 tinygo + +package chi + +import "net/http" + +// supportsPattern is true if the Go version is 1.23 and above. +// +// If this is true, `net/http.Request` has field `Pattern`. +const supportsPattern = false + +// setPattern sets the mux matched pattern in the http Request. +// +// setPattern is only supported in Go 1.23 and above so +// this is just a blank function so that it compiles. +func setPattern(rctx *Context, r *http.Request) {} diff --git a/vendor/github.com/go-chi/chi/tree.go b/vendor/github.com/go-chi/chi/v5/tree.go similarity index 95% rename from vendor/github.com/go-chi/chi/tree.go rename to vendor/github.com/go-chi/chi/v5/tree.go index 59b5b5f7b0..bcb86b6f17 100644 --- a/vendor/github.com/go-chi/chi/tree.go +++ b/vendor/github.com/go-chi/chi/v5/tree.go @@ -6,7 +6,6 @@ package chi import ( "fmt" - "math" "net/http" "regexp" "sort" @@ -14,7 +13,7 @@ import ( "strings" ) -type methodTyp int +type methodTyp uint const ( mSTUB methodTyp = 1 << iota @@ -44,6 +43,18 @@ var methodMap = map[string]methodTyp{ http.MethodTrace: mTRACE, } +var reverseMethodMap = map[methodTyp]string{ + mCONNECT: http.MethodConnect, + mDELETE: http.MethodDelete, + mGET: http.MethodGet, + mHEAD: http.MethodHead, + mOPTIONS: http.MethodOptions, + mPATCH: http.MethodPatch, + mPOST: http.MethodPost, + mPUT: http.MethodPut, + mTRACE: http.MethodTrace, +} + // RegisterMethod adds support for custom HTTP method handlers, available // via Router#Method and Router#MethodFunc func RegisterMethod(method string) { @@ -55,10 +66,10 @@ func RegisterMethod(method string) { return } n := len(methodMap) - if n > strconv.IntSize { + if n > strconv.IntSize-2 { panic(fmt.Sprintf("chi: max number of methods reached (%d)", strconv.IntSize)) } - mt := methodTyp(math.Exp2(float64(n))) + mt := methodTyp(2 << n) methodMap[method] = mt mALL |= mt } @@ -73,17 +84,8 @@ const ( ) type node struct { - // node type: static, regexp, param, catchAll - typ nodeTyp - - // first byte of the prefix - label byte - - // first byte of the child prefix - tail byte - - // prefix is the common prefix we ignore - prefix string + // subroutes on the leaf node + subroutes Routes // regexp matcher for regexp nodes rex *regexp.Regexp @@ -91,12 +93,21 @@ type node struct { // HTTP handler endpoints on the leaf node endpoints endpoints - // subroutes on the leaf node - subroutes Routes + // prefix is the common prefix we ignore + prefix string // child nodes should be stored in-order for iteration, // in groups of the node type. children [ntCatchAll + 1]nodes + + // first byte of the child prefix + tail byte + + // node type: static, regexp, param, catchAll + typ nodeTyp + + // first byte of the prefix + label byte } // endpoints is a mapping of http method constants to handlers @@ -430,10 +441,12 @@ func (n *node) findRoute(rctx *Context, method methodTyp, path string) *node { } else { continue } + } else if ntyp == ntRegexp && p == 0 { + continue } if ntyp == ntRegexp && xn.rex != nil { - if !xn.rex.Match([]byte(xsearch[:p])) { + if !xn.rex.MatchString(xsearch[:p]) { continue } } else if strings.IndexByte(xsearch[:p], '/') != -1 { @@ -453,6 +466,13 @@ func (n *node) findRoute(rctx *Context, method methodTyp, path string) *node { return xn } + for endpoints := range xn.endpoints { + if endpoints == mALL || endpoints == mSTUB { + continue + } + rctx.methodsAllowed = append(rctx.methodsAllowed, endpoints) + } + // flag that the routing context found a route, but not a corresponding // supported method rctx.methodNotAllowed = true @@ -492,6 +512,13 @@ func (n *node) findRoute(rctx *Context, method methodTyp, path string) *node { return xn } + for endpoints := range xn.endpoints { + if endpoints == mALL || endpoints == mSTUB { + continue + } + rctx.methodsAllowed = append(rctx.methodsAllowed, endpoints) + } + // flag that the routing context found a route, but not a corresponding // supported method rctx.methodNotAllowed = true @@ -623,14 +650,12 @@ func (n *node) routes() []Route { if h.handler == nil { continue } - m := methodTypString(mt) - if m == "" { - continue + if m, ok := reverseMethodMap[mt]; ok { + hs[m] = h.handler } - hs[m] = h.handler } - rt := Route{p, hs, subroutes} + rt := Route{subroutes, hs, p} rts = append(rts, rt) } @@ -703,11 +728,9 @@ func patNextSegment(pattern string) (nodeTyp, string, string, byte, int, int) { tail = pattern[pe] } - var rexpat string - if idx := strings.Index(key, ":"); idx >= 0 { + key, rexpat, isRegexp := strings.Cut(key, ":") + if isRegexp { nt = ntRegexp - rexpat = key[idx+1:] - key = key[:idx] } if len(rexpat) > 0 { @@ -763,15 +786,6 @@ func longestPrefix(k1, k2 string) int { return i } -func methodTypString(method methodTyp) string { - for s, t := range methodMap { - if method == t { - return s - } - } - return "" -} - type nodes []*node // Sort the list of nodes by label @@ -814,9 +828,9 @@ func (ns nodes) findEdge(label byte) *node { // Route describes the details of a routing handler. // Handlers map key is an HTTP method type Route struct { - Pattern string - Handlers map[string]http.Handler SubRoutes Routes + Handlers map[string]http.Handler + Pattern string } // WalkFunc is the type of the function called for each method and route visited by Walk. diff --git a/vendor/github.com/go-jose/go-jose/v3/.gitignore b/vendor/github.com/go-jose/go-jose/v3/.gitignore deleted file mode 100644 index eb29ebaefd..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -jose-util/jose-util -jose-util.t.err \ No newline at end of file diff --git a/vendor/github.com/go-jose/go-jose/v3/.golangci.yml b/vendor/github.com/go-jose/go-jose/v3/.golangci.yml deleted file mode 100644 index 2a577a8f95..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/.golangci.yml +++ /dev/null @@ -1,53 +0,0 @@ -# https://github.com/golangci/golangci-lint - -run: - skip-files: - - doc_test.go - modules-download-mode: readonly - -linters: - enable-all: true - disable: - - gochecknoglobals - - goconst - - lll - - maligned - - nakedret - - scopelint - - unparam - - funlen # added in 1.18 (requires go-jose changes before it can be enabled) - -linters-settings: - gocyclo: - min-complexity: 35 - -issues: - exclude-rules: - - text: "don't use ALL_CAPS in Go names" - linters: - - golint - - text: "hardcoded credentials" - linters: - - gosec - - text: "weak cryptographic primitive" - linters: - - gosec - - path: json/ - linters: - - dupl - - errcheck - - gocritic - - gocyclo - - golint - - govet - - ineffassign - - staticcheck - - structcheck - - stylecheck - - unused - - path: _test\.go - linters: - - scopelint - - path: jwk.go - linters: - - gocyclo diff --git a/vendor/github.com/go-jose/go-jose/v3/.travis.yml b/vendor/github.com/go-jose/go-jose/v3/.travis.yml deleted file mode 100644 index 48de631b00..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/.travis.yml +++ /dev/null @@ -1,33 +0,0 @@ -language: go - -matrix: - fast_finish: true - allow_failures: - - go: tip - -go: - - "1.13.x" - - "1.14.x" - - tip - -before_script: - - export PATH=$HOME/.local/bin:$PATH - -before_install: - - go get -u github.com/mattn/goveralls github.com/wadey/gocovmerge - - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.18.0 - - pip install cram --user - -script: - - go test -v -covermode=count -coverprofile=profile.cov . - - go test -v -covermode=count -coverprofile=cryptosigner/profile.cov ./cryptosigner - - go test -v -covermode=count -coverprofile=cipher/profile.cov ./cipher - - go test -v -covermode=count -coverprofile=jwt/profile.cov ./jwt - - go test -v ./json # no coverage for forked encoding/json package - - golangci-lint run - - cd jose-util && go build && PATH=$PWD:$PATH cram -v jose-util.t # cram tests jose-util - - cd .. - -after_success: - - gocovmerge *.cov */*.cov > merged.coverprofile - - goveralls -coverprofile merged.coverprofile -service=travis-ci diff --git a/vendor/github.com/go-jose/go-jose/v3/CHANGELOG.md b/vendor/github.com/go-jose/go-jose/v3/CHANGELOG.md deleted file mode 100644 index ce2a54ebf2..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/CHANGELOG.md +++ /dev/null @@ -1,78 +0,0 @@ -# v4.0.1 - -## Fixed - - - An attacker could send a JWE containing compressed data that used large - amounts of memory and CPU when decompressed by `Decrypt` or `DecryptMulti`. - Those functions now return an error if the decompressed data would exceed - 250kB or 10x the compressed size (whichever is larger). Thanks to - Enze Wang@Alioth and Jianjun Chen@Zhongguancun Lab (@zer0yu and @chenjj) - for reporting. - -# v4.0.0 - -This release makes some breaking changes in order to more thoroughly -address the vulnerabilities discussed in [Three New Attacks Against JSON Web -Tokens][1], "Sign/encrypt confusion", "Billion hash attack", and "Polyglot -token". - -## Changed - - - Limit JWT encryption types (exclude password or public key types) (#78) - - Enforce minimum length for HMAC keys (#85) - - jwt: match any audience in a list, rather than requiring all audiences (#81) - - jwt: accept only Compact Serialization (#75) - - jws: Add expected algorithms for signatures (#74) - - Require specifying expected algorithms for ParseEncrypted, - ParseSigned, ParseDetached, jwt.ParseEncrypted, jwt.ParseSigned, - jwt.ParseSignedAndEncrypted (#69, #74) - - Usually there is a small, known set of appropriate algorithms for a program - to use and it's a mistake to allow unexpected algorithms. For instance the - "billion hash attack" relies in part on programs accepting the PBES2 - encryption algorithm and doing the necessary work even if they weren't - specifically configured to allow PBES2. - - Revert "Strip padding off base64 strings" (#82) - - The specs require base64url encoding without padding. - - Minimum supported Go version is now 1.21 - -## Added - - - ParseSignedCompact, ParseSignedJSON, ParseEncryptedCompact, ParseEncryptedJSON. - - These allow parsing a specific serialization, as opposed to ParseSigned and - ParseEncrypted, which try to automatically detect which serialization was - provided. It's common to require a specific serialization for a specific - protocol - for instance JWT requires Compact serialization. - -[1]: https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf - -# v3.0.3 - -## Fixed - - - Limit decompression output size to prevent a DoS. Backport from v4.0.1. - -# v3.0.2 - -## Fixed - - - DecryptMulti: handle decompression error (#19) - -## Changed - - - jwe/CompactSerialize: improve performance (#67) - - Increase the default number of PBKDF2 iterations to 600k (#48) - - Return the proper algorithm for ECDSA keys (#45) - -## Added - - - Add Thumbprint support for opaque signers (#38) - -# v3.0.1 - -## Fixed - - - Security issue: an attacker specifying a large "p2c" value can cause - JSONWebEncryption.Decrypt and JSONWebEncryption.DecryptMulti to consume large - amounts of CPU, causing a DoS. Thanks to Matt Schwager (@mschwager) for the - disclosure and to Tom Tervoort for originally publishing the category of attack. - https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf diff --git a/vendor/github.com/go-jose/go-jose/v3/CONTRIBUTING.md b/vendor/github.com/go-jose/go-jose/v3/CONTRIBUTING.md deleted file mode 100644 index b63e1f8fee..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/CONTRIBUTING.md +++ /dev/null @@ -1,15 +0,0 @@ -# Contributing - -If you would like to contribute code to go-jose you can do so through GitHub by -forking the repository and sending a pull request. - -When submitting code, please make every effort to follow existing conventions -and style in order to keep the code as readable as possible. Please also make -sure all tests pass by running `go test`, and format your code with `go fmt`. -We also recommend using `golint` and `errcheck`. - -Before your code can be accepted into the project you must also sign the -Individual Contributor License Agreement. We use [cla-assistant.io][1] and you -will be prompted to sign once a pull request is opened. - -[1]: https://cla-assistant.io/ diff --git a/vendor/github.com/go-jose/go-jose/v3/README.md b/vendor/github.com/go-jose/go-jose/v3/README.md deleted file mode 100644 index 282cd9e135..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/README.md +++ /dev/null @@ -1,108 +0,0 @@ -# Go JOSE - -### Versions - -[Version 4](https://github.com/go-jose/go-jose) -([branch](https://github.com/go-jose/go-jose/), -[doc](https://pkg.go.dev/github.com/go-jose/go-jose/v4), [releases](https://github.com/go-jose/go-jose/releases)) is the current stable version: - - import "github.com/go-jose/go-jose/v4" - -The old [square/go-jose](https://github.com/square/go-jose) repo contains the prior v1 and v2 versions, which -are deprecated. - -### Summary - -Package jose aims to provide an implementation of the Javascript Object Signing -and Encryption set of standards. This includes support for JSON Web Encryption, -JSON Web Signature, and JSON Web Token standards. - -**Disclaimer**: This library contains encryption software that is subject to -the U.S. Export Administration Regulations. You may not export, re-export, -transfer or download this code or any part of it in violation of any United -States law, directive or regulation. In particular this software may not be -exported or re-exported in any form or on any media to Iran, North Sudan, -Syria, Cuba, or North Korea, or to denied persons or entities mentioned on any -US maintained blocked list. - -## Overview - -The implementation follows the -[JSON Web Encryption](https://dx.doi.org/10.17487/RFC7516) (RFC 7516), -[JSON Web Signature](https://dx.doi.org/10.17487/RFC7515) (RFC 7515), and -[JSON Web Token](https://dx.doi.org/10.17487/RFC7519) (RFC 7519) specifications. -Tables of supported algorithms are shown below. The library supports both -the compact and JWS/JWE JSON Serialization formats, and has optional support for -multiple recipients. It also comes with a small command-line utility -([`jose-util`](https://pkg.go.dev/github.com/go-jose/go-jose/jose-util)) -for dealing with JOSE messages in a shell. - -**Note**: We use a forked version of the `encoding/json` package from the Go -standard library which uses case-sensitive matching for member names (instead -of [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html)). -This is to avoid differences in interpretation of messages between go-jose and -libraries in other languages. - -### Supported algorithms - -See below for a table of supported algorithms. Algorithm identifiers match -the names in the [JSON Web Algorithms](https://dx.doi.org/10.17487/RFC7518) -standard where possible. The Godoc reference has a list of constants. - - Key encryption | Algorithm identifier(s) - :------------------------- | :------------------------------ - RSA-PKCS#1v1.5 | RSA1_5 - RSA-OAEP | RSA-OAEP, RSA-OAEP-256 - AES key wrap | A128KW, A192KW, A256KW - AES-GCM key wrap | A128GCMKW, A192GCMKW, A256GCMKW - ECDH-ES + AES key wrap | ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW - ECDH-ES (direct) | ECDH-ES1 - Direct encryption | dir1 - -1. Not supported in multi-recipient mode - - Signing / MAC | Algorithm identifier(s) - :------------------------- | :------------------------------ - RSASSA-PKCS#1v1.5 | RS256, RS384, RS512 - RSASSA-PSS | PS256, PS384, PS512 - HMAC | HS256, HS384, HS512 - ECDSA | ES256, ES384, ES512 - Ed25519 | EdDSA2 - -2. Only available in version 2 of the package - - Content encryption | Algorithm identifier(s) - :------------------------- | :------------------------------ - AES-CBC+HMAC | A128CBC-HS256, A192CBC-HS384, A256CBC-HS512 - AES-GCM | A128GCM, A192GCM, A256GCM - - Compression | Algorithm identifiers(s) - :------------------------- | ------------------------------- - DEFLATE (RFC 1951) | DEF - -### Supported key types - -See below for a table of supported key types. These are understood by the -library, and can be passed to corresponding functions such as `NewEncrypter` or -`NewSigner`. Each of these keys can also be wrapped in a JWK if desired, which -allows attaching a key id. - - Algorithm(s) | Corresponding types - :------------------------- | ------------------------------- - RSA | *[rsa.PublicKey](https://pkg.go.dev/crypto/rsa/#PublicKey), *[rsa.PrivateKey](https://pkg.go.dev/crypto/rsa/#PrivateKey) - ECDH, ECDSA | *[ecdsa.PublicKey](https://pkg.go.dev/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](https://pkg.go.dev/crypto/ecdsa/#PrivateKey) - EdDSA1 | [ed25519.PublicKey](https://pkg.go.dev/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://pkg.go.dev/crypto/ed25519#PrivateKey) - AES, HMAC | []byte - -1. Only available in version 2 or later of the package - -## Examples - -[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v3.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v3) -[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v3/jwt.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v3/jwt) - -Examples can be found in the Godoc -reference for this package. The -[`jose-util`](https://github.com/go-jose/go-jose/tree/v3/jose-util) -subdirectory also contains a small command-line utility which might be useful -as an example as well. diff --git a/vendor/github.com/go-jose/go-jose/v3/SECURITY.md b/vendor/github.com/go-jose/go-jose/v3/SECURITY.md deleted file mode 100644 index 2f18a75a82..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/SECURITY.md +++ /dev/null @@ -1,13 +0,0 @@ -# Security Policy -This document explains how to contact the Let's Encrypt security team to report security vulnerabilities. - -## Supported Versions -| Version | Supported | -| ------- | ----------| -| >= v3 | ✓ | -| v2 | ✗ | -| v1 | ✗ | - -## Reporting a vulnerability - -Please see [https://letsencrypt.org/contact/#security](https://letsencrypt.org/contact/#security) for the email address to report a vulnerability. Ensure that the subject line for your report contains the word `vulnerability` and is descriptive. Your email should be acknowledged within 24 hours. If you do not receive a response within 24 hours, please follow-up again with another email. diff --git a/vendor/github.com/go-jose/go-jose/v3/asymmetric.go b/vendor/github.com/go-jose/go-jose/v3/asymmetric.go deleted file mode 100644 index d4d4961b24..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/asymmetric.go +++ /dev/null @@ -1,595 +0,0 @@ -/*- - * Copyright 2014 Square Inc. - * - * 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. - */ - -package jose - -import ( - "crypto" - "crypto/aes" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rand" - "crypto/rsa" - "crypto/sha1" - "crypto/sha256" - "errors" - "fmt" - "math/big" - - josecipher "github.com/go-jose/go-jose/v3/cipher" - "github.com/go-jose/go-jose/v3/json" -) - -// A generic RSA-based encrypter/verifier -type rsaEncrypterVerifier struct { - publicKey *rsa.PublicKey -} - -// A generic RSA-based decrypter/signer -type rsaDecrypterSigner struct { - privateKey *rsa.PrivateKey -} - -// A generic EC-based encrypter/verifier -type ecEncrypterVerifier struct { - publicKey *ecdsa.PublicKey -} - -type edEncrypterVerifier struct { - publicKey ed25519.PublicKey -} - -// A key generator for ECDH-ES -type ecKeyGenerator struct { - size int - algID string - publicKey *ecdsa.PublicKey -} - -// A generic EC-based decrypter/signer -type ecDecrypterSigner struct { - privateKey *ecdsa.PrivateKey -} - -type edDecrypterSigner struct { - privateKey ed25519.PrivateKey -} - -// newRSARecipient creates recipientKeyInfo based on the given key. -func newRSARecipient(keyAlg KeyAlgorithm, publicKey *rsa.PublicKey) (recipientKeyInfo, error) { - // Verify that key management algorithm is supported by this encrypter - switch keyAlg { - case RSA1_5, RSA_OAEP, RSA_OAEP_256: - default: - return recipientKeyInfo{}, ErrUnsupportedAlgorithm - } - - if publicKey == nil { - return recipientKeyInfo{}, errors.New("invalid public key") - } - - return recipientKeyInfo{ - keyAlg: keyAlg, - keyEncrypter: &rsaEncrypterVerifier{ - publicKey: publicKey, - }, - }, nil -} - -// newRSASigner creates a recipientSigInfo based on the given key. -func newRSASigner(sigAlg SignatureAlgorithm, privateKey *rsa.PrivateKey) (recipientSigInfo, error) { - // Verify that key management algorithm is supported by this encrypter - switch sigAlg { - case RS256, RS384, RS512, PS256, PS384, PS512: - default: - return recipientSigInfo{}, ErrUnsupportedAlgorithm - } - - if privateKey == nil { - return recipientSigInfo{}, errors.New("invalid private key") - } - - return recipientSigInfo{ - sigAlg: sigAlg, - publicKey: staticPublicKey(&JSONWebKey{ - Key: privateKey.Public(), - }), - signer: &rsaDecrypterSigner{ - privateKey: privateKey, - }, - }, nil -} - -func newEd25519Signer(sigAlg SignatureAlgorithm, privateKey ed25519.PrivateKey) (recipientSigInfo, error) { - if sigAlg != EdDSA { - return recipientSigInfo{}, ErrUnsupportedAlgorithm - } - - if privateKey == nil { - return recipientSigInfo{}, errors.New("invalid private key") - } - return recipientSigInfo{ - sigAlg: sigAlg, - publicKey: staticPublicKey(&JSONWebKey{ - Key: privateKey.Public(), - }), - signer: &edDecrypterSigner{ - privateKey: privateKey, - }, - }, nil -} - -// newECDHRecipient creates recipientKeyInfo based on the given key. -func newECDHRecipient(keyAlg KeyAlgorithm, publicKey *ecdsa.PublicKey) (recipientKeyInfo, error) { - // Verify that key management algorithm is supported by this encrypter - switch keyAlg { - case ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW: - default: - return recipientKeyInfo{}, ErrUnsupportedAlgorithm - } - - if publicKey == nil || !publicKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) { - return recipientKeyInfo{}, errors.New("invalid public key") - } - - return recipientKeyInfo{ - keyAlg: keyAlg, - keyEncrypter: &ecEncrypterVerifier{ - publicKey: publicKey, - }, - }, nil -} - -// newECDSASigner creates a recipientSigInfo based on the given key. -func newECDSASigner(sigAlg SignatureAlgorithm, privateKey *ecdsa.PrivateKey) (recipientSigInfo, error) { - // Verify that key management algorithm is supported by this encrypter - switch sigAlg { - case ES256, ES384, ES512: - default: - return recipientSigInfo{}, ErrUnsupportedAlgorithm - } - - if privateKey == nil { - return recipientSigInfo{}, errors.New("invalid private key") - } - - return recipientSigInfo{ - sigAlg: sigAlg, - publicKey: staticPublicKey(&JSONWebKey{ - Key: privateKey.Public(), - }), - signer: &ecDecrypterSigner{ - privateKey: privateKey, - }, - }, nil -} - -// Encrypt the given payload and update the object. -func (ctx rsaEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) { - encryptedKey, err := ctx.encrypt(cek, alg) - if err != nil { - return recipientInfo{}, err - } - - return recipientInfo{ - encryptedKey: encryptedKey, - header: &rawHeader{}, - }, nil -} - -// Encrypt the given payload. Based on the key encryption algorithm, -// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256). -func (ctx rsaEncrypterVerifier) encrypt(cek []byte, alg KeyAlgorithm) ([]byte, error) { - switch alg { - case RSA1_5: - return rsa.EncryptPKCS1v15(RandReader, ctx.publicKey, cek) - case RSA_OAEP: - return rsa.EncryptOAEP(sha1.New(), RandReader, ctx.publicKey, cek, []byte{}) - case RSA_OAEP_256: - return rsa.EncryptOAEP(sha256.New(), RandReader, ctx.publicKey, cek, []byte{}) - } - - return nil, ErrUnsupportedAlgorithm -} - -// Decrypt the given payload and return the content encryption key. -func (ctx rsaDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) { - return ctx.decrypt(recipient.encryptedKey, headers.getAlgorithm(), generator) -} - -// Decrypt the given payload. Based on the key encryption algorithm, -// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256). -func (ctx rsaDecrypterSigner) decrypt(jek []byte, alg KeyAlgorithm, generator keyGenerator) ([]byte, error) { - // Note: The random reader on decrypt operations is only used for blinding, - // so stubbing is meanlingless (hence the direct use of rand.Reader). - switch alg { - case RSA1_5: - defer func() { - // DecryptPKCS1v15SessionKey sometimes panics on an invalid payload - // because of an index out of bounds error, which we want to ignore. - // This has been fixed in Go 1.3.1 (released 2014/08/13), the recover() - // only exists for preventing crashes with unpatched versions. - // See: https://groups.google.com/forum/#!topic/golang-dev/7ihX6Y6kx9k - // See: https://code.google.com/p/go/source/detail?r=58ee390ff31602edb66af41ed10901ec95904d33 - _ = recover() - }() - - // Perform some input validation. - keyBytes := ctx.privateKey.PublicKey.N.BitLen() / 8 - if keyBytes != len(jek) { - // Input size is incorrect, the encrypted payload should always match - // the size of the public modulus (e.g. using a 2048 bit key will - // produce 256 bytes of output). Reject this since it's invalid input. - return nil, ErrCryptoFailure - } - - cek, _, err := generator.genKey() - if err != nil { - return nil, ErrCryptoFailure - } - - // When decrypting an RSA-PKCS1v1.5 payload, we must take precautions to - // prevent chosen-ciphertext attacks as described in RFC 3218, "Preventing - // the Million Message Attack on Cryptographic Message Syntax". We are - // therefore deliberately ignoring errors here. - _ = rsa.DecryptPKCS1v15SessionKey(rand.Reader, ctx.privateKey, jek, cek) - - return cek, nil - case RSA_OAEP: - // Use rand.Reader for RSA blinding - return rsa.DecryptOAEP(sha1.New(), rand.Reader, ctx.privateKey, jek, []byte{}) - case RSA_OAEP_256: - // Use rand.Reader for RSA blinding - return rsa.DecryptOAEP(sha256.New(), rand.Reader, ctx.privateKey, jek, []byte{}) - } - - return nil, ErrUnsupportedAlgorithm -} - -// Sign the given payload -func (ctx rsaDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) { - var hash crypto.Hash - - switch alg { - case RS256, PS256: - hash = crypto.SHA256 - case RS384, PS384: - hash = crypto.SHA384 - case RS512, PS512: - hash = crypto.SHA512 - default: - return Signature{}, ErrUnsupportedAlgorithm - } - - hasher := hash.New() - - // According to documentation, Write() on hash never fails - _, _ = hasher.Write(payload) - hashed := hasher.Sum(nil) - - var out []byte - var err error - - switch alg { - case RS256, RS384, RS512: - // TODO(https://github.com/go-jose/go-jose/issues/40): As of go1.20, the - // random parameter is legacy and ignored, and it can be nil. - // https://cs.opensource.google/go/go/+/refs/tags/go1.20:src/crypto/rsa/pkcs1v15.go;l=263;bpv=0;bpt=1 - out, err = rsa.SignPKCS1v15(RandReader, ctx.privateKey, hash, hashed) - case PS256, PS384, PS512: - out, err = rsa.SignPSS(RandReader, ctx.privateKey, hash, hashed, &rsa.PSSOptions{ - SaltLength: rsa.PSSSaltLengthEqualsHash, - }) - } - - if err != nil { - return Signature{}, err - } - - return Signature{ - Signature: out, - protected: &rawHeader{}, - }, nil -} - -// Verify the given payload -func (ctx rsaEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error { - var hash crypto.Hash - - switch alg { - case RS256, PS256: - hash = crypto.SHA256 - case RS384, PS384: - hash = crypto.SHA384 - case RS512, PS512: - hash = crypto.SHA512 - default: - return ErrUnsupportedAlgorithm - } - - hasher := hash.New() - - // According to documentation, Write() on hash never fails - _, _ = hasher.Write(payload) - hashed := hasher.Sum(nil) - - switch alg { - case RS256, RS384, RS512: - return rsa.VerifyPKCS1v15(ctx.publicKey, hash, hashed, signature) - case PS256, PS384, PS512: - return rsa.VerifyPSS(ctx.publicKey, hash, hashed, signature, nil) - } - - return ErrUnsupportedAlgorithm -} - -// Encrypt the given payload and update the object. -func (ctx ecEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) { - switch alg { - case ECDH_ES: - // ECDH-ES mode doesn't wrap a key, the shared secret is used directly as the key. - return recipientInfo{ - header: &rawHeader{}, - }, nil - case ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW: - default: - return recipientInfo{}, ErrUnsupportedAlgorithm - } - - generator := ecKeyGenerator{ - algID: string(alg), - publicKey: ctx.publicKey, - } - - switch alg { - case ECDH_ES_A128KW: - generator.size = 16 - case ECDH_ES_A192KW: - generator.size = 24 - case ECDH_ES_A256KW: - generator.size = 32 - } - - kek, header, err := generator.genKey() - if err != nil { - return recipientInfo{}, err - } - - block, err := aes.NewCipher(kek) - if err != nil { - return recipientInfo{}, err - } - - jek, err := josecipher.KeyWrap(block, cek) - if err != nil { - return recipientInfo{}, err - } - - return recipientInfo{ - encryptedKey: jek, - header: &header, - }, nil -} - -// Get key size for EC key generator -func (ctx ecKeyGenerator) keySize() int { - return ctx.size -} - -// Get a content encryption key for ECDH-ES -func (ctx ecKeyGenerator) genKey() ([]byte, rawHeader, error) { - priv, err := ecdsa.GenerateKey(ctx.publicKey.Curve, RandReader) - if err != nil { - return nil, rawHeader{}, err - } - - out := josecipher.DeriveECDHES(ctx.algID, []byte{}, []byte{}, priv, ctx.publicKey, ctx.size) - - b, err := json.Marshal(&JSONWebKey{ - Key: &priv.PublicKey, - }) - if err != nil { - return nil, nil, err - } - - headers := rawHeader{ - headerEPK: makeRawMessage(b), - } - - return out, headers, nil -} - -// Decrypt the given payload and return the content encryption key. -func (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) { - epk, err := headers.getEPK() - if err != nil { - return nil, errors.New("go-jose/go-jose: invalid epk header") - } - if epk == nil { - return nil, errors.New("go-jose/go-jose: missing epk header") - } - - publicKey, ok := epk.Key.(*ecdsa.PublicKey) - if publicKey == nil || !ok { - return nil, errors.New("go-jose/go-jose: invalid epk header") - } - - if !ctx.privateKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) { - return nil, errors.New("go-jose/go-jose: invalid public key in epk header") - } - - apuData, err := headers.getAPU() - if err != nil { - return nil, errors.New("go-jose/go-jose: invalid apu header") - } - apvData, err := headers.getAPV() - if err != nil { - return nil, errors.New("go-jose/go-jose: invalid apv header") - } - - deriveKey := func(algID string, size int) []byte { - return josecipher.DeriveECDHES(algID, apuData.bytes(), apvData.bytes(), ctx.privateKey, publicKey, size) - } - - var keySize int - - algorithm := headers.getAlgorithm() - switch algorithm { - case ECDH_ES: - // ECDH-ES uses direct key agreement, no key unwrapping necessary. - return deriveKey(string(headers.getEncryption()), generator.keySize()), nil - case ECDH_ES_A128KW: - keySize = 16 - case ECDH_ES_A192KW: - keySize = 24 - case ECDH_ES_A256KW: - keySize = 32 - default: - return nil, ErrUnsupportedAlgorithm - } - - key := deriveKey(string(algorithm), keySize) - block, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - return josecipher.KeyUnwrap(block, recipient.encryptedKey) -} - -func (ctx edDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) { - if alg != EdDSA { - return Signature{}, ErrUnsupportedAlgorithm - } - - sig, err := ctx.privateKey.Sign(RandReader, payload, crypto.Hash(0)) - if err != nil { - return Signature{}, err - } - - return Signature{ - Signature: sig, - protected: &rawHeader{}, - }, nil -} - -func (ctx edEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error { - if alg != EdDSA { - return ErrUnsupportedAlgorithm - } - ok := ed25519.Verify(ctx.publicKey, payload, signature) - if !ok { - return errors.New("go-jose/go-jose: ed25519 signature failed to verify") - } - return nil -} - -// Sign the given payload -func (ctx ecDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) { - var expectedBitSize int - var hash crypto.Hash - - switch alg { - case ES256: - expectedBitSize = 256 - hash = crypto.SHA256 - case ES384: - expectedBitSize = 384 - hash = crypto.SHA384 - case ES512: - expectedBitSize = 521 - hash = crypto.SHA512 - } - - curveBits := ctx.privateKey.Curve.Params().BitSize - if expectedBitSize != curveBits { - return Signature{}, fmt.Errorf("go-jose/go-jose: expected %d bit key, got %d bits instead", expectedBitSize, curveBits) - } - - hasher := hash.New() - - // According to documentation, Write() on hash never fails - _, _ = hasher.Write(payload) - hashed := hasher.Sum(nil) - - r, s, err := ecdsa.Sign(RandReader, ctx.privateKey, hashed) - if err != nil { - return Signature{}, err - } - - keyBytes := curveBits / 8 - if curveBits%8 > 0 { - keyBytes++ - } - - // We serialize the outputs (r and s) into big-endian byte arrays and pad - // them with zeros on the left to make sure the sizes work out. Both arrays - // must be keyBytes long, and the output must be 2*keyBytes long. - rBytes := r.Bytes() - rBytesPadded := make([]byte, keyBytes) - copy(rBytesPadded[keyBytes-len(rBytes):], rBytes) - - sBytes := s.Bytes() - sBytesPadded := make([]byte, keyBytes) - copy(sBytesPadded[keyBytes-len(sBytes):], sBytes) - - out := append(rBytesPadded, sBytesPadded...) - - return Signature{ - Signature: out, - protected: &rawHeader{}, - }, nil -} - -// Verify the given payload -func (ctx ecEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error { - var keySize int - var hash crypto.Hash - - switch alg { - case ES256: - keySize = 32 - hash = crypto.SHA256 - case ES384: - keySize = 48 - hash = crypto.SHA384 - case ES512: - keySize = 66 - hash = crypto.SHA512 - default: - return ErrUnsupportedAlgorithm - } - - if len(signature) != 2*keySize { - return fmt.Errorf("go-jose/go-jose: invalid signature size, have %d bytes, wanted %d", len(signature), 2*keySize) - } - - hasher := hash.New() - - // According to documentation, Write() on hash never fails - _, _ = hasher.Write(payload) - hashed := hasher.Sum(nil) - - r := big.NewInt(0).SetBytes(signature[:keySize]) - s := big.NewInt(0).SetBytes(signature[keySize:]) - - match := ecdsa.Verify(ctx.publicKey, hashed, r, s) - if !match { - return errors.New("go-jose/go-jose: ecdsa signature failed to verify") - } - - return nil -} diff --git a/vendor/github.com/go-jose/go-jose/v3/cipher/cbc_hmac.go b/vendor/github.com/go-jose/go-jose/v3/cipher/cbc_hmac.go deleted file mode 100644 index af029cec0b..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/cipher/cbc_hmac.go +++ /dev/null @@ -1,196 +0,0 @@ -/*- - * Copyright 2014 Square Inc. - * - * 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. - */ - -package josecipher - -import ( - "bytes" - "crypto/cipher" - "crypto/hmac" - "crypto/sha256" - "crypto/sha512" - "crypto/subtle" - "encoding/binary" - "errors" - "hash" -) - -const ( - nonceBytes = 16 -) - -// NewCBCHMAC instantiates a new AEAD based on CBC+HMAC. -func NewCBCHMAC(key []byte, newBlockCipher func([]byte) (cipher.Block, error)) (cipher.AEAD, error) { - keySize := len(key) / 2 - integrityKey := key[:keySize] - encryptionKey := key[keySize:] - - blockCipher, err := newBlockCipher(encryptionKey) - if err != nil { - return nil, err - } - - var hash func() hash.Hash - switch keySize { - case 16: - hash = sha256.New - case 24: - hash = sha512.New384 - case 32: - hash = sha512.New - } - - return &cbcAEAD{ - hash: hash, - blockCipher: blockCipher, - authtagBytes: keySize, - integrityKey: integrityKey, - }, nil -} - -// An AEAD based on CBC+HMAC -type cbcAEAD struct { - hash func() hash.Hash - authtagBytes int - integrityKey []byte - blockCipher cipher.Block -} - -func (ctx *cbcAEAD) NonceSize() int { - return nonceBytes -} - -func (ctx *cbcAEAD) Overhead() int { - // Maximum overhead is block size (for padding) plus auth tag length, where - // the length of the auth tag is equivalent to the key size. - return ctx.blockCipher.BlockSize() + ctx.authtagBytes -} - -// Seal encrypts and authenticates the plaintext. -func (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte { - // Output buffer -- must take care not to mangle plaintext input. - ciphertext := make([]byte, uint64(len(plaintext))+uint64(ctx.Overhead()))[:len(plaintext)] - copy(ciphertext, plaintext) - ciphertext = padBuffer(ciphertext, ctx.blockCipher.BlockSize()) - - cbc := cipher.NewCBCEncrypter(ctx.blockCipher, nonce) - - cbc.CryptBlocks(ciphertext, ciphertext) - authtag := ctx.computeAuthTag(data, nonce, ciphertext) - - ret, out := resize(dst, uint64(len(dst))+uint64(len(ciphertext))+uint64(len(authtag))) - copy(out, ciphertext) - copy(out[len(ciphertext):], authtag) - - return ret -} - -// Open decrypts and authenticates the ciphertext. -func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { - if len(ciphertext) < ctx.authtagBytes { - return nil, errors.New("go-jose/go-jose: invalid ciphertext (too short)") - } - - offset := len(ciphertext) - ctx.authtagBytes - expectedTag := ctx.computeAuthTag(data, nonce, ciphertext[:offset]) - match := subtle.ConstantTimeCompare(expectedTag, ciphertext[offset:]) - if match != 1 { - return nil, errors.New("go-jose/go-jose: invalid ciphertext (auth tag mismatch)") - } - - cbc := cipher.NewCBCDecrypter(ctx.blockCipher, nonce) - - // Make copy of ciphertext buffer, don't want to modify in place - buffer := append([]byte{}, ciphertext[:offset]...) - - if len(buffer)%ctx.blockCipher.BlockSize() > 0 { - return nil, errors.New("go-jose/go-jose: invalid ciphertext (invalid length)") - } - - cbc.CryptBlocks(buffer, buffer) - - // Remove padding - plaintext, err := unpadBuffer(buffer, ctx.blockCipher.BlockSize()) - if err != nil { - return nil, err - } - - ret, out := resize(dst, uint64(len(dst))+uint64(len(plaintext))) - copy(out, plaintext) - - return ret, nil -} - -// Compute an authentication tag -func (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte { - buffer := make([]byte, uint64(len(aad))+uint64(len(nonce))+uint64(len(ciphertext))+8) - n := 0 - n += copy(buffer, aad) - n += copy(buffer[n:], nonce) - n += copy(buffer[n:], ciphertext) - binary.BigEndian.PutUint64(buffer[n:], uint64(len(aad))*8) - - // According to documentation, Write() on hash.Hash never fails. - hmac := hmac.New(ctx.hash, ctx.integrityKey) - _, _ = hmac.Write(buffer) - - return hmac.Sum(nil)[:ctx.authtagBytes] -} - -// resize ensures that the given slice has a capacity of at least n bytes. -// If the capacity of the slice is less than n, a new slice is allocated -// and the existing data will be copied. -func resize(in []byte, n uint64) (head, tail []byte) { - if uint64(cap(in)) >= n { - head = in[:n] - } else { - head = make([]byte, n) - copy(head, in) - } - - tail = head[len(in):] - return -} - -// Apply padding -func padBuffer(buffer []byte, blockSize int) []byte { - missing := blockSize - (len(buffer) % blockSize) - ret, out := resize(buffer, uint64(len(buffer))+uint64(missing)) - padding := bytes.Repeat([]byte{byte(missing)}, missing) - copy(out, padding) - return ret -} - -// Remove padding -func unpadBuffer(buffer []byte, blockSize int) ([]byte, error) { - if len(buffer)%blockSize != 0 { - return nil, errors.New("go-jose/go-jose: invalid padding") - } - - last := buffer[len(buffer)-1] - count := int(last) - - if count == 0 || count > blockSize || count > len(buffer) { - return nil, errors.New("go-jose/go-jose: invalid padding") - } - - padding := bytes.Repeat([]byte{last}, count) - if !bytes.HasSuffix(buffer, padding) { - return nil, errors.New("go-jose/go-jose: invalid padding") - } - - return buffer[:len(buffer)-count], nil -} diff --git a/vendor/github.com/go-jose/go-jose/v3/cipher/concat_kdf.go b/vendor/github.com/go-jose/go-jose/v3/cipher/concat_kdf.go deleted file mode 100644 index f62c3bdba5..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/cipher/concat_kdf.go +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright 2014 Square Inc. - * - * 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. - */ - -package josecipher - -import ( - "crypto" - "encoding/binary" - "hash" - "io" -) - -type concatKDF struct { - z, info []byte - i uint32 - cache []byte - hasher hash.Hash -} - -// NewConcatKDF builds a KDF reader based on the given inputs. -func NewConcatKDF(hash crypto.Hash, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo []byte) io.Reader { - buffer := make([]byte, uint64(len(algID))+uint64(len(ptyUInfo))+uint64(len(ptyVInfo))+uint64(len(supPubInfo))+uint64(len(supPrivInfo))) - n := 0 - n += copy(buffer, algID) - n += copy(buffer[n:], ptyUInfo) - n += copy(buffer[n:], ptyVInfo) - n += copy(buffer[n:], supPubInfo) - copy(buffer[n:], supPrivInfo) - - hasher := hash.New() - - return &concatKDF{ - z: z, - info: buffer, - hasher: hasher, - cache: []byte{}, - i: 1, - } -} - -func (ctx *concatKDF) Read(out []byte) (int, error) { - copied := copy(out, ctx.cache) - ctx.cache = ctx.cache[copied:] - - for copied < len(out) { - ctx.hasher.Reset() - - // Write on a hash.Hash never fails - _ = binary.Write(ctx.hasher, binary.BigEndian, ctx.i) - _, _ = ctx.hasher.Write(ctx.z) - _, _ = ctx.hasher.Write(ctx.info) - - hash := ctx.hasher.Sum(nil) - chunkCopied := copy(out[copied:], hash) - copied += chunkCopied - ctx.cache = hash[chunkCopied:] - - ctx.i++ - } - - return copied, nil -} diff --git a/vendor/github.com/go-jose/go-jose/v3/cipher/ecdh_es.go b/vendor/github.com/go-jose/go-jose/v3/cipher/ecdh_es.go deleted file mode 100644 index 093c646740..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/cipher/ecdh_es.go +++ /dev/null @@ -1,86 +0,0 @@ -/*- - * Copyright 2014 Square Inc. - * - * 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. - */ - -package josecipher - -import ( - "bytes" - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "encoding/binary" -) - -// DeriveECDHES derives a shared encryption key using ECDH/ConcatKDF as described in JWE/JWA. -// It is an error to call this function with a private/public key that are not on the same -// curve. Callers must ensure that the keys are valid before calling this function. Output -// size may be at most 1<<16 bytes (64 KiB). -func DeriveECDHES(alg string, apuData, apvData []byte, priv *ecdsa.PrivateKey, pub *ecdsa.PublicKey, size int) []byte { - if size > 1<<16 { - panic("ECDH-ES output size too large, must be less than or equal to 1<<16") - } - - // algId, partyUInfo, partyVInfo inputs must be prefixed with the length - algID := lengthPrefixed([]byte(alg)) - ptyUInfo := lengthPrefixed(apuData) - ptyVInfo := lengthPrefixed(apvData) - - // suppPubInfo is the encoded length of the output size in bits - supPubInfo := make([]byte, 4) - binary.BigEndian.PutUint32(supPubInfo, uint32(size)*8) - - if !priv.PublicKey.Curve.IsOnCurve(pub.X, pub.Y) { - panic("public key not on same curve as private key") - } - - z, _ := priv.Curve.ScalarMult(pub.X, pub.Y, priv.D.Bytes()) - zBytes := z.Bytes() - - // Note that calling z.Bytes() on a big.Int may strip leading zero bytes from - // the returned byte array. This can lead to a problem where zBytes will be - // shorter than expected which breaks the key derivation. Therefore we must pad - // to the full length of the expected coordinate here before calling the KDF. - octSize := dSize(priv.Curve) - if len(zBytes) != octSize { - zBytes = append(bytes.Repeat([]byte{0}, octSize-len(zBytes)), zBytes...) - } - - reader := NewConcatKDF(crypto.SHA256, zBytes, algID, ptyUInfo, ptyVInfo, supPubInfo, []byte{}) - key := make([]byte, size) - - // Read on the KDF will never fail - _, _ = reader.Read(key) - - return key -} - -// dSize returns the size in octets for a coordinate on a elliptic curve. -func dSize(curve elliptic.Curve) int { - order := curve.Params().P - bitLen := order.BitLen() - size := bitLen / 8 - if bitLen%8 != 0 { - size++ - } - return size -} - -func lengthPrefixed(data []byte) []byte { - out := make([]byte, len(data)+4) - binary.BigEndian.PutUint32(out, uint32(len(data))) - copy(out[4:], data) - return out -} diff --git a/vendor/github.com/go-jose/go-jose/v3/cipher/key_wrap.go b/vendor/github.com/go-jose/go-jose/v3/cipher/key_wrap.go deleted file mode 100644 index b9effbca8a..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/cipher/key_wrap.go +++ /dev/null @@ -1,109 +0,0 @@ -/*- - * Copyright 2014 Square Inc. - * - * 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. - */ - -package josecipher - -import ( - "crypto/cipher" - "crypto/subtle" - "encoding/binary" - "errors" -) - -var defaultIV = []byte{0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6} - -// KeyWrap implements NIST key wrapping; it wraps a content encryption key (cek) with the given block cipher. -func KeyWrap(block cipher.Block, cek []byte) ([]byte, error) { - if len(cek)%8 != 0 { - return nil, errors.New("go-jose/go-jose: key wrap input must be 8 byte blocks") - } - - n := len(cek) / 8 - r := make([][]byte, n) - - for i := range r { - r[i] = make([]byte, 8) - copy(r[i], cek[i*8:]) - } - - buffer := make([]byte, 16) - tBytes := make([]byte, 8) - copy(buffer, defaultIV) - - for t := 0; t < 6*n; t++ { - copy(buffer[8:], r[t%n]) - - block.Encrypt(buffer, buffer) - - binary.BigEndian.PutUint64(tBytes, uint64(t+1)) - - for i := 0; i < 8; i++ { - buffer[i] ^= tBytes[i] - } - copy(r[t%n], buffer[8:]) - } - - out := make([]byte, (n+1)*8) - copy(out, buffer[:8]) - for i := range r { - copy(out[(i+1)*8:], r[i]) - } - - return out, nil -} - -// KeyUnwrap implements NIST key unwrapping; it unwraps a content encryption key (cek) with the given block cipher. -func KeyUnwrap(block cipher.Block, ciphertext []byte) ([]byte, error) { - if len(ciphertext)%8 != 0 { - return nil, errors.New("go-jose/go-jose: key wrap input must be 8 byte blocks") - } - - n := (len(ciphertext) / 8) - 1 - r := make([][]byte, n) - - for i := range r { - r[i] = make([]byte, 8) - copy(r[i], ciphertext[(i+1)*8:]) - } - - buffer := make([]byte, 16) - tBytes := make([]byte, 8) - copy(buffer[:8], ciphertext[:8]) - - for t := 6*n - 1; t >= 0; t-- { - binary.BigEndian.PutUint64(tBytes, uint64(t+1)) - - for i := 0; i < 8; i++ { - buffer[i] ^= tBytes[i] - } - copy(buffer[8:], r[t%n]) - - block.Decrypt(buffer, buffer) - - copy(r[t%n], buffer[8:]) - } - - if subtle.ConstantTimeCompare(buffer[:8], defaultIV) == 0 { - return nil, errors.New("go-jose/go-jose: failed to unwrap key") - } - - out := make([]byte, n*8) - for i := range r { - copy(out[i*8:], r[i]) - } - - return out, nil -} diff --git a/vendor/github.com/go-jose/go-jose/v3/crypter.go b/vendor/github.com/go-jose/go-jose/v3/crypter.go deleted file mode 100644 index 8870e8905f..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/crypter.go +++ /dev/null @@ -1,593 +0,0 @@ -/*- - * Copyright 2014 Square Inc. - * - * 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. - */ - -package jose - -import ( - "crypto/ecdsa" - "crypto/rsa" - "errors" - "fmt" - - "github.com/go-jose/go-jose/v3/json" -) - -// Encrypter represents an encrypter which produces an encrypted JWE object. -type Encrypter interface { - Encrypt(plaintext []byte) (*JSONWebEncryption, error) - EncryptWithAuthData(plaintext []byte, aad []byte) (*JSONWebEncryption, error) - Options() EncrypterOptions -} - -// A generic content cipher -type contentCipher interface { - keySize() int - encrypt(cek []byte, aad, plaintext []byte) (*aeadParts, error) - decrypt(cek []byte, aad []byte, parts *aeadParts) ([]byte, error) -} - -// A key generator (for generating/getting a CEK) -type keyGenerator interface { - keySize() int - genKey() ([]byte, rawHeader, error) -} - -// A generic key encrypter -type keyEncrypter interface { - encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) // Encrypt a key -} - -// A generic key decrypter -type keyDecrypter interface { - decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) // Decrypt a key -} - -// A generic encrypter based on the given key encrypter and content cipher. -type genericEncrypter struct { - contentAlg ContentEncryption - compressionAlg CompressionAlgorithm - cipher contentCipher - recipients []recipientKeyInfo - keyGenerator keyGenerator - extraHeaders map[HeaderKey]interface{} -} - -type recipientKeyInfo struct { - keyID string - keyAlg KeyAlgorithm - keyEncrypter keyEncrypter -} - -// EncrypterOptions represents options that can be set on new encrypters. -type EncrypterOptions struct { - Compression CompressionAlgorithm - - // Optional map of name/value pairs to be inserted into the protected - // header of a JWS object. Some specifications which make use of - // JWS require additional values here. - // - // Values will be serialized by [json.Marshal] and must be valid inputs to - // that function. - // - // [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal - ExtraHeaders map[HeaderKey]interface{} -} - -// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it -// if necessary, and returns the updated EncrypterOptions. -// -// The v parameter will be serialized by [json.Marshal] and must be a valid -// input to that function. -// -// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal -func (eo *EncrypterOptions) WithHeader(k HeaderKey, v interface{}) *EncrypterOptions { - if eo.ExtraHeaders == nil { - eo.ExtraHeaders = map[HeaderKey]interface{}{} - } - eo.ExtraHeaders[k] = v - return eo -} - -// WithContentType adds a content type ("cty") header and returns the updated -// EncrypterOptions. -func (eo *EncrypterOptions) WithContentType(contentType ContentType) *EncrypterOptions { - return eo.WithHeader(HeaderContentType, contentType) -} - -// WithType adds a type ("typ") header and returns the updated EncrypterOptions. -func (eo *EncrypterOptions) WithType(typ ContentType) *EncrypterOptions { - return eo.WithHeader(HeaderType, typ) -} - -// Recipient represents an algorithm/key to encrypt messages to. -// -// PBES2Count and PBES2Salt correspond with the "p2c" and "p2s" headers used -// on the password-based encryption algorithms PBES2-HS256+A128KW, -// PBES2-HS384+A192KW, and PBES2-HS512+A256KW. If they are not provided a safe -// default of 100000 will be used for the count and a 128-bit random salt will -// be generated. -type Recipient struct { - Algorithm KeyAlgorithm - // Key must have one of these types: - // - ed25519.PublicKey - // - *ecdsa.PublicKey - // - *rsa.PublicKey - // - *JSONWebKey - // - JSONWebKey - // - []byte (a symmetric key) - // - Any type that satisfies the OpaqueKeyEncrypter interface - // - // The type of Key must match the value of Algorithm. - Key interface{} - KeyID string - PBES2Count int - PBES2Salt []byte -} - -// NewEncrypter creates an appropriate encrypter based on the key type -func NewEncrypter(enc ContentEncryption, rcpt Recipient, opts *EncrypterOptions) (Encrypter, error) { - encrypter := &genericEncrypter{ - contentAlg: enc, - recipients: []recipientKeyInfo{}, - cipher: getContentCipher(enc), - } - if opts != nil { - encrypter.compressionAlg = opts.Compression - encrypter.extraHeaders = opts.ExtraHeaders - } - - if encrypter.cipher == nil { - return nil, ErrUnsupportedAlgorithm - } - - var keyID string - var rawKey interface{} - switch encryptionKey := rcpt.Key.(type) { - case JSONWebKey: - keyID, rawKey = encryptionKey.KeyID, encryptionKey.Key - case *JSONWebKey: - keyID, rawKey = encryptionKey.KeyID, encryptionKey.Key - case OpaqueKeyEncrypter: - keyID, rawKey = encryptionKey.KeyID(), encryptionKey - default: - rawKey = encryptionKey - } - - switch rcpt.Algorithm { - case DIRECT: - // Direct encryption mode must be treated differently - keyBytes, ok := rawKey.([]byte) - if !ok { - return nil, ErrUnsupportedKeyType - } - if encrypter.cipher.keySize() != len(keyBytes) { - return nil, ErrInvalidKeySize - } - encrypter.keyGenerator = staticKeyGenerator{ - key: keyBytes, - } - recipientInfo, _ := newSymmetricRecipient(rcpt.Algorithm, keyBytes) - recipientInfo.keyID = keyID - if rcpt.KeyID != "" { - recipientInfo.keyID = rcpt.KeyID - } - encrypter.recipients = []recipientKeyInfo{recipientInfo} - return encrypter, nil - case ECDH_ES: - // ECDH-ES (w/o key wrapping) is similar to DIRECT mode - keyDSA, ok := rawKey.(*ecdsa.PublicKey) - if !ok { - return nil, ErrUnsupportedKeyType - } - encrypter.keyGenerator = ecKeyGenerator{ - size: encrypter.cipher.keySize(), - algID: string(enc), - publicKey: keyDSA, - } - recipientInfo, _ := newECDHRecipient(rcpt.Algorithm, keyDSA) - recipientInfo.keyID = keyID - if rcpt.KeyID != "" { - recipientInfo.keyID = rcpt.KeyID - } - encrypter.recipients = []recipientKeyInfo{recipientInfo} - return encrypter, nil - default: - // Can just add a standard recipient - encrypter.keyGenerator = randomKeyGenerator{ - size: encrypter.cipher.keySize(), - } - err := encrypter.addRecipient(rcpt) - return encrypter, err - } -} - -// NewMultiEncrypter creates a multi-encrypter based on the given parameters -func NewMultiEncrypter(enc ContentEncryption, rcpts []Recipient, opts *EncrypterOptions) (Encrypter, error) { - cipher := getContentCipher(enc) - - if cipher == nil { - return nil, ErrUnsupportedAlgorithm - } - if len(rcpts) == 0 { - return nil, fmt.Errorf("go-jose/go-jose: recipients is nil or empty") - } - - encrypter := &genericEncrypter{ - contentAlg: enc, - recipients: []recipientKeyInfo{}, - cipher: cipher, - keyGenerator: randomKeyGenerator{ - size: cipher.keySize(), - }, - } - - if opts != nil { - encrypter.compressionAlg = opts.Compression - encrypter.extraHeaders = opts.ExtraHeaders - } - - for _, recipient := range rcpts { - err := encrypter.addRecipient(recipient) - if err != nil { - return nil, err - } - } - - return encrypter, nil -} - -func (ctx *genericEncrypter) addRecipient(recipient Recipient) (err error) { - var recipientInfo recipientKeyInfo - - switch recipient.Algorithm { - case DIRECT, ECDH_ES: - return fmt.Errorf("go-jose/go-jose: key algorithm '%s' not supported in multi-recipient mode", recipient.Algorithm) - } - - recipientInfo, err = makeJWERecipient(recipient.Algorithm, recipient.Key) - if recipient.KeyID != "" { - recipientInfo.keyID = recipient.KeyID - } - - switch recipient.Algorithm { - case PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW: - if sr, ok := recipientInfo.keyEncrypter.(*symmetricKeyCipher); ok { - sr.p2c = recipient.PBES2Count - sr.p2s = recipient.PBES2Salt - } - } - - if err == nil { - ctx.recipients = append(ctx.recipients, recipientInfo) - } - return err -} - -func makeJWERecipient(alg KeyAlgorithm, encryptionKey interface{}) (recipientKeyInfo, error) { - switch encryptionKey := encryptionKey.(type) { - case *rsa.PublicKey: - return newRSARecipient(alg, encryptionKey) - case *ecdsa.PublicKey: - return newECDHRecipient(alg, encryptionKey) - case []byte: - return newSymmetricRecipient(alg, encryptionKey) - case string: - return newSymmetricRecipient(alg, []byte(encryptionKey)) - case *JSONWebKey: - recipient, err := makeJWERecipient(alg, encryptionKey.Key) - recipient.keyID = encryptionKey.KeyID - return recipient, err - case OpaqueKeyEncrypter: - return newOpaqueKeyEncrypter(alg, encryptionKey) - } - return recipientKeyInfo{}, ErrUnsupportedKeyType -} - -// newDecrypter creates an appropriate decrypter based on the key type -func newDecrypter(decryptionKey interface{}) (keyDecrypter, error) { - switch decryptionKey := decryptionKey.(type) { - case *rsa.PrivateKey: - return &rsaDecrypterSigner{ - privateKey: decryptionKey, - }, nil - case *ecdsa.PrivateKey: - return &ecDecrypterSigner{ - privateKey: decryptionKey, - }, nil - case []byte: - return &symmetricKeyCipher{ - key: decryptionKey, - }, nil - case string: - return &symmetricKeyCipher{ - key: []byte(decryptionKey), - }, nil - case JSONWebKey: - return newDecrypter(decryptionKey.Key) - case *JSONWebKey: - return newDecrypter(decryptionKey.Key) - case OpaqueKeyDecrypter: - return &opaqueKeyDecrypter{decrypter: decryptionKey}, nil - default: - return nil, ErrUnsupportedKeyType - } -} - -// Implementation of encrypt method producing a JWE object. -func (ctx *genericEncrypter) Encrypt(plaintext []byte) (*JSONWebEncryption, error) { - return ctx.EncryptWithAuthData(plaintext, nil) -} - -// Implementation of encrypt method producing a JWE object. -func (ctx *genericEncrypter) EncryptWithAuthData(plaintext, aad []byte) (*JSONWebEncryption, error) { - obj := &JSONWebEncryption{} - obj.aad = aad - - obj.protected = &rawHeader{} - err := obj.protected.set(headerEncryption, ctx.contentAlg) - if err != nil { - return nil, err - } - - obj.recipients = make([]recipientInfo, len(ctx.recipients)) - - if len(ctx.recipients) == 0 { - return nil, fmt.Errorf("go-jose/go-jose: no recipients to encrypt to") - } - - cek, headers, err := ctx.keyGenerator.genKey() - if err != nil { - return nil, err - } - - obj.protected.merge(&headers) - - for i, info := range ctx.recipients { - recipient, err := info.keyEncrypter.encryptKey(cek, info.keyAlg) - if err != nil { - return nil, err - } - - err = recipient.header.set(headerAlgorithm, info.keyAlg) - if err != nil { - return nil, err - } - - if info.keyID != "" { - err = recipient.header.set(headerKeyID, info.keyID) - if err != nil { - return nil, err - } - } - obj.recipients[i] = recipient - } - - if len(ctx.recipients) == 1 { - // Move per-recipient headers into main protected header if there's - // only a single recipient. - obj.protected.merge(obj.recipients[0].header) - obj.recipients[0].header = nil - } - - if ctx.compressionAlg != NONE { - plaintext, err = compress(ctx.compressionAlg, plaintext) - if err != nil { - return nil, err - } - - err = obj.protected.set(headerCompression, ctx.compressionAlg) - if err != nil { - return nil, err - } - } - - for k, v := range ctx.extraHeaders { - b, err := json.Marshal(v) - if err != nil { - return nil, err - } - (*obj.protected)[k] = makeRawMessage(b) - } - - authData := obj.computeAuthData() - parts, err := ctx.cipher.encrypt(cek, authData, plaintext) - if err != nil { - return nil, err - } - - obj.iv = parts.iv - obj.ciphertext = parts.ciphertext - obj.tag = parts.tag - - return obj, nil -} - -func (ctx *genericEncrypter) Options() EncrypterOptions { - return EncrypterOptions{ - Compression: ctx.compressionAlg, - ExtraHeaders: ctx.extraHeaders, - } -} - -// Decrypt and validate the object and return the plaintext. This -// function does not support multi-recipient. If you desire multi-recipient -// decryption use DecryptMulti instead. -// -// The decryptionKey argument must contain a private or symmetric key -// and must have one of these types: -// - *ecdsa.PrivateKey -// - *rsa.PrivateKey -// - *JSONWebKey -// - JSONWebKey -// - *JSONWebKeySet -// - JSONWebKeySet -// - []byte (a symmetric key) -// - string (a symmetric key) -// - Any type that satisfies the OpaqueKeyDecrypter interface. -// -// Note that ed25519 is only available for signatures, not encryption, so is -// not an option here. -// -// Automatically decompresses plaintext, but returns an error if the decompressed -// data would be >250kB or >10x the size of the compressed data, whichever is larger. -func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) { - headers := obj.mergedHeaders(nil) - - if len(obj.recipients) > 1 { - return nil, errors.New("go-jose/go-jose: too many recipients in payload; expecting only one") - } - - critical, err := headers.getCritical() - if err != nil { - return nil, fmt.Errorf("go-jose/go-jose: invalid crit header") - } - - if len(critical) > 0 { - return nil, fmt.Errorf("go-jose/go-jose: unsupported crit header") - } - - key := tryJWKS(decryptionKey, obj.Header) - decrypter, err := newDecrypter(key) - if err != nil { - return nil, err - } - - cipher := getContentCipher(headers.getEncryption()) - if cipher == nil { - return nil, fmt.Errorf("go-jose/go-jose: unsupported enc value '%s'", string(headers.getEncryption())) - } - - generator := randomKeyGenerator{ - size: cipher.keySize(), - } - - parts := &aeadParts{ - iv: obj.iv, - ciphertext: obj.ciphertext, - tag: obj.tag, - } - - authData := obj.computeAuthData() - - var plaintext []byte - recipient := obj.recipients[0] - recipientHeaders := obj.mergedHeaders(&recipient) - - cek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator) - if err == nil { - // Found a valid CEK -- let's try to decrypt. - plaintext, err = cipher.decrypt(cek, authData, parts) - } - - if plaintext == nil { - return nil, ErrCryptoFailure - } - - // The "zip" header parameter may only be present in the protected header. - if comp := obj.protected.getCompression(); comp != "" { - plaintext, err = decompress(comp, plaintext) - if err != nil { - return nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err) - } - } - - return plaintext, nil -} - -// DecryptMulti decrypts and validates the object and returns the plaintexts, -// with support for multiple recipients. It returns the index of the recipient -// for which the decryption was successful, the merged headers for that recipient, -// and the plaintext. -// -// The decryptionKey argument must have one of the types allowed for the -// decryptionKey argument of Decrypt(). -// -// Automatically decompresses plaintext, but returns an error if the decompressed -// data would be >250kB or >3x the size of the compressed data, whichever is larger. -func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) { - globalHeaders := obj.mergedHeaders(nil) - - critical, err := globalHeaders.getCritical() - if err != nil { - return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: invalid crit header") - } - - if len(critical) > 0 { - return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported crit header") - } - - key := tryJWKS(decryptionKey, obj.Header) - decrypter, err := newDecrypter(key) - if err != nil { - return -1, Header{}, nil, err - } - - encryption := globalHeaders.getEncryption() - cipher := getContentCipher(encryption) - if cipher == nil { - return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported enc value '%s'", string(encryption)) - } - - generator := randomKeyGenerator{ - size: cipher.keySize(), - } - - parts := &aeadParts{ - iv: obj.iv, - ciphertext: obj.ciphertext, - tag: obj.tag, - } - - authData := obj.computeAuthData() - - index := -1 - var plaintext []byte - var headers rawHeader - - for i, recipient := range obj.recipients { - recipientHeaders := obj.mergedHeaders(&recipient) - - cek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator) - if err == nil { - // Found a valid CEK -- let's try to decrypt. - plaintext, err = cipher.decrypt(cek, authData, parts) - if err == nil { - index = i - headers = recipientHeaders - break - } - } - } - - if plaintext == nil { - return -1, Header{}, nil, ErrCryptoFailure - } - - // The "zip" header parameter may only be present in the protected header. - if comp := obj.protected.getCompression(); comp != "" { - plaintext, err = decompress(comp, plaintext) - if err != nil { - return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err) - } - } - - sanitized, err := headers.sanitized() - if err != nil { - return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: failed to sanitize header: %v", err) - } - - return index, sanitized, plaintext, err -} diff --git a/vendor/github.com/go-jose/go-jose/v3/encoding.go b/vendor/github.com/go-jose/go-jose/v3/encoding.go deleted file mode 100644 index 9f07cfdcb8..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/encoding.go +++ /dev/null @@ -1,237 +0,0 @@ -/*- - * Copyright 2014 Square Inc. - * - * 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. - */ - -package jose - -import ( - "bytes" - "compress/flate" - "encoding/base64" - "encoding/binary" - "fmt" - "io" - "math/big" - "strings" - "unicode" - - "github.com/go-jose/go-jose/v3/json" -) - -// Helper function to serialize known-good objects. -// Precondition: value is not a nil pointer. -func mustSerializeJSON(value interface{}) []byte { - out, err := json.Marshal(value) - if err != nil { - panic(err) - } - // We never want to serialize the top-level value "null," since it's not a - // valid JOSE message. But if a caller passes in a nil pointer to this method, - // MarshalJSON will happily serialize it as the top-level value "null". If - // that value is then embedded in another operation, for instance by being - // base64-encoded and fed as input to a signing algorithm - // (https://github.com/go-jose/go-jose/issues/22), the result will be - // incorrect. Because this method is intended for known-good objects, and a nil - // pointer is not a known-good object, we are free to panic in this case. - // Note: It's not possible to directly check whether the data pointed at by an - // interface is a nil pointer, so we do this hacky workaround. - // https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I - if string(out) == "null" { - panic("Tried to serialize a nil pointer.") - } - return out -} - -// Strip all newlines and whitespace -func stripWhitespace(data string) string { - buf := strings.Builder{} - buf.Grow(len(data)) - for _, r := range data { - if !unicode.IsSpace(r) { - buf.WriteRune(r) - } - } - return buf.String() -} - -// Perform compression based on algorithm -func compress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) { - switch algorithm { - case DEFLATE: - return deflate(input) - default: - return nil, ErrUnsupportedAlgorithm - } -} - -// Perform decompression based on algorithm -func decompress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) { - switch algorithm { - case DEFLATE: - return inflate(input) - default: - return nil, ErrUnsupportedAlgorithm - } -} - -// deflate compresses the input. -func deflate(input []byte) ([]byte, error) { - output := new(bytes.Buffer) - - // Writing to byte buffer, err is always nil - writer, _ := flate.NewWriter(output, 1) - _, _ = io.Copy(writer, bytes.NewBuffer(input)) - - err := writer.Close() - return output.Bytes(), err -} - -// inflate decompresses the input. -// -// Errors if the decompressed data would be >250kB or >10x the size of the -// compressed data, whichever is larger. -func inflate(input []byte) ([]byte, error) { - output := new(bytes.Buffer) - reader := flate.NewReader(bytes.NewBuffer(input)) - - maxCompressedSize := 10 * int64(len(input)) - if maxCompressedSize < 250000 { - maxCompressedSize = 250000 - } - - limit := maxCompressedSize + 1 - n, err := io.CopyN(output, reader, limit) - if err != nil && err != io.EOF { - return nil, err - } - if n == limit { - return nil, fmt.Errorf("uncompressed data would be too large (>%d bytes)", maxCompressedSize) - } - - err = reader.Close() - return output.Bytes(), err -} - -// byteBuffer represents a slice of bytes that can be serialized to url-safe base64. -type byteBuffer struct { - data []byte -} - -func newBuffer(data []byte) *byteBuffer { - if data == nil { - return nil - } - return &byteBuffer{ - data: data, - } -} - -func newFixedSizeBuffer(data []byte, length int) *byteBuffer { - if len(data) > length { - panic("go-jose/go-jose: invalid call to newFixedSizeBuffer (len(data) > length)") - } - pad := make([]byte, length-len(data)) - return newBuffer(append(pad, data...)) -} - -func newBufferFromInt(num uint64) *byteBuffer { - data := make([]byte, 8) - binary.BigEndian.PutUint64(data, num) - return newBuffer(bytes.TrimLeft(data, "\x00")) -} - -func (b *byteBuffer) MarshalJSON() ([]byte, error) { - return json.Marshal(b.base64()) -} - -func (b *byteBuffer) UnmarshalJSON(data []byte) error { - var encoded string - err := json.Unmarshal(data, &encoded) - if err != nil { - return err - } - - if encoded == "" { - return nil - } - - decoded, err := base64URLDecode(encoded) - if err != nil { - return err - } - - *b = *newBuffer(decoded) - - return nil -} - -func (b *byteBuffer) base64() string { - return base64.RawURLEncoding.EncodeToString(b.data) -} - -func (b *byteBuffer) bytes() []byte { - // Handling nil here allows us to transparently handle nil slices when serializing. - if b == nil { - return nil - } - return b.data -} - -func (b byteBuffer) bigInt() *big.Int { - return new(big.Int).SetBytes(b.data) -} - -func (b byteBuffer) toInt() int { - return int(b.bigInt().Int64()) -} - -// base64URLDecode is implemented as defined in https://www.rfc-editor.org/rfc/rfc7515.html#appendix-C -func base64URLDecode(value string) ([]byte, error) { - value = strings.TrimRight(value, "=") - return base64.RawURLEncoding.DecodeString(value) -} - -func base64EncodeLen(sl []byte) int { - return base64.RawURLEncoding.EncodedLen(len(sl)) -} - -func base64JoinWithDots(inputs ...[]byte) string { - if len(inputs) == 0 { - return "" - } - - // Count of dots. - totalCount := len(inputs) - 1 - - for _, input := range inputs { - totalCount += base64EncodeLen(input) - } - - out := make([]byte, totalCount) - startEncode := 0 - for i, input := range inputs { - base64.RawURLEncoding.Encode(out[startEncode:], input) - - if i == len(inputs)-1 { - continue - } - - startEncode += base64EncodeLen(input) - out[startEncode] = '.' - startEncode++ - } - - return string(out) -} diff --git a/vendor/github.com/go-jose/go-jose/v3/json/LICENSE b/vendor/github.com/go-jose/go-jose/v3/json/LICENSE deleted file mode 100644 index 7448756763..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/json/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/go-jose/go-jose/v3/json/README.md b/vendor/github.com/go-jose/go-jose/v3/json/README.md deleted file mode 100644 index 86de5e5581..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/json/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Safe JSON - -This repository contains a fork of the `encoding/json` package from Go 1.6. - -The following changes were made: - -* Object deserialization uses case-sensitive member name matching instead of - [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html). - This is to avoid differences in the interpretation of JOSE messages between - go-jose and libraries written in other languages. -* When deserializing a JSON object, we check for duplicate keys and reject the - input whenever we detect a duplicate. Rather than trying to work with malformed - data, we prefer to reject it right away. diff --git a/vendor/github.com/go-jose/go-jose/v3/json/decode.go b/vendor/github.com/go-jose/go-jose/v3/json/decode.go deleted file mode 100644 index 50634dd847..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/json/decode.go +++ /dev/null @@ -1,1216 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Represents JSON data structure using native Go types: booleans, floats, -// strings, arrays, and maps. - -package json - -import ( - "bytes" - "encoding" - "encoding/base64" - "errors" - "fmt" - "math" - "reflect" - "runtime" - "strconv" - "unicode" - "unicode/utf16" - "unicode/utf8" -) - -// Unmarshal parses the JSON-encoded data and stores the result -// in the value pointed to by v. -// -// Unmarshal uses the inverse of the encodings that -// Marshal uses, allocating maps, slices, and pointers as necessary, -// with the following additional rules: -// -// To unmarshal JSON into a pointer, Unmarshal first handles the case of -// the JSON being the JSON literal null. In that case, Unmarshal sets -// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into -// the value pointed at by the pointer. If the pointer is nil, Unmarshal -// allocates a new value for it to point to. -// -// To unmarshal JSON into a struct, Unmarshal matches incoming object -// keys to the keys used by Marshal (either the struct field name or its tag), -// preferring an exact match but also accepting a case-insensitive match. -// Unmarshal will only set exported fields of the struct. -// -// To unmarshal JSON into an interface value, -// Unmarshal stores one of these in the interface value: -// -// bool, for JSON booleans -// float64, for JSON numbers -// string, for JSON strings -// []interface{}, for JSON arrays -// map[string]interface{}, for JSON objects -// nil for JSON null -// -// To unmarshal a JSON array into a slice, Unmarshal resets the slice length -// to zero and then appends each element to the slice. -// As a special case, to unmarshal an empty JSON array into a slice, -// Unmarshal replaces the slice with a new empty slice. -// -// To unmarshal a JSON array into a Go array, Unmarshal decodes -// JSON array elements into corresponding Go array elements. -// If the Go array is smaller than the JSON array, -// the additional JSON array elements are discarded. -// If the JSON array is smaller than the Go array, -// the additional Go array elements are set to zero values. -// -// To unmarshal a JSON object into a string-keyed map, Unmarshal first -// establishes a map to use, If the map is nil, Unmarshal allocates a new map. -// Otherwise Unmarshal reuses the existing map, keeping existing entries. -// Unmarshal then stores key-value pairs from the JSON object into the map. -// -// If a JSON value is not appropriate for a given target type, -// or if a JSON number overflows the target type, Unmarshal -// skips that field and completes the unmarshaling as best it can. -// If no more serious errors are encountered, Unmarshal returns -// an UnmarshalTypeError describing the earliest such error. -// -// The JSON null value unmarshals into an interface, map, pointer, or slice -// by setting that Go value to nil. Because null is often used in JSON to mean -// “not present,” unmarshaling a JSON null into any other Go type has no effect -// on the value and produces no error. -// -// When unmarshaling quoted strings, invalid UTF-8 or -// invalid UTF-16 surrogate pairs are not treated as an error. -// Instead, they are replaced by the Unicode replacement -// character U+FFFD. -func Unmarshal(data []byte, v interface{}) error { - // Check for well-formedness. - // Avoids filling out half a data structure - // before discovering a JSON syntax error. - var d decodeState - err := checkValid(data, &d.scan) - if err != nil { - return err - } - - d.init(data) - return d.unmarshal(v) -} - -// Unmarshaler is the interface implemented by objects -// that can unmarshal a JSON description of themselves. -// The input can be assumed to be a valid encoding of -// a JSON value. UnmarshalJSON must copy the JSON data -// if it wishes to retain the data after returning. -type Unmarshaler interface { - UnmarshalJSON([]byte) error -} - -// An UnmarshalTypeError describes a JSON value that was -// not appropriate for a value of a specific Go type. -type UnmarshalTypeError struct { - Value string // description of JSON value - "bool", "array", "number -5" - Type reflect.Type // type of Go value it could not be assigned to - Offset int64 // error occurred after reading Offset bytes -} - -func (e *UnmarshalTypeError) Error() string { - return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String() -} - -// An UnmarshalFieldError describes a JSON object key that -// led to an unexported (and therefore unwritable) struct field. -// (No longer used; kept for compatibility.) -type UnmarshalFieldError struct { - Key string - Type reflect.Type - Field reflect.StructField -} - -func (e *UnmarshalFieldError) Error() string { - return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String() -} - -// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. -// (The argument to Unmarshal must be a non-nil pointer.) -type InvalidUnmarshalError struct { - Type reflect.Type -} - -func (e *InvalidUnmarshalError) Error() string { - if e.Type == nil { - return "json: Unmarshal(nil)" - } - - if e.Type.Kind() != reflect.Ptr { - return "json: Unmarshal(non-pointer " + e.Type.String() + ")" - } - return "json: Unmarshal(nil " + e.Type.String() + ")" -} - -func (d *decodeState) unmarshal(v interface{}) (err error) { - defer func() { - if r := recover(); r != nil { - if _, ok := r.(runtime.Error); ok { - panic(r) - } - err = r.(error) - } - }() - - rv := reflect.ValueOf(v) - if rv.Kind() != reflect.Ptr || rv.IsNil() { - return &InvalidUnmarshalError{reflect.TypeOf(v)} - } - - d.scan.reset() - // We decode rv not rv.Elem because the Unmarshaler interface - // test must be applied at the top level of the value. - d.value(rv) - return d.savedError -} - -// A Number represents a JSON number literal. -type Number string - -// String returns the literal text of the number. -func (n Number) String() string { return string(n) } - -// Float64 returns the number as a float64. -func (n Number) Float64() (float64, error) { - return strconv.ParseFloat(string(n), 64) -} - -// Int64 returns the number as an int64. -func (n Number) Int64() (int64, error) { - return strconv.ParseInt(string(n), 10, 64) -} - -// isValidNumber reports whether s is a valid JSON number literal. -func isValidNumber(s string) bool { - // This function implements the JSON numbers grammar. - // See https://tools.ietf.org/html/rfc7159#section-6 - // and http://json.org/number.gif - - if s == "" { - return false - } - - // Optional - - if s[0] == '-' { - s = s[1:] - if s == "" { - return false - } - } - - // Digits - switch { - default: - return false - - case s[0] == '0': - s = s[1:] - - case '1' <= s[0] && s[0] <= '9': - s = s[1:] - for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { - s = s[1:] - } - } - - // . followed by 1 or more digits. - if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' { - s = s[2:] - for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { - s = s[1:] - } - } - - // e or E followed by an optional - or + and - // 1 or more digits. - if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') { - s = s[1:] - if s[0] == '+' || s[0] == '-' { - s = s[1:] - if s == "" { - return false - } - } - for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { - s = s[1:] - } - } - - // Make sure we are at the end. - return s == "" -} - -type NumberUnmarshalType int - -const ( - // unmarshal a JSON number into an interface{} as a float64 - UnmarshalFloat NumberUnmarshalType = iota - // unmarshal a JSON number into an interface{} as a `json.Number` - UnmarshalJSONNumber - // unmarshal a JSON number into an interface{} as a int64 - // if value is an integer otherwise float64 - UnmarshalIntOrFloat -) - -// decodeState represents the state while decoding a JSON value. -type decodeState struct { - data []byte - off int // read offset in data - scan scanner - nextscan scanner // for calls to nextValue - savedError error - numberType NumberUnmarshalType -} - -// errPhase is used for errors that should not happen unless -// there is a bug in the JSON decoder or something is editing -// the data slice while the decoder executes. -var errPhase = errors.New("JSON decoder out of sync - data changing underfoot?") - -func (d *decodeState) init(data []byte) *decodeState { - d.data = data - d.off = 0 - d.savedError = nil - return d -} - -// error aborts the decoding by panicking with err. -func (d *decodeState) error(err error) { - panic(err) -} - -// saveError saves the first err it is called with, -// for reporting at the end of the unmarshal. -func (d *decodeState) saveError(err error) { - if d.savedError == nil { - d.savedError = err - } -} - -// next cuts off and returns the next full JSON value in d.data[d.off:]. -// The next value is known to be an object or array, not a literal. -func (d *decodeState) next() []byte { - c := d.data[d.off] - item, rest, err := nextValue(d.data[d.off:], &d.nextscan) - if err != nil { - d.error(err) - } - d.off = len(d.data) - len(rest) - - // Our scanner has seen the opening brace/bracket - // and thinks we're still in the middle of the object. - // invent a closing brace/bracket to get it out. - if c == '{' { - d.scan.step(&d.scan, '}') - } else { - d.scan.step(&d.scan, ']') - } - - return item -} - -// scanWhile processes bytes in d.data[d.off:] until it -// receives a scan code not equal to op. -// It updates d.off and returns the new scan code. -func (d *decodeState) scanWhile(op int) int { - var newOp int - for { - if d.off >= len(d.data) { - newOp = d.scan.eof() - d.off = len(d.data) + 1 // mark processed EOF with len+1 - } else { - c := d.data[d.off] - d.off++ - newOp = d.scan.step(&d.scan, c) - } - if newOp != op { - break - } - } - return newOp -} - -// value decodes a JSON value from d.data[d.off:] into the value. -// it updates d.off to point past the decoded value. -func (d *decodeState) value(v reflect.Value) { - if !v.IsValid() { - _, rest, err := nextValue(d.data[d.off:], &d.nextscan) - if err != nil { - d.error(err) - } - d.off = len(d.data) - len(rest) - - // d.scan thinks we're still at the beginning of the item. - // Feed in an empty string - the shortest, simplest value - - // so that it knows we got to the end of the value. - if d.scan.redo { - // rewind. - d.scan.redo = false - d.scan.step = stateBeginValue - } - d.scan.step(&d.scan, '"') - d.scan.step(&d.scan, '"') - - n := len(d.scan.parseState) - if n > 0 && d.scan.parseState[n-1] == parseObjectKey { - // d.scan thinks we just read an object key; finish the object - d.scan.step(&d.scan, ':') - d.scan.step(&d.scan, '"') - d.scan.step(&d.scan, '"') - d.scan.step(&d.scan, '}') - } - - return - } - - switch op := d.scanWhile(scanSkipSpace); op { - default: - d.error(errPhase) - - case scanBeginArray: - d.array(v) - - case scanBeginObject: - d.object(v) - - case scanBeginLiteral: - d.literal(v) - } -} - -type unquotedValue struct{} - -// valueQuoted is like value but decodes a -// quoted string literal or literal null into an interface value. -// If it finds anything other than a quoted string literal or null, -// valueQuoted returns unquotedValue{}. -func (d *decodeState) valueQuoted() interface{} { - switch op := d.scanWhile(scanSkipSpace); op { - default: - d.error(errPhase) - - case scanBeginArray: - d.array(reflect.Value{}) - - case scanBeginObject: - d.object(reflect.Value{}) - - case scanBeginLiteral: - switch v := d.literalInterface().(type) { - case nil, string: - return v - } - } - return unquotedValue{} -} - -// indirect walks down v allocating pointers as needed, -// until it gets to a non-pointer. -// if it encounters an Unmarshaler, indirect stops and returns that. -// if decodingNull is true, indirect stops at the last pointer so it can be set to nil. -func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { - // If v is a named type and is addressable, - // start with its address, so that if the type has pointer methods, - // we find them. - if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() { - v = v.Addr() - } - for { - // Load value from interface, but only if the result will be - // usefully addressable. - if v.Kind() == reflect.Interface && !v.IsNil() { - e := v.Elem() - if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) { - v = e - continue - } - } - - if v.Kind() != reflect.Ptr { - break - } - - if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() { - break - } - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) - } - if v.Type().NumMethod() > 0 { - if u, ok := v.Interface().(Unmarshaler); ok { - return u, nil, reflect.Value{} - } - if u, ok := v.Interface().(encoding.TextUnmarshaler); ok { - return nil, u, reflect.Value{} - } - } - v = v.Elem() - } - return nil, nil, v -} - -// array consumes an array from d.data[d.off-1:], decoding into the value v. -// the first byte of the array ('[') has been read already. -func (d *decodeState) array(v reflect.Value) { - // Check for unmarshaler. - u, ut, pv := d.indirect(v, false) - if u != nil { - d.off-- - err := u.UnmarshalJSON(d.next()) - if err != nil { - d.error(err) - } - return - } - if ut != nil { - d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)}) - d.off-- - d.next() - return - } - - v = pv - - // Check type of target. - switch v.Kind() { - case reflect.Interface: - if v.NumMethod() == 0 { - // Decoding into nil interface? Switch to non-reflect code. - v.Set(reflect.ValueOf(d.arrayInterface())) - return - } - // Otherwise it's invalid. - fallthrough - default: - d.saveError(&UnmarshalTypeError{"array", v.Type(), int64(d.off)}) - d.off-- - d.next() - return - case reflect.Array: - case reflect.Slice: - break - } - - i := 0 - for { - // Look ahead for ] - can only happen on first iteration. - op := d.scanWhile(scanSkipSpace) - if op == scanEndArray { - break - } - - // Back up so d.value can have the byte we just read. - d.off-- - d.scan.undo(op) - - // Get element of array, growing if necessary. - if v.Kind() == reflect.Slice { - // Grow slice if necessary - if i >= v.Cap() { - newcap := v.Cap() + v.Cap()/2 - if newcap < 4 { - newcap = 4 - } - newv := reflect.MakeSlice(v.Type(), v.Len(), newcap) - reflect.Copy(newv, v) - v.Set(newv) - } - if i >= v.Len() { - v.SetLen(i + 1) - } - } - - if i < v.Len() { - // Decode into element. - d.value(v.Index(i)) - } else { - // Ran out of fixed array: skip. - d.value(reflect.Value{}) - } - i++ - - // Next token must be , or ]. - op = d.scanWhile(scanSkipSpace) - if op == scanEndArray { - break - } - if op != scanArrayValue { - d.error(errPhase) - } - } - - if i < v.Len() { - if v.Kind() == reflect.Array { - // Array. Zero the rest. - z := reflect.Zero(v.Type().Elem()) - for ; i < v.Len(); i++ { - v.Index(i).Set(z) - } - } else { - v.SetLen(i) - } - } - if i == 0 && v.Kind() == reflect.Slice { - v.Set(reflect.MakeSlice(v.Type(), 0, 0)) - } -} - -var nullLiteral = []byte("null") - -// object consumes an object from d.data[d.off-1:], decoding into the value v. -// the first byte ('{') of the object has been read already. -func (d *decodeState) object(v reflect.Value) { - // Check for unmarshaler. - u, ut, pv := d.indirect(v, false) - if u != nil { - d.off-- - err := u.UnmarshalJSON(d.next()) - if err != nil { - d.error(err) - } - return - } - if ut != nil { - d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) - d.off-- - d.next() // skip over { } in input - return - } - v = pv - - // Decoding into nil interface? Switch to non-reflect code. - if v.Kind() == reflect.Interface && v.NumMethod() == 0 { - v.Set(reflect.ValueOf(d.objectInterface())) - return - } - - // Check type of target: struct or map[string]T - switch v.Kind() { - case reflect.Map: - // map must have string kind - t := v.Type() - if t.Key().Kind() != reflect.String { - d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) - d.off-- - d.next() // skip over { } in input - return - } - if v.IsNil() { - v.Set(reflect.MakeMap(t)) - } - case reflect.Struct: - - default: - d.saveError(&UnmarshalTypeError{"object", v.Type(), int64(d.off)}) - d.off-- - d.next() // skip over { } in input - return - } - - var mapElem reflect.Value - keys := map[string]bool{} - - for { - // Read opening " of string key or closing }. - op := d.scanWhile(scanSkipSpace) - if op == scanEndObject { - // closing } - can only happen on first iteration. - break - } - if op != scanBeginLiteral { - d.error(errPhase) - } - - // Read key. - start := d.off - 1 - op = d.scanWhile(scanContinue) - item := d.data[start : d.off-1] - key, ok := unquote(item) - if !ok { - d.error(errPhase) - } - - // Check for duplicate keys. - _, ok = keys[key] - if !ok { - keys[key] = true - } else { - d.error(fmt.Errorf("json: duplicate key '%s' in object", key)) - } - - // Figure out field corresponding to key. - var subv reflect.Value - destring := false // whether the value is wrapped in a string to be decoded first - - if v.Kind() == reflect.Map { - elemType := v.Type().Elem() - if !mapElem.IsValid() { - mapElem = reflect.New(elemType).Elem() - } else { - mapElem.Set(reflect.Zero(elemType)) - } - subv = mapElem - } else { - var f *field - fields := cachedTypeFields(v.Type()) - for i := range fields { - ff := &fields[i] - if bytes.Equal(ff.nameBytes, []byte(key)) { - f = ff - break - } - } - if f != nil { - subv = v - destring = f.quoted - for _, i := range f.index { - if subv.Kind() == reflect.Ptr { - if subv.IsNil() { - subv.Set(reflect.New(subv.Type().Elem())) - } - subv = subv.Elem() - } - subv = subv.Field(i) - } - } - } - - // Read : before value. - if op == scanSkipSpace { - op = d.scanWhile(scanSkipSpace) - } - if op != scanObjectKey { - d.error(errPhase) - } - - // Read value. - if destring { - switch qv := d.valueQuoted().(type) { - case nil: - d.literalStore(nullLiteral, subv, false) - case string: - d.literalStore([]byte(qv), subv, true) - default: - d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type())) - } - } else { - d.value(subv) - } - - // Write value back to map; - // if using struct, subv points into struct already. - if v.Kind() == reflect.Map { - kv := reflect.ValueOf(key).Convert(v.Type().Key()) - v.SetMapIndex(kv, subv) - } - - // Next token must be , or }. - op = d.scanWhile(scanSkipSpace) - if op == scanEndObject { - break - } - if op != scanObjectValue { - d.error(errPhase) - } - } -} - -// literal consumes a literal from d.data[d.off-1:], decoding into the value v. -// The first byte of the literal has been read already -// (that's how the caller knows it's a literal). -func (d *decodeState) literal(v reflect.Value) { - // All bytes inside literal return scanContinue op code. - start := d.off - 1 - op := d.scanWhile(scanContinue) - - // Scan read one byte too far; back up. - d.off-- - d.scan.undo(op) - - d.literalStore(d.data[start:d.off], v, false) -} - -// convertNumber converts the number literal s to a float64, int64 or a Number -// depending on d.numberDecodeType. -func (d *decodeState) convertNumber(s string) (interface{}, error) { - switch d.numberType { - - case UnmarshalJSONNumber: - return Number(s), nil - case UnmarshalIntOrFloat: - v, err := strconv.ParseInt(s, 10, 64) - if err == nil { - return v, nil - } - - // tries to parse integer number in scientific notation - f, err := strconv.ParseFloat(s, 64) - if err != nil { - return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)} - } - - // if it has no decimal value use int64 - if fi, fd := math.Modf(f); fd == 0.0 { - return int64(fi), nil - } - return f, nil - default: - f, err := strconv.ParseFloat(s, 64) - if err != nil { - return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)} - } - return f, nil - } - -} - -var numberType = reflect.TypeOf(Number("")) - -// literalStore decodes a literal stored in item into v. -// -// fromQuoted indicates whether this literal came from unwrapping a -// string from the ",string" struct tag option. this is used only to -// produce more helpful error messages. -func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) { - // Check for unmarshaler. - if len(item) == 0 { - //Empty string given - d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) - return - } - wantptr := item[0] == 'n' // null - u, ut, pv := d.indirect(v, wantptr) - if u != nil { - err := u.UnmarshalJSON(item) - if err != nil { - d.error(err) - } - return - } - if ut != nil { - if item[0] != '"' { - if fromQuoted { - d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) - } else { - d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) - } - return - } - s, ok := unquoteBytes(item) - if !ok { - if fromQuoted { - d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) - } else { - d.error(errPhase) - } - } - err := ut.UnmarshalText(s) - if err != nil { - d.error(err) - } - return - } - - v = pv - - switch c := item[0]; c { - case 'n': // null - switch v.Kind() { - case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: - v.Set(reflect.Zero(v.Type())) - // otherwise, ignore null for primitives/string - } - case 't', 'f': // true, false - value := c == 't' - switch v.Kind() { - default: - if fromQuoted { - d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) - } else { - d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)}) - } - case reflect.Bool: - v.SetBool(value) - case reflect.Interface: - if v.NumMethod() == 0 { - v.Set(reflect.ValueOf(value)) - } else { - d.saveError(&UnmarshalTypeError{"bool", v.Type(), int64(d.off)}) - } - } - - case '"': // string - s, ok := unquoteBytes(item) - if !ok { - if fromQuoted { - d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) - } else { - d.error(errPhase) - } - } - switch v.Kind() { - default: - d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) - case reflect.Slice: - if v.Type().Elem().Kind() != reflect.Uint8 { - d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) - break - } - b := make([]byte, base64.StdEncoding.DecodedLen(len(s))) - n, err := base64.StdEncoding.Decode(b, s) - if err != nil { - d.saveError(err) - break - } - v.SetBytes(b[:n]) - case reflect.String: - v.SetString(string(s)) - case reflect.Interface: - if v.NumMethod() == 0 { - v.Set(reflect.ValueOf(string(s))) - } else { - d.saveError(&UnmarshalTypeError{"string", v.Type(), int64(d.off)}) - } - } - - default: // number - if c != '-' && (c < '0' || c > '9') { - if fromQuoted { - d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) - } else { - d.error(errPhase) - } - } - s := string(item) - switch v.Kind() { - default: - if v.Kind() == reflect.String && v.Type() == numberType { - v.SetString(s) - if !isValidNumber(s) { - d.error(fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item)) - } - break - } - if fromQuoted { - d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())) - } else { - d.error(&UnmarshalTypeError{"number", v.Type(), int64(d.off)}) - } - case reflect.Interface: - n, err := d.convertNumber(s) - if err != nil { - d.saveError(err) - break - } - if v.NumMethod() != 0 { - d.saveError(&UnmarshalTypeError{"number", v.Type(), int64(d.off)}) - break - } - v.Set(reflect.ValueOf(n)) - - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - n, err := strconv.ParseInt(s, 10, 64) - if err != nil || v.OverflowInt(n) { - d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)}) - break - } - v.SetInt(n) - - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - n, err := strconv.ParseUint(s, 10, 64) - if err != nil || v.OverflowUint(n) { - d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)}) - break - } - v.SetUint(n) - - case reflect.Float32, reflect.Float64: - n, err := strconv.ParseFloat(s, v.Type().Bits()) - if err != nil || v.OverflowFloat(n) { - d.saveError(&UnmarshalTypeError{"number " + s, v.Type(), int64(d.off)}) - break - } - v.SetFloat(n) - } - } -} - -// The xxxInterface routines build up a value to be stored -// in an empty interface. They are not strictly necessary, -// but they avoid the weight of reflection in this common case. - -// valueInterface is like value but returns interface{} -func (d *decodeState) valueInterface() interface{} { - switch d.scanWhile(scanSkipSpace) { - default: - d.error(errPhase) - panic("unreachable") - case scanBeginArray: - return d.arrayInterface() - case scanBeginObject: - return d.objectInterface() - case scanBeginLiteral: - return d.literalInterface() - } -} - -// arrayInterface is like array but returns []interface{}. -func (d *decodeState) arrayInterface() []interface{} { - var v = make([]interface{}, 0) - for { - // Look ahead for ] - can only happen on first iteration. - op := d.scanWhile(scanSkipSpace) - if op == scanEndArray { - break - } - - // Back up so d.value can have the byte we just read. - d.off-- - d.scan.undo(op) - - v = append(v, d.valueInterface()) - - // Next token must be , or ]. - op = d.scanWhile(scanSkipSpace) - if op == scanEndArray { - break - } - if op != scanArrayValue { - d.error(errPhase) - } - } - return v -} - -// objectInterface is like object but returns map[string]interface{}. -func (d *decodeState) objectInterface() map[string]interface{} { - m := make(map[string]interface{}) - keys := map[string]bool{} - - for { - // Read opening " of string key or closing }. - op := d.scanWhile(scanSkipSpace) - if op == scanEndObject { - // closing } - can only happen on first iteration. - break - } - if op != scanBeginLiteral { - d.error(errPhase) - } - - // Read string key. - start := d.off - 1 - op = d.scanWhile(scanContinue) - item := d.data[start : d.off-1] - key, ok := unquote(item) - if !ok { - d.error(errPhase) - } - - // Check for duplicate keys. - _, ok = keys[key] - if !ok { - keys[key] = true - } else { - d.error(fmt.Errorf("json: duplicate key '%s' in object", key)) - } - - // Read : before value. - if op == scanSkipSpace { - op = d.scanWhile(scanSkipSpace) - } - if op != scanObjectKey { - d.error(errPhase) - } - - // Read value. - m[key] = d.valueInterface() - - // Next token must be , or }. - op = d.scanWhile(scanSkipSpace) - if op == scanEndObject { - break - } - if op != scanObjectValue { - d.error(errPhase) - } - } - return m -} - -// literalInterface is like literal but returns an interface value. -func (d *decodeState) literalInterface() interface{} { - // All bytes inside literal return scanContinue op code. - start := d.off - 1 - op := d.scanWhile(scanContinue) - - // Scan read one byte too far; back up. - d.off-- - d.scan.undo(op) - item := d.data[start:d.off] - - switch c := item[0]; c { - case 'n': // null - return nil - - case 't', 'f': // true, false - return c == 't' - - case '"': // string - s, ok := unquote(item) - if !ok { - d.error(errPhase) - } - return s - - default: // number - if c != '-' && (c < '0' || c > '9') { - d.error(errPhase) - } - n, err := d.convertNumber(string(item)) - if err != nil { - d.saveError(err) - } - return n - } -} - -// getu4 decodes \uXXXX from the beginning of s, returning the hex value, -// or it returns -1. -func getu4(s []byte) rune { - if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { - return -1 - } - r, err := strconv.ParseUint(string(s[2:6]), 16, 64) - if err != nil { - return -1 - } - return rune(r) -} - -// unquote converts a quoted JSON string literal s into an actual string t. -// The rules are different than for Go, so cannot use strconv.Unquote. -func unquote(s []byte) (t string, ok bool) { - s, ok = unquoteBytes(s) - t = string(s) - return -} - -func unquoteBytes(s []byte) (t []byte, ok bool) { - if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' { - return - } - s = s[1 : len(s)-1] - - // Check for unusual characters. If there are none, - // then no unquoting is needed, so return a slice of the - // original bytes. - r := 0 - for r < len(s) { - c := s[r] - if c == '\\' || c == '"' || c < ' ' { - break - } - if c < utf8.RuneSelf { - r++ - continue - } - rr, size := utf8.DecodeRune(s[r:]) - if rr == utf8.RuneError && size == 1 { - break - } - r += size - } - if r == len(s) { - return s, true - } - - b := make([]byte, len(s)+2*utf8.UTFMax) - w := copy(b, s[0:r]) - for r < len(s) { - // Out of room? Can only happen if s is full of - // malformed UTF-8 and we're replacing each - // byte with RuneError. - if w >= len(b)-2*utf8.UTFMax { - nb := make([]byte, (len(b)+utf8.UTFMax)*2) - copy(nb, b[0:w]) - b = nb - } - switch c := s[r]; { - case c == '\\': - r++ - if r >= len(s) { - return - } - switch s[r] { - default: - return - case '"', '\\', '/', '\'': - b[w] = s[r] - r++ - w++ - case 'b': - b[w] = '\b' - r++ - w++ - case 'f': - b[w] = '\f' - r++ - w++ - case 'n': - b[w] = '\n' - r++ - w++ - case 'r': - b[w] = '\r' - r++ - w++ - case 't': - b[w] = '\t' - r++ - w++ - case 'u': - r-- - rr := getu4(s[r:]) - if rr < 0 { - return - } - r += 6 - if utf16.IsSurrogate(rr) { - rr1 := getu4(s[r:]) - if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar { - // A valid pair; consume. - r += 6 - w += utf8.EncodeRune(b[w:], dec) - break - } - // Invalid surrogate; fall back to replacement rune. - rr = unicode.ReplacementChar - } - w += utf8.EncodeRune(b[w:], rr) - } - - // Quote, control characters are invalid. - case c == '"', c < ' ': - return - - // ASCII - case c < utf8.RuneSelf: - b[w] = c - r++ - w++ - - // Coerce to well-formed UTF-8. - default: - rr, size := utf8.DecodeRune(s[r:]) - r += size - w += utf8.EncodeRune(b[w:], rr) - } - } - return b[0:w], true -} diff --git a/vendor/github.com/go-jose/go-jose/v3/json/encode.go b/vendor/github.com/go-jose/go-jose/v3/json/encode.go deleted file mode 100644 index 98de68ce1e..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/json/encode.go +++ /dev/null @@ -1,1197 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package json implements encoding and decoding of JSON objects as defined in -// RFC 4627. The mapping between JSON objects and Go values is described -// in the documentation for the Marshal and Unmarshal functions. -// -// See "JSON and Go" for an introduction to this package: -// https://golang.org/doc/articles/json_and_go.html -package json - -import ( - "bytes" - "encoding" - "encoding/base64" - "fmt" - "math" - "reflect" - "runtime" - "sort" - "strconv" - "strings" - "sync" - "unicode" - "unicode/utf8" -) - -// Marshal returns the JSON encoding of v. -// -// Marshal traverses the value v recursively. -// If an encountered value implements the Marshaler interface -// and is not a nil pointer, Marshal calls its MarshalJSON method -// to produce JSON. If no MarshalJSON method is present but the -// value implements encoding.TextMarshaler instead, Marshal calls -// its MarshalText method. -// The nil pointer exception is not strictly necessary -// but mimics a similar, necessary exception in the behavior of -// UnmarshalJSON. -// -// Otherwise, Marshal uses the following type-dependent default encodings: -// -// Boolean values encode as JSON booleans. -// -// Floating point, integer, and Number values encode as JSON numbers. -// -// String values encode as JSON strings coerced to valid UTF-8, -// replacing invalid bytes with the Unicode replacement rune. -// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" -// to keep some browsers from misinterpreting JSON output as HTML. -// Ampersand "&" is also escaped to "\u0026" for the same reason. -// -// Array and slice values encode as JSON arrays, except that -// []byte encodes as a base64-encoded string, and a nil slice -// encodes as the null JSON object. -// -// Struct values encode as JSON objects. Each exported struct field -// becomes a member of the object unless -// - the field's tag is "-", or -// - the field is empty and its tag specifies the "omitempty" option. -// -// The empty values are false, 0, any -// nil pointer or interface value, and any array, slice, map, or string of -// length zero. The object's default key string is the struct field name -// but can be specified in the struct field's tag value. The "json" key in -// the struct field's tag value is the key name, followed by an optional comma -// and options. Examples: -// -// // Field is ignored by this package. -// Field int `json:"-"` -// -// // Field appears in JSON as key "myName". -// Field int `json:"myName"` -// -// // Field appears in JSON as key "myName" and -// // the field is omitted from the object if its value is empty, -// // as defined above. -// Field int `json:"myName,omitempty"` -// -// // Field appears in JSON as key "Field" (the default), but -// // the field is skipped if empty. -// // Note the leading comma. -// Field int `json:",omitempty"` -// -// The "string" option signals that a field is stored as JSON inside a -// JSON-encoded string. It applies only to fields of string, floating point, -// integer, or boolean types. This extra level of encoding is sometimes used -// when communicating with JavaScript programs: -// -// Int64String int64 `json:",string"` -// -// The key name will be used if it's a non-empty string consisting of -// only Unicode letters, digits, dollar signs, percent signs, hyphens, -// underscores and slashes. -// -// Anonymous struct fields are usually marshaled as if their inner exported fields -// were fields in the outer struct, subject to the usual Go visibility rules amended -// as described in the next paragraph. -// An anonymous struct field with a name given in its JSON tag is treated as -// having that name, rather than being anonymous. -// An anonymous struct field of interface type is treated the same as having -// that type as its name, rather than being anonymous. -// -// The Go visibility rules for struct fields are amended for JSON when -// deciding which field to marshal or unmarshal. If there are -// multiple fields at the same level, and that level is the least -// nested (and would therefore be the nesting level selected by the -// usual Go rules), the following extra rules apply: -// -// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, -// even if there are multiple untagged fields that would otherwise conflict. -// 2) If there is exactly one field (tagged or not according to the first rule), that is selected. -// 3) Otherwise there are multiple fields, and all are ignored; no error occurs. -// -// Handling of anonymous struct fields is new in Go 1.1. -// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of -// an anonymous struct field in both current and earlier versions, give the field -// a JSON tag of "-". -// -// Map values encode as JSON objects. -// The map's key type must be string; the map keys are used as JSON object -// keys, subject to the UTF-8 coercion described for string values above. -// -// Pointer values encode as the value pointed to. -// A nil pointer encodes as the null JSON object. -// -// Interface values encode as the value contained in the interface. -// A nil interface value encodes as the null JSON object. -// -// Channel, complex, and function values cannot be encoded in JSON. -// Attempting to encode such a value causes Marshal to return -// an UnsupportedTypeError. -// -// JSON cannot represent cyclic data structures and Marshal does not -// handle them. Passing cyclic structures to Marshal will result in -// an infinite recursion. -func Marshal(v interface{}) ([]byte, error) { - e := &encodeState{} - err := e.marshal(v) - if err != nil { - return nil, err - } - return e.Bytes(), nil -} - -// MarshalIndent is like Marshal but applies Indent to format the output. -func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { - b, err := Marshal(v) - if err != nil { - return nil, err - } - var buf bytes.Buffer - err = Indent(&buf, b, prefix, indent) - if err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 -// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 -// so that the JSON will be safe to embed inside HTML