code: func parseLegacyResourceAddress(s string) (addrs.ResourceInstance, error) {
  	var ret addrs.ResourceInstance
  
  	// Split based on ".". Every resource address should have at least two
  	// elements (type and name).
  	parts := strings.Split(s, ".")
  	if len(parts) < 2 || len(parts) > 4 {
  		return ret, fmt.Errorf("invalid internal resource address format: %s", s)
  	}
  
  	// Data resource if we have at least 3 parts and the first one is data
  	ret.Resource.Mode = addrs.ManagedResourceMode
  	if len(parts) > 2 && parts[0] == "data" {
  		ret.Resource.Mode = addrs.DataResourceMode
  		parts = parts[1:]
  	}
  
  	// If we're not a data resource and we have more than 3, then it is an error
  	if len(parts) > 3 && ret.Resource.Mode != addrs.DataResourceMode {
  		return ret, fmt.Errorf("invalid internal resource address format: %s", s)
  	}
  
  	// Build the parts of the resource address that are guaranteed to exist
  	ret.Resource.Type = parts[0]
  	ret.Resource.Name = parts[1]
  	ret.Key = addrs.NoKey
  
  	// If we have more parts, then we have an index. Parse that.
  	if len(parts) > 2 {
  		idx, err := strconv.ParseInt(parts[2], 0, 0)
  		if err != nil {
  			return ret, fmt.Errorf("error parsing resource address %q: %s", s, err)
  		}
  
  		ret.Key = addrs.IntKey(idx)
  	}
  
  	return ret, nil
  }
docs: // parseLegacyResourceAddress parses the different identifier format used
  // state formats before version 4, like "instance.name.0".