code: func NewResourceConfigShimmed(val cty.Value, schema *configschema.Block) *ResourceConfig {
  	if !val.Type().IsObjectType() {
  		panic(fmt.Errorf("NewResourceConfigShimmed given %#v; an object type is required", val.Type()))
  	}
  	ret := &ResourceConfig{}
  
  	legacyVal := hcl2shim.ConfigValueFromHCL2Block(val, schema)
  	if legacyVal != nil {
  		ret.Config = legacyVal
  
  		// Now we need to walk through our structure and find any unknown values,
  		// producing the separate list ComputedKeys to represent these. We use the
  		// schema here so that we can preserve the expected invariant
  		// that an attribute is always either wholly known or wholly unknown, while
  		// a child block can be partially unknown.
  		ret.ComputedKeys = newResourceConfigShimmedComputedKeys(val, schema, "")
  	} else {
  		ret.Config = make(map[string]interface{})
  	}
  	ret.Raw = ret.Config
  
  	return ret
  }
docs: // NewResourceConfigShimmed wraps a cty.Value of object type in a legacy
  // ResourceConfig object, so that it can be passed to older APIs that expect
  // this wrapping.
  //
  // The returned ResourceConfig is already interpolated and cannot be
  // re-interpolated. It is, therefore, useful only to functions that expect
  // an already-populated ResourceConfig which they then treat as read-only.
  //
  // If the given value is not of an object type that conforms to the given
  // schema then this function will panic.