1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Yaml\Exception;
13
14/**
15 * Exception class thrown when an error occurs during parsing.
16 *
17 * @author Fabien Potencier <fabien@symfony.com>
18 */
19class ParseException extends RuntimeException
20{
21    private $parsedFile;
22    private $parsedLine;
23    private $snippet;
24    private $rawMessage;
25
26    /**
27     * @param string          $message    The error message
28     * @param int             $parsedLine The line where the error occurred
29     * @param string|null     $snippet    The snippet of code near the problem
30     * @param string|null     $parsedFile The file name where the error occurred
31     * @param \Exception|null $previous   The previous exception
32     */
33    public function __construct(string $message, int $parsedLine = -1, string $snippet = null, string $parsedFile = null, \Exception $previous = null)
34    {
35        $this->parsedFile = $parsedFile;
36        $this->parsedLine = $parsedLine;
37        $this->snippet = $snippet;
38        $this->rawMessage = $message;
39
40        $this->updateRepr();
41
42        parent::__construct($this->message, 0, $previous);
43    }
44
45    /**
46     * Gets the snippet of code near the error.
47     *
48     * @return string The snippet of code
49     */
50    public function getSnippet()
51    {
52        return $this->snippet;
53    }
54
55    /**
56     * Sets the snippet of code near the error.
57     *
58     * @param string $snippet The code snippet
59     */
60    public function setSnippet($snippet)
61    {
62        $this->snippet = $snippet;
63
64        $this->updateRepr();
65    }
66
67    /**
68     * Gets the filename where the error occurred.
69     *
70     * This method returns null if a string is parsed.
71     *
72     * @return string The filename
73     */
74    public function getParsedFile()
75    {
76        return $this->parsedFile;
77    }
78
79    /**
80     * Sets the filename where the error occurred.
81     *
82     * @param string $parsedFile The filename
83     */
84    public function setParsedFile($parsedFile)
85    {
86        $this->parsedFile = $parsedFile;
87
88        $this->updateRepr();
89    }
90
91    /**
92     * Gets the line where the error occurred.
93     *
94     * @return int The file line
95     */
96    public function getParsedLine()
97    {
98        return $this->parsedLine;
99    }
100
101    /**
102     * Sets the line where the error occurred.
103     *
104     * @param int $parsedLine The file line
105     */
106    public function setParsedLine($parsedLine)
107    {
108        $this->parsedLine = $parsedLine;
109
110        $this->updateRepr();
111    }
112
113    private function updateRepr()
114    {
115        $this->message = $this->rawMessage;
116
117        $dot = false;
118        if ('.' === substr($this->message, -1)) {
119            $this->message = substr($this->message, 0, -1);
120            $dot = true;
121        }
122
123        if (null !== $this->parsedFile) {
124            $this->message .= sprintf(' in %s', json_encode($this->parsedFile, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
125        }
126
127        if ($this->parsedLine >= 0) {
128            $this->message .= sprintf(' at line %d', $this->parsedLine);
129        }
130
131        if ($this->snippet) {
132            $this->message .= sprintf(' (near "%s")', $this->snippet);
133        }
134
135        if ($dot) {
136            $this->message .= '.';
137        }
138    }
139}
140