| 247 | } |
| 248 | |
| 249 | func aliasAs(kind, qualifiedName, alias string, requireQualified bool) ContainerOption { |
| 250 | return func(c *Container) (*Container, error) { |
| 251 | if len(alias) == 0 || strings.Contains(alias, ".") { |
| 252 | return nil, fmt.Errorf( |
| 253 | "%s must be non-empty and simple (not qualified): %s=%s", kind, kind, alias) |
| 254 | } |
| 255 | |
| 256 | if len(qualifiedName) == 0 { |
| 257 | return nil, fmt.Errorf("%s must refer to a valid name: %s", kind, qualifiedName) |
| 258 | } |
| 259 | if qualifiedName[0:1] == "." { |
| 260 | return nil, fmt.Errorf("qualified name must not begin with a leading '.': %s", |
| 261 | qualifiedName) |
| 262 | } |
| 263 | ind := strings.LastIndex(qualifiedName, ".") |
| 264 | if ind == len(qualifiedName)-1 || (requireQualified && ind <= 0) { |
| 265 | return nil, fmt.Errorf("%s must refer to a valid qualified name: %s", |
| 266 | kind, qualifiedName) |
| 267 | } |
| 268 | aliasRef, found := c.AliasSet()[alias] |
| 269 | if found { |
| 270 | return nil, fmt.Errorf( |
| 271 | "%s collides with existing reference: name=%s, %s=%s, existing=%s", |
| 272 | kind, qualifiedName, kind, alias, aliasRef) |
| 273 | } |
| 274 | if strings.HasPrefix(c.Name(), alias+".") || c.Name() == alias { |
| 275 | return nil, fmt.Errorf( |
| 276 | "%s collides with container name: name=%s, %s=%s, container=%s", |
| 277 | kind, qualifiedName, kind, alias, c.Name()) |
| 278 | } |
| 279 | if c == nil { |
| 280 | c = &Container{} |
| 281 | } |
| 282 | if c.aliases == nil { |
| 283 | c.aliases = make(map[string]string) |
| 284 | } |
| 285 | c.aliases[alias] = qualifiedName |
| 286 | return c, nil |
| 287 | } |
| 288 | } |
| 289 | |
| 290 | func isIdentifierChar(r rune) bool { |
| 291 | return r <= unicode.MaxASCII && (r == '.' || r == '_' || unicode.IsLetter(r) || unicode.IsNumber(r)) |