1<?php
2
3declare(strict_types=1);
4
5/**
6 * This file is part of phpDocumentor.
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 *
11 * @link      http://phpdoc.org
12 */
13
14namespace phpDocumentor\Reflection\DocBlock\Tags;
15
16use InvalidArgumentException;
17use phpDocumentor\Reflection\DocBlock\Description;
18use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
19use phpDocumentor\Reflection\DocBlock\StandardTagFactory;
20use phpDocumentor\Reflection\Types\Context as TypeContext;
21use Webmozart\Assert\Assert;
22use function preg_match;
23
24/**
25 * Parses a tag definition for a DocBlock.
26 */
27final class Generic extends BaseTag implements Factory\StaticMethod
28{
29    /**
30     * Parses a tag and populates the member variables.
31     *
32     * @param string      $name        Name of the tag.
33     * @param Description $description The contents of the given tag.
34     */
35    public function __construct(string $name, ?Description $description = null)
36    {
37        $this->validateTagName($name);
38
39        $this->name        = $name;
40        $this->description = $description;
41    }
42
43    /**
44     * Creates a new tag that represents any unknown tag type.
45     *
46     * @return static
47     */
48    public static function create(
49        string $body,
50        string $name = '',
51        ?DescriptionFactory $descriptionFactory = null,
52        ?TypeContext $context = null
53    ) : self {
54        Assert::stringNotEmpty($name);
55        Assert::notNull($descriptionFactory);
56
57        $description = $body !== '' ? $descriptionFactory->create($body, $context) : null;
58
59        return new static($name, $description);
60    }
61
62    /**
63     * Returns the tag as a serialized string
64     */
65    public function __toString() : string
66    {
67        if ($this->description) {
68            $description = $this->description->render();
69        } else {
70            $description = '';
71        }
72
73        return $description;
74    }
75
76    /**
77     * Validates if the tag name matches the expected format, otherwise throws an exception.
78     */
79    private function validateTagName(string $name) : void
80    {
81        if (!preg_match('/^' . StandardTagFactory::REGEX_TAGNAME . '$/u', $name)) {
82            throw new InvalidArgumentException(
83                'The tag name "' . $name . '" is not wellformed. Tags may only consist of letters, underscores, '
84                . 'hyphens and backslashes.'
85            );
86        }
87    }
88}
89