func()

in internal/meta/config_info.go [145:195]


func (cfgs ConfigInfos) addReferenceDependency() error {
	// TF resource id to Azure resource ids.
	// Typically, one TF resource id maps to one Azure resource id. However, there are cases that one one TF resource id maps to multiple Azure resource ids.
	// E.g. A parent and child resources have the same TF id. Or the association resource's TF id is the same as the master resource's.
	m := map[string][]armid.ResourceId{}
	for _, cfg := range cfgs {
		m[cfg.TFResourceId] = append(m[cfg.TFResourceId], cfg.AzureResourceID)
	}

	for i, cfg := range cfgs {
		file, err := hclsyntax.ParseConfig(cfg.hcl.Bytes(), "main.tf", hcl.InitialPos)
		if err != nil {
			return fmt.Errorf("parsing hcl for %s: %v", cfg.AzureResourceID, err)
		}
		hclsyntax.VisitAll(file.Body.(*hclsyntax.Body), func(node hclsyntax.Node) hcl.Diagnostics {
			expr, ok := node.(*hclsyntax.LiteralValueExpr)
			if !ok {
				return nil
			}
			val := expr.Val
			if !expr.Val.IsKnown() || !val.Type().Equals(cty.String) {
				return nil
			}
			maybeTFId := val.AsString()

			// This is safe to match case sensitively given the TF id are consistent across the provider. Otherwise, it is a provider bug.
			dependingResourceIds, ok := m[maybeTFId]
			if !ok {
				return nil
			}

			var dependingResourceIdsWithoutSelf []string
			for _, id := range dependingResourceIds[:] {
				if id.String() == cfg.AzureResourceID.String() {
					continue
				}
				// if cfg is parent of `id` resource, we should skip, or it will cause circular dependency, so skip parent depends on sub resources
				if cfg.AzureResourceID.Equal(id.Parent()) {
					continue
				}
				dependingResourceIdsWithoutSelf = append(dependingResourceIdsWithoutSelf, id.String())
			}
			if len(dependingResourceIdsWithoutSelf) != 0 {
				cfg.DependsOn = append(cfg.DependsOn, Dependency{Candidates: dependingResourceIdsWithoutSelf})
			}
			return nil
		})
		cfgs[i] = cfg
	}
	return nil
}