# Path: schema_salad/sourceline.py
# class SourceLine:
#     def __init__(
#         self,
#         item: Any,
#         key: Optional[Any] = None,
#         raise_type: Callable[[str], Any] = str,
#         include_traceback: bool = False,
#     ) -> None:
#         self.item = item
#         self.key = key
#         self.raise_type = raise_type
#         self.include_traceback = include_traceback
# 
#     def __enter__(self) -> "SourceLine":
#         return self
# 
#     def __exit__(
#         self,
#         exc_type: Any,
#         exc_value: Any,
#         tb: Any,
#     ) -> None:
#         if not exc_value:
#             return
#         raise self.makeError(str(exc_value)) from exc_value
# 
#     def file(self) -> Optional[str]:
#         if hasattr(self.item, "lc") and hasattr(self.item.lc, "filename"):
#             return str(self.item.lc.filename)
#         else:
#             return None
# 
#     def start(self) -> Optional[Tuple[int, int]]:
#         if self.file() is None:
#             return None
#         elif (
#             self.key is None
#             or self.item.lc.data is None
#             or self.key not in self.item.lc.data
#         ):
#             return ((self.item.lc.line or 0) + 1, (self.item.lc.col or 0) + 1)
#         else:
#             return (
#                 (self.item.lc.data[self.key][0] or 0) + 1,
#                 (self.item.lc.data[self.key][1] or 0) + 1,
#             )
# 
#     def end(self) -> Optional[Tuple[int, int]]:
#         return None
# 
#     def makeLead(self) -> str:
#         if self.file():
#             lcol = self.start()
#             line, col = lcol if lcol else ("", "")
#             return f"{self.file()}:{line}:{col}:"
#         else:
#             return ""
# 
#     def makeError(self, msg: str) -> Any:
#         if not isinstance(self.item, ruamel.yaml.comments.CommentedBase):
#             return self.raise_type(msg)
#         errs = []
#         lead = self.makeLead()
#         for m in msg.splitlines():
#             if bool(lineno_re.match(m)):
#                 errs.append(m)
#             else:
#                 errs.append(f"{lead} {m}")
#         return self.raise_type("\n".join(errs))
# 
# def reflow_all(text: str, maxline: Optional[int] = None) -> str:
#     if maxline is None:
#         maxline = int(os.environ.get("COLUMNS", "100"))
#     maxno = 0
#     for line in text.splitlines():
#         g = lineno_re.match(line)
#         if not g:
#             continue
#         group = g.group(1)
#         assert group is not None  # nosec
#         maxno = max(maxno, len(group))
#     maxno_text = maxline - maxno
#     msg = []  # type: List[str]
#     for line in text.splitlines():
#         g = lineno_re.match(line)
#         if not g:
#             msg.append(line)
#             continue
#         pre = g.group(1)
#         assert pre is not None  # nosec
#         group2 = g.group(2)
#         assert group2 is not None  # nosec
#         reflowed = reflow(group2, maxno_text, g.group(3)).splitlines()
#         msg.extend([pre.ljust(maxno, " ") + r for r in reflowed])
#     return "\n".join(msg)
# 
# def strip_duplicated_lineno(text: str) -> str:
#     """Same as `strip_dup_lineno` but without reflow"""
#     pre = None  # type: Optional[str]
#     msg = []
#     for line in text.splitlines():
#         g = lineno_re.match(line)
#         if not g:
#             msg.append(line)
#             continue
#         elif g.group(1) != pre:
#             msg.append(line)
#             pre = g.group(1)
#         else:
#             group1 = g.group(1)
#             group2 = g.group(2)
#             assert group1 is not None  # nosec
#             assert group2 is not None  # nosec
#             msg.append(" " * len(group1) + group2)
#     return "\n".join(msg)


from typing import List, Optional, Sequence, Tuple, Union
from .sourceline import SourceLine, reflow_all, strip_duplicated_lineno
            return exc

        if children is None:
            self.children = []  # type: List["SchemaSaladException"]
        elif len(children) <= 1:
            self.children = sum((simplify(c) for c in children), [])
        else:
            self.children = sum(
                (simplify(with_bullet(c, bullet_for_children)) for c in children), []
            )

        self.with_sourceline(sl)
        self.propagate_sourceline()

    def propagate_sourceline(self) -> None:
        if self.file is None:
            return
        for c in self.children:
            if c.file is None:
                c.file = self.file
                c.start = self.start
                c.end = self.end
                c.propagate_sourceline()

    def as_warning(self) -> "SchemaSaladException":
        self.is_warning = True
        for c in self.children:
            c.as_warning()
        return self


# Path: schema_salad/sourceline.py
# class SourceLine:
#     def __init__(
#         self,
#         item: Any,
#         key: Optional[Any] = None,
#         raise_type: Callable[[str], Any] = str,
#         include_traceback: bool = False,
#     ) -> None:
#         self.item = item
#         self.key = key
#         self.raise_type = raise_type
#         self.include_traceback = include_traceback
# 
#     def __enter__(self) -> "SourceLine":
#         return self
# 
#     def __exit__(
#         self,
#         exc_type: Any,
#         exc_value: Any,
#         tb: Any,
#     ) -> None:
#         if not exc_value:
#             return
#         raise self.makeError(str(exc_value)) from exc_value
# 
#     def file(self) -> Optional[str]:
#         if hasattr(self.item, "lc") and hasattr(self.item.lc, "filename"):
#             return str(self.item.lc.filename)
#         else:
#             return None
# 
#     def start(self) -> Optional[Tuple[int, int]]:
#         if self.file() is None:
#             return None
#         elif (
#             self.key is None
#             or self.item.lc.data is None
#             or self.key not in self.item.lc.data
#         ):
#             return ((self.item.lc.line or 0) + 1, (self.item.lc.col or 0) + 1)
#         else:
#             return (
#                 (self.item.lc.data[self.key][0] or 0) + 1,
#                 (self.item.lc.data[self.key][1] or 0) + 1,
#             )
# 
#     def end(self) -> Optional[Tuple[int, int]]:
#         return None
# 
#     def makeLead(self) -> str:
#         if self.file():
#             lcol = self.start()
#             line, col = lcol if lcol else ("", "")
#             return f"{self.file()}:{line}:{col}:"
#         else:
#             return ""
# 
#     def makeError(self, msg: str) -> Any:
#         if not isinstance(self.item, ruamel.yaml.comments.CommentedBase):
#             return self.raise_type(msg)
#         errs = []
#         lead = self.makeLead()
#         for m in msg.splitlines():
#             if bool(lineno_re.match(m)):
#                 errs.append(m)
#             else:
#                 errs.append(f"{lead} {m}")
#         return self.raise_type("\n".join(errs))
# 
# def reflow_all(text: str, maxline: Optional[int] = None) -> str:
#     if maxline is None:
#         maxline = int(os.environ.get("COLUMNS", "100"))
#     maxno = 0
#     for line in text.splitlines():
#         g = lineno_re.match(line)
#         if not g:
#             continue
#         group = g.group(1)
#         assert group is not None  # nosec
#         maxno = max(maxno, len(group))
#     maxno_text = maxline - maxno
#     msg = []  # type: List[str]
#     for line in text.splitlines():
#         g = lineno_re.match(line)
#         if not g:
#             msg.append(line)
#             continue
#         pre = g.group(1)
#         assert pre is not None  # nosec
#         group2 = g.group(2)
#         assert group2 is not None  # nosec
#         reflowed = reflow(group2, maxno_text, g.group(3)).splitlines()
#         msg.extend([pre.ljust(maxno, " ") + r for r in reflowed])
#     return "\n".join(msg)
# 
# def strip_duplicated_lineno(text: str) -> str:
#     """Same as `strip_dup_lineno` but without reflow"""
#     pre = None  # type: Optional[str]
#     msg = []
#     for line in text.splitlines():
#         g = lineno_re.match(line)
#         if not g:
#             msg.append(line)
#             continue
#         elif g.group(1) != pre:
#             msg.append(line)
#             pre = g.group(1)
#         else:
#             group1 = g.group(1)
#             group2 = g.group(2)
#             assert group1 is not None  # nosec
#             assert group2 is not None  # nosec
#             msg.append(" " * len(group1) + group2)
#     return "\n".join(msg)


# Path: schema_salad/exceptions.py
from typing import List, Optional, Sequence, Tuple, Union
from .sourceline import SourceLine, reflow_all, strip_duplicated_lineno

            return exc

        if children is None:
            self.children = []  # type: List["SchemaSaladException"]
        elif len(children) <= 1:
            self.children = sum((simplify(c) for c in children), [])
        else:
            self.children = sum(
                (simplify(with_bullet(c, bullet_for_children)) for c in children), []
            )

        self.with_sourceline(sl)
        self.propagate_sourceline()

    def propagate_sourceline(self) -> None:
        if self.file is None:
            return
        for c in self.children:
            if c.file is None:
                c.file = self.file
                c.start = self.start
                c.end = self.end
                c.propagate_sourceline()

    def as_warning(self) -> "SchemaSaladException":
        self.is_warning = True
        for c in self.children:
            c.as_warning()
        return self


    def with_sourceline(self, sl: Optional[SourceLine]) -> "SchemaSaladException":