Parse the entire input and return a Schema.
(self)
| 204 | return ParseError(message, token.line, token.column) |
| 205 | |
| 206 | def parse(self) -> Schema: |
| 207 | """Parse the entire input and return a Schema.""" |
| 208 | package = None |
| 209 | package_alias = None |
| 210 | imports = [] |
| 211 | enums = [] |
| 212 | messages = [] |
| 213 | unions = [] |
| 214 | services = [] |
| 215 | options = {} |
| 216 | |
| 217 | while not self.at_end(): |
| 218 | if self.check(TokenType.PACKAGE): |
| 219 | if package is not None: |
| 220 | raise self.error("Duplicate package declaration") |
| 221 | package, package_alias = self.parse_package() |
| 222 | elif self.check(TokenType.IMPORT): |
| 223 | imports.append(self.parse_import()) |
| 224 | elif self.check(TokenType.OPTION): |
| 225 | # File-level option |
| 226 | name, value = self.parse_file_option() |
| 227 | options[name] = value |
| 228 | elif self.check(TokenType.ENUM): |
| 229 | enums.append(self.parse_enum()) |
| 230 | elif self.check(TokenType.UNION): |
| 231 | unions.append(self.parse_union()) |
| 232 | elif self.check(TokenType.MESSAGE): |
| 233 | messages.append(self.parse_message()) |
| 234 | elif self.check(TokenType.SERVICE): |
| 235 | services.append(self.parse_service()) |
| 236 | else: |
| 237 | raise self.error(f"Unexpected token: {self.current().value}") |
| 238 | |
| 239 | return Schema( |
| 240 | package=package, |
| 241 | package_alias=package_alias, |
| 242 | imports=imports, |
| 243 | enums=enums, |
| 244 | messages=messages, |
| 245 | unions=unions, |
| 246 | services=services, |
| 247 | options=options, |
| 248 | source_file=self.filename, |
| 249 | source_format=self.source_format, |
| 250 | ) |
| 251 | |
| 252 | def make_location(self, token: Token) -> SourceLocation: |
| 253 | """Create a source location from a token.""" |