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