github.com/myhau/pulumi/pkg/v3@v3.70.2-0.20221116134521-f2775972e587/resource/deploy/state_builder.go (about)

     1  // Copyright 2016-2022, Pulumi Corporation.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package deploy
    16  
    17  import (
    18  	"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
    19  )
    20  
    21  // Simplifies non-mutating edits on resource.State
    22  type stateBuilder struct {
    23  	state    resource.State
    24  	original *resource.State
    25  	edited   bool
    26  }
    27  
    28  func newStateBuilder(state *resource.State) *stateBuilder {
    29  	return &stateBuilder{*state, state, false}
    30  }
    31  
    32  func (sb *stateBuilder) withUpdatedParent(update func(resource.URN) resource.URN) *stateBuilder {
    33  	if sb.state.Parent != "" {
    34  		sb.setURN(&sb.state.Parent, update(sb.state.Parent))
    35  	}
    36  	return sb
    37  }
    38  
    39  func (sb *stateBuilder) withUpdatedProvider(update func(string) string) *stateBuilder {
    40  	if sb.state.Provider != "" {
    41  		sb.setString(&sb.state.Provider, update(sb.state.Provider))
    42  	}
    43  	return sb
    44  }
    45  
    46  func (sb *stateBuilder) withUpdatedDependencies(update func(resource.URN) resource.URN) *stateBuilder {
    47  	var edited bool
    48  	edited, sb.state.Dependencies = sb.updateURNSlice(sb.state.Dependencies, update)
    49  	sb.edited = sb.edited || edited
    50  	return sb
    51  }
    52  
    53  func (sb *stateBuilder) withUpdatedPropertyDependencies(update func(resource.URN) resource.URN) *stateBuilder {
    54  	m := map[resource.PropertyKey][]resource.URN{}
    55  	edited := false
    56  	for k, urns := range sb.state.PropertyDependencies {
    57  		var edit bool
    58  		edit, m[k] = sb.updateURNSlice(urns, update)
    59  		edited = edited || edit
    60  	}
    61  	if edited {
    62  		sb.state.PropertyDependencies = m
    63  	}
    64  	sb.edited = sb.edited || edited
    65  	return sb
    66  }
    67  
    68  func (sb *stateBuilder) build() *resource.State {
    69  	if !sb.edited {
    70  		return sb.original
    71  	}
    72  	return &sb.state
    73  }
    74  
    75  // internal
    76  func (sb *stateBuilder) setString(loc *string, value string) {
    77  	if *loc == value {
    78  		return
    79  	}
    80  	sb.edited = true
    81  	*loc = value
    82  }
    83  
    84  // internal
    85  func (sb *stateBuilder) setURN(loc *resource.URN, value resource.URN) {
    86  	if *loc == value {
    87  		return
    88  	}
    89  	sb.edited = true
    90  	*loc = value
    91  }
    92  
    93  // internal
    94  func (sb *stateBuilder) updateURNSlice(
    95  	slice []resource.URN,
    96  	update func(resource.URN) resource.URN) (bool, []resource.URN) {
    97  	needsUpdate := false
    98  	for _, urn := range slice {
    99  		if update(urn) != urn {
   100  			needsUpdate = true
   101  			break
   102  		}
   103  	}
   104  	if !needsUpdate {
   105  		return false, slice
   106  	}
   107  	copy := make([]resource.URN, len(slice))
   108  	for i, urn := range slice {
   109  		copy[i] = update(urn)
   110  	}
   111  	return true, copy
   112  }