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, \Throwable $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    public function setSnippet(string $snippet)
59    {
60        $this->snippet = $snippet;
61
62        $this->updateRepr();
63    }
64
65    /**
66     * Gets the filename where the error occurred.
67     *
68     * This method returns null if a string is parsed.
69     *
70     * @return string The filename
71     */
72    public function getParsedFile()
73    {
74        return $this->parsedFile;
75    }
76
77    /**
78     * Sets the filename where the error occurred.
79     */
80    public function setParsedFile(string $parsedFile)
81    {
82        $this->parsedFile = $parsedFile;
83
84        $this->updateRepr();
85    }
86
87    /**
88     * Gets the line where the error occurred.
89     *
90     * @return int The file line
91     */
92    public function getParsedLine()
93    {
94        return $this->parsedLine;
95    }
96
97    /**
98     * Sets the line where the error occurred.
99     */
100    public function setParsedLine(int $parsedLine)
101    {
102        $this->parsedLine = $parsedLine;
103
104        $this->updateRepr();
105    }
106
107    private function updateRepr()
108    {
109        $this->message = $this->rawMessage;
110
111        $dot = false;
112        if ('.' === substr($this->message, -1)) {
113            $this->message = substr($this->message, 0, -1);
114            $dot = true;
115        }
116
117        if (null !== $this->parsedFile) {
118            $this->message .= sprintf(' in %s', json_encode($this->parsedFile, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
119        }
120
121        if ($this->parsedLine >= 0) {
122            $this->message .= sprintf(' at line %d', $this->parsedLine);
123        }
124
125        if ($this->snippet) {
126            $this->message .= sprintf(' (near "%s")', $this->snippet);
127        }
128
129        if ($dot) {
130            $this->message .= '.';
131        }
132    }
133}
134