code: func parseResourceAddressInternal(s string) (*ResourceAddress, error) {
  	// 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 nil, fmt.Errorf("Invalid internal resource address format: %s", s)
  	}
  
  	// Data resource if we have at least 3 parts and the first one is data
  	mode := config.ManagedResourceMode
  	if len(parts) > 2 && parts[0] == "data" {
  		mode = config.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 && mode != config.DataResourceMode {
  		return nil, fmt.Errorf("Invalid internal resource address format: %s", s)
  	}
  
  	// Build the parts of the resource address that are guaranteed to exist
  	addr := &ResourceAddress{
  		Type:         parts[0],
  		Name:         parts[1],
  		Index:        -1,
  		InstanceType: TypePrimary,
  		Mode:         mode,
  	}
  
  	// 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 nil, fmt.Errorf("Error parsing resource address %q: %s", s, err)
  		}
  
  		addr.Index = int(idx)
  	}
  
  	return addr, nil
  }
docs: // parseResourceAddressInternal parses the somewhat bespoke resource
  // identifier used in states and diffs, such as "instance.name.0".