code: func parseIndexTag(indexName, dosaAnnotation string) (string, *PrimaryKey, error) {
  	// index name struct must be exported in the entity,
  	// otherwise it will be ignored when upserting the schema.
  	if len(indexName) != 0 && unicode.IsLower([]rune(indexName)[0]) {
  		expected := []rune(indexName)
  		expected[0] = unicode.ToUpper(expected[0])
  		return "", nil, fmt.Errorf("index name (%s) must be exported, "+
  			"try (%s) instead", indexName, string(expected))
  	}
  	tag := dosaAnnotation
  	// find the primaryKey
  	matchs := indexKeyPattern0.FindStringSubmatch(tag)
  	if len(matchs) != 4 {
  		return "", nil, fmt.Errorf("dosa.Index %s with an invalid dosa index tag %q", indexName, tag)
  	}
  	pkString := matchs[1]
  	key, err := parsePrimaryKey(indexName, pkString)
  	if err != nil {
  		return "", nil, errors.Wrapf(err, "struct %s has an invalid index key %q", indexName, pkString)
  	}
  	toRemove := strings.TrimSuffix(matchs[0], matchs[2])
  	toRemove = strings.TrimSuffix(matchs[0], matchs[3])
  	tag = strings.Replace(tag, toRemove, "", 1)
  
  	//find the name
  	fullNameTag, name, err := parseNameTag(tag, indexName)
  	if err != nil {
  		return "", nil, errors.Wrapf(err, "invalid name tag: %s", tag)
  	}
  
  	tag = strings.Replace(tag, fullNameTag, "", 1)
  	tag = strings.TrimSpace(tag)
  	if tag != "" {
  		return "", nil, fmt.Errorf("index field %s with an invalid dosa index tag: %s", indexName, tag)
  	}
  
  	return name, key, nil
  }
docs: // parseIndexTag functions parses DOSA index tag