Repository: asyncapi/parser-js
Pull request #814 (2023-07-24 21:19:41)

feat: add support for multi-format schema
**Description**
This PR adds the required changes for supporting [Multi-format schemas](https://github.com/asyncapi/spec/issues/622).
The API changes are in this`parser-api` PR https://github.com/asyncapi/parser-api/pull/86 waiting to be reviewed.

Replaces https://github.com/asyncapi/parser-js/pull/785

**Related issue(s)**
https://github.com/asyncapi/spec/issues/622

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=814)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=814)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=814)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=814)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=814)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814&metric=duplicated_lines_density&view=list) No Duplication information


smoya: @magicmatatjahu @jonaslagoni this is now ready for review again 🙏 
sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=814)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=814)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=814)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=814)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=814&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=814&metric=duplicated_lines_density&view=list) No Duplication information


jonaslagoni: Merging, if you have anything @magicmatatjahu it can be addressed afterwards 🙂 

Patch:
diff --git a/src/models/message-trait.ts b/src/models/message-trait.ts
index b140fdf..8abb1f1 100644
--- a/src/models/message-trait.ts
+++ b/src/models/message-trait.ts
@@ -6,7 +6,8 @@ import type { SchemaInterface } from './schema';
 
 export interface MessageTraitInterface extends BaseModel, BindingsMixinInterface, DescriptionMixinInterface, ExtensionsMixinInterface, ExternalDocumentationMixinInterface, TagsMixinInterface {
   id(): string;
-  schemaFormat(): string;
+  hasSchemaFormat(): boolean;
+  schemaFormat(): string | undefined;
   hasMessageId(): boolean;
   messageId(): string | undefined;
   hasCorrelationId(): boolean;
diff --git a/src/models/schema.ts b/src/models/schema.ts
index dbcebe4..bc1f5d4 100644
--- a/src/models/schema.ts
+++ b/src/models/schema.ts
@@ -49,6 +49,7 @@ export interface SchemaInterface extends BaseModel<v2.AsyncAPISchemaObject>, Ext
   propertyNames(): SchemaInterface | undefined;
   readOnly(): boolean | undefined;
   required(): Array<string> | undefined;
+  schemaFormat(): string
   then(): SchemaInterface | undefined;
   title(): string | undefined;
   type(): string | Array<string> | undefined;
diff --git a/src/models/v2/message-trait.ts b/src/models/v2/message-trait.ts
index 299b785..cee1166 100644
--- a/src/models/v2/message-trait.ts
+++ b/src/models/v2/message-trait.ts
@@ -5,8 +5,8 @@ import { MessageExample } from './message-example';
 import { Schema } from './schema';
 
 import { xParserMessageName } from '../../constants';
-import { getDefaultSchemaFormat } from '../../schema-parser';
 import { bindings, hasDescription, description, extensions, hasExternalDocs, externalDocs, tags } from './mixins';
+import { getDefaultSchemaFormat } from '../../schema-parser';
 
 import type { BindingsInterface } from '../bindings';
 import type { CorrelationIdInterface } from '../correlation-id';
@@ -24,7 +24,11 @@ export class MessageTrait<J extends v2.MessageTraitObject = v2.MessageTraitObjec
     return this.messageId() || this._meta.id || this.json(xParserMessageName) as string;
   }
 
-  schemaFormat(): string {
+  hasSchemaFormat(): boolean {
+    return this.schemaFormat() !== undefined;
+  }
+
+  schemaFormat(): string | undefined {
     return this._json.schemaFormat || getDefaultSchemaFormat(this._meta.asyncapi.semver.version);
   }
 
diff --git a/src/models/v2/message.ts b/src/models/v2/message.ts
index ad87eeb..5908d29 100644
--- a/src/models/v2/message.ts
+++ b/src/models/v2/message.ts
@@ -27,7 +27,7 @@ export class Message extends MessageTrait<v2.MessageObject> implements MessageIn
   
   payload(): SchemaInterface | undefined {
     if (!this._json.payload) return undefined;
-    return this.createModel(Schema, this._json.payload, { pointer: `${this._meta.pointer}/payload` });
+    return this.createModel(Schema, this._json.payload, { pointer: `${this._meta.pointer}/payload`, schemaFormat: this._json.schemaFormat });
   }
 
   servers(): ServersInterface {
diff --git a/src/models/v2/schema.ts b/src/models/v2/schema.ts
index 20ae875..9f2df86 100644
--- a/src/models/v2/schema.ts
+++ b/src/models/v2/schema.ts
@@ -2,6 +2,7 @@ import { BaseModel } from '../base';
 
 import { xParserSchemaId } from '../../constants';
 import { extensions, hasExternalDocs, externalDocs } from './mixins';
+import { getDefaultSchemaFormat } from '../../schema-parser';
 
 import type { ExtensionsInterface } from '../extensions';
 import type { ExternalDocumentationInterface } from '../external-docs';
@@ -9,7 +10,7 @@ import type { SchemaInterface } from '../schema';
 
 import type { v2 } from '../../spec-types';
 
-export class Schema extends BaseModel<v2.AsyncAPISchemaObject, { id?: string, parent?: Schema }> implements SchemaInterface {
+export class Schema extends BaseModel<v2.AsyncAPISchemaObject, { id?: string, parent?: Schema, schemaFormat?: string }> implements SchemaInterface {
   id(): string {
     return this.$id() || this._meta.id || this.json(xParserSchemaId as any) as string;
   }
@@ -267,6 +268,10 @@ export class Schema extends BaseModel<v2.AsyncAPISchemaObject, { id?: string, pa
     return this._json.required;
   }
 
+  schemaFormat(): string {
+    return this._meta.schemaFormat || getDefaultSchemaFormat(this._meta.asyncapi.semver.version);
+  }
+
   then(): SchemaInterface | undefined {
     if (typeof this._json === 'boolean' || typeof this._json.then !== 'object') return;
     return this.createModel(Schema, this._json.then, { pointer: `${this._meta.pointer}/then`, parent: this });
diff --git a/src/models/v3/message-trait.ts b/src/models/v3/message-trait.ts
index d4ea244..ccbd8ca 100644
--- a/src/models/v3/message-trait.ts
+++ b/src/models/v3/message-trait.ts
@@ -4,7 +4,6 @@ import { MessageExample } from './message-example';
 import { Schema } from './schema';
 
 import { xParserMessageName } from '../../constants';
-import { getDefaultSchemaFormat } from '../../schema-parser';
 import { CoreModel } from './mixins';
 
 import type { CorrelationIdInterface } from '../correlation-id';
@@ -19,14 +18,18 @@ export class MessageTrait<J extends v3.MessageTraitObject = v3.MessageTraitObjec
     return this.messageId() || this._meta.id || this.extensions().get(xParserMessageName)?.value<string>() as string;
   }
 
-  schemaFormat(): string {
-    return this._json.schemaFormat || getDefaultSchemaFormat(this._meta.asyncapi.semver.version);
-  }
-
   hasMessageId(): boolean {
     return !!this._json.messageId;
   }
 
+  hasSchemaFormat(): boolean {
+    return false;
+  }
+
+  schemaFormat(): string | undefined {
+    return undefined;
+  }
+
   messageId(): string | undefined {
     return this._json.messageId;
   }
diff --git a/src/models/v3/message.ts b/src/models/v3/message.ts
index 07fc5bf..ce05a9e 100644
--- a/src/models/v3/message.ts
+++ b/src/models/v3/message.ts
@@ -25,7 +25,20 @@ export class Message extends MessageTrait<v3.MessageObject> implements MessageIn
   
   payload(): SchemaInterface | undefined {
     if (!this._json.payload) return undefined;
-    return this.createModel(Schema, this._json.payload, { pointer: this.jsonPath('payload') });
+    return this.createModel(Schema, this._json.payload, { pointer: this.jsonPath('payload')});
+  }
+
+  hasSchemaFormat(): boolean {
+    // If it has a payload, schema format is expected (at least the default)
+    return this.hasPayload();
+  }
+  
+  schemaFormat(): string | undefined {
+    if (this.hasSchemaFormat()) {
+      return this.payload()?.schemaFormat();
+    }
+
+    return undefined;
   }
 
   servers(): ServersInterface {
diff --git a/src/models/v3/schema.ts b/src/models/v3/schema.ts
index 889f254..763c91a 100644
--- a/src/models/v3/schema.ts
+++ b/src/models/v3/schema.ts
@@ -1,304 +1,318 @@
-import { BaseModel } from '../base';
+import { BaseModel, ModelMetadata } from '../base';
 
 import { xParserSchemaId } from '../../constants';
 import { extensions, hasExternalDocs, externalDocs } from './mixins';
-import { retrievePossibleRef, hasRef } from '../../utils';
+import { getDefaultSchemaFormat } from '../../schema-parser';
+import { AsyncAPISchemaObject } from 'spec-types/v3';
 
-import type { ModelMetadata } from '../base';
 import type { ExtensionsInterface } from '../extensions';
 import type { ExternalDocumentationInterface } from '../external-docs';
 import type { SchemaInterface } from '../schema';
 
 import type { v3 } from '../../spec-types';
 
-export class Schema extends BaseModel<v3.AsyncAPISchemaObject, { id?: string, parent?: Schema }> implements SchemaInterface {
+export class Schema extends BaseModel<v3.MultiFormatSchemaObject, { id?: string, parent?: Schema }> implements SchemaInterface {
+  private _schemaFormat: string;
+  private _schemaObject: AsyncAPISchemaObject;
+
+  // The following constructor is needed because, starting from AsyncAPI v3, schemas can be multi-format as well.
   constructor(
-    _json: v3.AsyncAPISchemaObject,
-    _meta: ModelMetadata & { id?: string, parent?: Schema } = {} as any,
+    protected readonly _json: v3.MultiFormatSchemaObject,
+    protected readonly _meta: ModelMetadata & { id?: string, parent?: Schema } = {} as ModelMetadata & { id?: string, parent?: Schema },
   ) {
-    _json = retrievePossibleRef(_json, _meta.pointer as string, _meta.asyncapi?.parsed);
     super(_json, _meta);
+    
+    // Based on the shape of the JSON, we grab the data for the Schema from the root (Schema) or rather from `schema` field (MultiFormatSchema).
+    if (typeof _json === 'object' && typeof _json.schema === 'object') {
+      this._schemaObject = _json.schema;
+      this._schemaFormat = _json.schemaFormat;
+    } else {
+      this._schemaObject = _json;
+      this._schemaFormat = getDefaultSchemaFormat(_meta.asyncapi?.semver?.version);
+    }
   }
-
   id(): string {
-    return this.$id() || this._meta.id || this.json(xParserSchemaId as any) as string;
+    return this.$id() || this._meta.id || (this._schemaObject as any)[xParserSchemaId] as string;
   }
 
   $comment(): string | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.$comment;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.$comment;
   }
 
   $id(): string | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.$id;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.$id;
   }
 
   $schema(): string {
-    if (typeof this._json === 'boolean') return 'http://json-schema.org/draft-07/schema#';
-    return this._json.$schema || 'http://json-schema.org/draft-07/schema#';
+    if (typeof this._schemaObject === 'boolean') return 'http://json-schema.org/draft-07/schema#';
+    return this._schemaObject.$schema || 'http://json-schema.org/draft-07/schema#';
   }
 
   additionalItems(): boolean | SchemaInterface {
-    if (typeof this._json === 'boolean') return this._json;
-    if (this._json.additionalItems === undefined) return true;
-    if (typeof this._json.additionalItems === 'boolean') return this._json.additionalItems;
-    return this.createModel(Schema, this._json.additionalItems, { pointer: `${this._meta.pointer}/additionalItems`, parent: this });
+    if (typeof this._schemaObject === 'boolean') return this._schemaObject;
+    if (this._schemaObject.additionalItems === undefined) return true;
+    if (typeof this._schemaObject.additionalItems === 'boolean') return this._schemaObject.additionalItems;
+    return this.createModel(Schema, this._schemaObject.additionalItems, { pointer: `${this._meta.pointer}/additionalItems`, parent: this });
   }
 
   additionalProperties(): boolean | SchemaInterface {
-    if (typeof this._json === 'boolean') return this._json;
-    if (this._json.additionalProperties === undefined) return true;
-    if (typeof this._json.additionalProperties === 'boolean') return this._json.additionalProperties;
-    return this.createModel(Schema, this._json.additionalProperties, { pointer: `${this._meta.pointer}/additionalProperties`, parent: this });
+    if (typeof this._schemaObject === 'boolean') return this._schemaObject;
+    if (this._schemaObject.additionalProperties === undefined) return true;
+    if (typeof this._schemaObject.additionalProperties === 'boolean') return this._schemaObject.additionalProperties;
+    return this.createModel(Schema, this._schemaObject.additionalProperties, { pointer: `${this._meta.pointer}/additionalProperties`, parent: this });
   }
 
   allOf(): Array<SchemaInterface> | undefined {
-    if (typeof this._json === 'boolean') return;
-    if (!Array.isArray(this._json.allOf)) return undefined;
-    return this._json.allOf.map((s, index) => this.createModel(Schema, s, { pointer: `${this._meta.pointer}/allOf/${index}`, parent: this }));
+    if (typeof this._schemaObject === 'boolean') return;
+    if (!Array.isArray(this._schemaObject.allOf)) return undefined;
+    return this._schemaObject.allOf.map((s, index) => this.createModel(Schema, s, { pointer: `${this._meta.pointer}/allOf/${index}`, parent: this }));
   }
 
   anyOf(): Array<SchemaInterface> | undefined {
-    if (typeof this._json === 'boolean') return;
-    if (!Array.isArray(this._json.anyOf)) return undefined;
-    return this._json.anyOf.map((s, index) => this.createModel(Schema, s, { pointer: `${this._meta.pointer}/anyOf/${index}`, parent: this }));
+    if (typeof this._schemaObject === 'boolean') return;
+    if (!Array.isArray(this._schemaObject.anyOf)) return undefined;
+    return this._schemaObject.anyOf.map((s, index) => this.createModel(Schema, s, { pointer: `${this._meta.pointer}/anyOf/${index}`, parent: this }));
   }
 
   const(): any {
-    if (typeof this._json === 'boolean') return;
-    return this._json.const;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.const;
   }
 
   contains(): SchemaInterface | undefined {
-    if (typeof this._json === 'boolean' || typeof this._json.contains !== 'object') return;
-    return this.createModel(Schema, this._json.contains, { pointer: `${this._meta.pointer}/contains`, parent: this });
+    if (typeof this._schemaObject === 'boolean' || typeof this._schemaObject.contains !== 'object') return;
+    return this.createModel(Schema, this._schemaObject.contains, { pointer: `${this._meta.pointer}/contains`, parent: this });
   }
 
   contentEncoding(): string | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.contentEncoding;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.contentEncoding;
   }
 
   contentMediaType(): string | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.contentMediaType;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.contentMediaType;
   }
 
   default(): any {
-    if (typeof this._json === 'boolean') return;
-    return this._json.default;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.default;
   }
 
   definitions(): Record<string, SchemaInterface> | undefined {
-    if (typeof this._json === 'boolean' || typeof this._json.definitions !== 'object') return;
-    return Object.entries(this._json.definitions).reduce((acc: Record<string, SchemaInterface>, [key, s]: [string, any]) => {
+    if (typeof this._schemaObject === 'boolean' || typeof this._schemaObject.definitions !== 'object') return;
+    return Object.entries(this._schemaObject.definitions).reduce((acc: Record<string, SchemaInterface>, [key, s]: [string, any]) => {
       acc[key] = this.createModel(Schema, s, { pointer: `${this._meta.pointer}/definitions/${key}`, parent: this });
       return acc;
     }, {});
   }
 
   description(): string | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.description;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.description;
   }
 
   dependencies(): Record<string, SchemaInterface | Array<string>> | undefined {
-    if (typeof this._json === 'boolean') return;
-    if (typeof this._json.dependencies !== 'object') return undefined;
-    return Object.entries(this._json.dependencies).reduce((acc: Record<string, SchemaInterface | Array<string>>, [key, s]: [string, any]) => {
+    if (typeof this._schemaObject === 'boolean') return;
+    if (typeof this._schemaObject.dependencies !== 'object') return undefined;
+    return Object.entries(this._schemaObject.dependencies).reduce((acc: Record<string, SchemaInterface | Array<string>>, [key, s]: [string, any]) => {
       acc[key] = Array.isArray(s) ? s : this.createModel(Schema, s, { pointer: `${this._meta.pointer}/dependencies/${key}`, parent: this });
       return acc;
     }, {});
   }
 
   deprecated(): boolean {
-    if (typeof this._json === 'boolean') return false;
-    return this._json.deprecated || false;
+    if (typeof this._schemaObject === 'boolean') return false;
+    return this._schemaObject.deprecated || false;
   }
 
   discriminator(): string | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.discriminator;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.discriminator;
   }
 
   else(): SchemaInterface | undefined {
-    if (typeof this._json === 'boolean' || typeof this._json.else !== 'object') return;
-    return this.createModel(Schema, this._json.else, { pointer: `${this._meta.pointer}/else`, parent: this });
+    if (typeof this._schemaObject === 'boolean' || typeof this._schemaObject.else !== 'object') return;
+    return this.createModel(Schema, this._schemaObject.else, { pointer: `${this._meta.pointer}/else`, parent: this });
   }
 
   enum(): Array<any> | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.enum;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.enum;
   }
 
   examples(): Array<any> | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.examples;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.examples;
   }
 
   exclusiveMaximum(): number | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.exclusiveMaximum;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.exclusiveMaximum;
   }
 
   exclusiveMinimum(): number | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.exclusiveMinimum;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.exclusiveMinimum;
   }
 
   format(): string | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.format;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.format;
   }
 
   isBooleanSchema(): boolean {
-    return typeof this._json === 'boolean';
+    return typeof this._schemaObject === 'boolean';
   }
 
   if(): SchemaInterface | undefined {
-    if (typeof this._json === 'boolean' || typeof this._json.if !== 'object') return;
-    return this.createModel(Schema, this._json.if, { pointer: `${this._meta.pointer}/if`, parent: this });
+    if (typeof this._schemaObject === 'boolean' || typeof this._schemaObject.if !== 'object') return;
+    return this.createModel(Schema, this._schemaObject.if, { pointer: `${this._meta.pointer}/if`, parent: this });
   }
 
   isCircular(): boolean {
-    if (hasRef(this._json)) return true;
     let parent = this._meta.parent;
     while (parent) {
-      if (parent._json === this._json) return true;
+      if (parent._json === this._schemaObject) return true;
       parent = parent._meta.parent;
     }
     return false;
   }
 
   items(): SchemaInterface | Array<SchemaInterface> | undefined {
-    if (typeof this._json === 'boolean' || typeof this._json.items !== 'object') return;
-    if (Array.isArray(this._json.items)) {
-      return this._json.items.map((s, index) => this.createModel(Schema, s, { pointer: `${this._meta.pointer}/items/${index}`, parent: this }));
+    if (typeof this._schemaObject === 'boolean' || typeof this._schemaObject.items !== 'object') return;
+    if (Array.isArray(this._schemaObject.items)) {
+      return this._schemaObject.items.map((s, index) => this.createModel(Schema, s, { pointer: `${this._meta.pointer}/items/${index}`, parent: this }));
     }
-    return this.createModel(Schema, this._json.items, { pointer: `${this._meta.pointer}/items`, parent: this });
+    return this.createModel(Schema, this._schemaObject.items, { pointer: `${this._meta.pointer}/items`, parent: this });
   }
 
   maximum(): number | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.maximum;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.maximum;
   }
 
   maxItems(): number | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.maxItems;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.maxItems;
   }
 
   maxLength(): number | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.maxLength;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.maxLength;
   }
 
   maxProperties(): number | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.maxProperties;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.maxProperties;
   }
 
   minimum(): number | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.minimum;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.minimum;
   }
 
   minItems(): number | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.minItems;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.minItems;
   }
 
   minLength(): number | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.minLength;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.minLength;
   }
 
   minProperties(): number | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.minProperties;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.minProperties;
   }
 
   multipleOf(): number | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.multipleOf;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.multipleOf;
   }
 
   not(): SchemaInterface | undefined {
-    if (typeof this._json === 'boolean' || typeof this._json.not !== 'object') return;
-    return this.createModel(Schema, this._json.not, { pointer: `${this._meta.pointer}/not`, parent: this });
+    if (typeof this._schemaObject === 'boolean' || typeof this._schemaObject.not !== 'object') return;
+    return this.createModel(Schema, this._schemaObject.not, { pointer: `${this._meta.pointer}/not`, parent: this });
   }
 
   oneOf(): Array<SchemaInterface> | undefined {
-    if (typeof this._json === 'boolean') return;
-    if (!Array.isArray(this._json.oneOf)) return undefined;
-    return this._json.oneOf.map((s, index) => this.createModel(Schema, s, { pointer: `${this._meta.pointer}/oneOf/${index}`, parent: this }));
+    if (typeof this._schemaObject === 'boolean') return;
+    if (!Array.isArray(this._schemaObject.oneOf)) return undefined;
+    return this._schemaObject.oneOf.map((s, index) => this.createModel(Schema, s, { pointer: `${this._meta.pointer}/oneOf/${index}`, parent: this }));
   }
 
   pattern(): string | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.pattern;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.pattern;
   }
 
   patternProperties(): Record<string, SchemaInterface> | undefined {
-    if (typeof this._json === 'boolean' || typeof this._json.patternProperties !== 'object') return;
-    return Object.entries(this._json.patternProperties).reduce((acc: Record<string, SchemaInterface>, [key, s]: [string, any]) => {
+    if (typeof this._schemaObject === 'boolean' || typeof this._schemaObject.patternProperties !== 'object') return;
+    return Object.entries(this._schemaObject.patternProperties).reduce((acc: Record<string, SchemaInterface>, [key, s]: [string, any]) => {
       acc[key] = this.createModel(Schema, s, { pointer: `${this._meta.pointer}/patternProperties/${key}`, parent: this });
       return acc;
     }, {});
   }
 
   properties(): Record<string, SchemaInterface> | undefined {
-    if (typeof this._json === 'boolean' || typeof this._json.properties !== 'object') return;
-    return Object.entries(this._json.properties).reduce((acc: Record<string, SchemaInterface>, [key, s]: [string, any]) => {
+    if (typeof this._schemaObject === 'boolean' || typeof this._schemaObject.properties !== 'object') return;
+    return Object.entries(this._schemaObject.properties).reduce((acc: Record<string, SchemaInterface>, [key, s]: [string, any]) => {
       acc[key] = this.createModel(Schema, s, { pointer: `${this._meta.pointer}/properties/${key}`, parent: this });
       return acc;
     }, {});
   }
 
   property(name: string): SchemaInterface | undefined {
-    if (typeof this._json === 'boolean' || typeof this._json.properties !== 'object' || typeof this._json.properties[name] !== 'object') return;
-    return this.createModel(Schema, this._json.properties[name], { pointer: `${this._meta.pointer}/properties/${name}`, parent: this });
+    if (typeof this._schemaObject === 'boolean' || typeof this._schemaObject.properties !== 'object' || typeof this._schemaObject.properties[name] !== 'object') return;
+    return this.createModel(Schema, this._schemaObject.properties[name], { pointer: `${this._meta.pointer}/properties/${name}`, parent: this });
   }
 
   propertyNames(): SchemaInterface | undefined {
-    if (typeof this._json === 'boolean' || typeof this._json.propertyNames !== 'object') return;
-    return this.createModel(Schema, this._json.propertyNames, { pointer: `${this._meta.pointer}/propertyNames`, parent: this });
+    if (typeof this._schemaObject === 'boolean' || typeof this._schemaObject.propertyNames !== 'object') return;
+    return this.createModel(Schema, this._schemaObject.propertyNames, { pointer: `${this._meta.pointer}/propertyNames`, parent: this });
   }
 
   readOnly(): boolean | undefined {
-    if (typeof this._json === 'boolean') return false;
-    return this._json.readOnly || false;
+    if (typeof this._schemaObject === 'boolean') return false;
+    return this._schemaObject.readOnly || false;
   }
 
   required(): Array<string> | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.required;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.required;
+  }
+
+  schemaFormat(): string {
+    return this._schemaFormat;
   }
 
   then(): SchemaInterface | undefined {
-    if (typeof this._json === 'boolean' || typeof this._json.then !== 'object') return;
-    return this.createModel(Schema, this._json.then, { pointer: `${this._meta.pointer}/then`, parent: this });
+    if (typeof this._schemaObject === 'boolean' || typeof this._schemaObject.then !== 'object') return;
+    return this.createModel(Schema, this._schemaObject.then, { pointer: `${this._meta.pointer}/then`, parent: this });
   }
 
   title(): string | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.title;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.title;
   }
 
   type(): string | Array<string> | undefined {
-    if (typeof this._json === 'boolean') return;
-    return this._json.type;
+    if (typeof this._schemaObject === 'boolean') return;
+    return this._schemaObject.type;
   }
 
   uniqueItems(): boolean | undefined {
-    if (typeof this._json === 'boolean') return false;
-    return this._json.uniqueItems || false;
+    if (typeof this._schemaObject === 'boolean') return false;
+    return this._schemaObject.uniqueItems || false;
   }
 
   writeOnly(): boolean | undefined {
-    if (typeof this._json === 'boolean') return false;
-    return this._json.writeOnly || false;
+    if (typeof this._schemaObject === 'boolean') return false;
+    return this._schemaObject.writeOnly || false;
   }
 
   hasExternalDocs(): boolean {
diff --git a/src/spec-types/v3.ts b/src/spec-types/v3.ts
index 08a3377..e0fc849 100644
--- a/src/spec-types/v3.ts
+++ b/src/spec-types/v3.ts
@@ -402,8 +402,9 @@ export interface OAuthFlowObjectAuthorizationCode extends OAuthFlowObjectBase, S
 }
 
 export type SchemaObject = AsyncAPISchemaObject | ReferenceObject;
-
 export type AsyncAPISchemaObject = AsyncAPISchemaDefinition | boolean;
+export type MultiFormatSchemaObject = AsyncAPISchemaObject | { schema: AsyncAPISchemaObject, schemaFormat: string | undefined }
+
 export interface AsyncAPISchemaDefinition extends SpecificationExtensions {
   $id?: string;
   $schema?: JSONSchema7Version;
diff --git a/src/utils.ts b/src/utils.ts
index cc394c3..0690d02 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -144,21 +144,6 @@ export function findSubArrayIndex(arr: Array<any>, subarr: Array<any>, fromIndex
   return -1;
 }
 
-export function retrievePossibleRef(data: any, pathOfData: string, spec: any = {}): any {
-  if (!hasRef(data)) {
-    return data;
-  }
-
-  const refPath = serializePath(data.$ref);
-  if (pathOfData.startsWith(refPath)) { // starts by given path
-    return retrieveDeepData(spec, splitPath(refPath)) || data;
-  } else if (pathOfData.includes(refPath)) { // circular path in substring of path
-    const substringPath = pathOfData.split(refPath)[0];
-    return retrieveDeepData(spec, splitPath(`${substringPath}${refPath}`)) || data;
-  }
-  return data;
-}
-
 export function resolveServerUrl(url: string): { host: string, pathname: string | undefined } {
   // eslint-disable-next-line prefer-const
   let [maybeProtocol, maybeHost] = url.split('://');


Test patch:
diff --git a/test/models/v2/message.spec.ts b/test/models/v2/message.spec.ts
index 1110314..ab445a8 100644
--- a/test/models/v2/message.spec.ts
+++ b/test/models/v2/message.spec.ts
@@ -26,16 +26,18 @@ describe('Message model', function() {
     });
   });
 
-  describe('.schemaFormat()', function() {
+  describe('.schemaFormat() + .hasSchemaFormat()', function() {
     it('should return defined schemaFormat', function() {
       const doc = { schemaFormat: 'customSchemaFormat' };
       const d = new Message(doc, { asyncapi: {} as any, pointer: '', id: 'message' });
+      expect(d.hasSchemaFormat()).toBeTruthy();
       expect(d.schemaFormat()).toEqual('customSchemaFormat');
     });
 
     it('should return default schemaFormat if schemaFormat field is absent', function() {
       const doc = {};
       const d = new Message(doc, { asyncapi: { semver: { version: '2.0.0' } } as any, pointer: '', id: 'message' });
+      expect(d.hasSchemaFormat()).toBeTruthy();
       expect(d.schemaFormat()).toEqual('application/vnd.aai.asyncapi;version=2.0.0');
     });
   });
diff --git a/test/models/v2/schema.spec.ts b/test/models/v2/schema.spec.ts
index 4e48b33..391305b 100644
--- a/test/models/v2/schema.spec.ts
+++ b/test/models/v2/schema.spec.ts
@@ -3,6 +3,8 @@ import { Schema } from '../../../src/models/v2/schema';
 import { assertExtensions, assertExternalDocumentation } from './utils';
 import { xParserSchemaId } from '../../../src/constants';
 
+import { getDefaultSchemaFormat } from '../../../src/schema-parser';
+
 import type { v2 } from '../../../src/spec-types';
 
 describe('Channel model', function() {
@@ -751,6 +753,20 @@ describe('Channel model', function() {
     });
   });
 
+  describe('.schemaFormat()', function() {
+    it('should return the format of the schema', function() {
+      const actualSchemaFormat = 'application/vnd.apache.avro;version=1.9.0';
+      const d = new Schema({}, {asyncapi: {} as any, pointer: '', schemaFormat: actualSchemaFormat});
+      expect(d.schemaFormat()).toEqual(actualSchemaFormat);
+    });
+
+    it('should return the default schema format where there is no value', function() {
+      const doc = {asyncapi: '2.6.0' };
+      const d = new Schema(doc, {asyncapi: { semver: { version: doc.asyncapi } }});
+      expect(d.schemaFormat()).toEqual(getDefaultSchemaFormat(doc.asyncapi));
+    });
+  });
+
   describe('.then()', function() {
     it('should return value', function() {
       const doc = { then: {} };
diff --git a/test/models/v3/message-trait.spec.ts b/test/models/v3/message-trait.spec.ts
index 43dce32..ad046af 100644
--- a/test/models/v3/message-trait.spec.ts
+++ b/test/models/v3/message-trait.spec.ts
@@ -22,16 +22,18 @@ describe('MessageTrait model', function() {
   });
 
   describe('.schemaFormat()', function() {
-    it('should return defined schemaFormat', function() {
+    it('should return always undefined', function() {
       const doc = { schemaFormat: 'customSchemaFormat' };
       const d = new MessageTrait(doc, { asyncapi: {} as any, pointer: '', id: 'message' });
-      expect(d.schemaFormat()).toEqual('customSchemaFormat');
+      expect(d.schemaFormat()).toBeUndefined();
     });
+  });
 
-    it('should return default schemaFormat if schemaFormat field is absent', function() {
-      const doc = {};
-      const d = new MessageTrait(doc, { asyncapi: { semver: { version: '2.0.0' } } as any, pointer: '', id: 'message' });
-      expect(d.schemaFormat()).toEqual('application/vnd.aai.asyncapi;version=2.0.0');
+  describe('.hasSchemaFormat()', function() {
+    it('should return always false', function() {
+      const doc = { schemaFormat: 'customSchemaFormat' };
+      const d = new MessageTrait(doc, { asyncapi: {} as any, pointer: '', id: 'message' });
+      expect(d.hasSchemaFormat()).toBeFalsy();
     });
   });
 
diff --git a/test/models/v3/message.spec.ts b/test/models/v3/message.spec.ts
index 2359495..91432f3 100644
--- a/test/models/v3/message.spec.ts
+++ b/test/models/v3/message.spec.ts
@@ -1,13 +1,7 @@
-import { Channels } from '../../../src/models/v3/channels';
-import { Channel } from '../../../src/models/v3/channel';
 import { Message } from '../../../src/models/v3/message';
 import { MessageTraits } from '../../../src/models/v3/message-traits';
 import { MessageTrait } from '../../../src/models/v3/message-trait';
-import { Operations } from '../../../src/models/v3/operations';
-import { Operation } from '../../../src/models/v3/operation';
 import { Schema } from '../../../src/models/v3/schema';
-import { Servers } from '../../../src/models/v3/servers';
-import { Server } from '../../../src/models/v3/server';
 
 import { assertCoreModel } from './utils';
 
@@ -26,18 +20,27 @@ describe('Message model', function() {
     });
   });
 
-  describe('.schemaFormat()', function() {
-    it('should return defined schemaFormat', function() {
-      const doc = { schemaFormat: 'customSchemaFormat' };
+  describe('.schemaFormat() + .hasSchemaFormat()', function() {
+    it('should return defined schemaFormat, and true for hasSchemaFormat()', function() {
+      const doc = { payload: {schemaFormat: 'customSchemaFormat', schema: {} }};
       const d = new Message(doc, { asyncapi: {} as any, pointer: '', id: 'message' });
+      expect(d.hasSchemaFormat()).toBeTruthy();
       expect(d.schemaFormat()).toEqual('customSchemaFormat');
     });
 
     it('should return default schemaFormat if schemaFormat field is absent', function() {
-      const doc = {};
+      const doc = {payload: {}};
       const d = new Message(doc, { asyncapi: { semver: { version: '2.0.0' } } as any, pointer: '', id: 'message' });
+      expect(d.hasSchemaFormat()).toBeTruthy();
       expect(d.schemaFormat()).toEqual('application/vnd.aai.asyncapi;version=2.0.0');
     });
+
+    it('should return undefined schemaFormat, and false for hasSchemaFormat() if there is no payload', function() {
+      const doc = {};
+      const d = new Message(doc, { asyncapi: { semver: { version: '2.0.0' } } as any, pointer: '', id: 'message' });
+      expect(d.hasSchemaFormat()).toBeFalsy();
+      expect(d.schemaFormat()).toBeUndefined();
+    });
   });
 
   describe('.hasPayload()', function() {
diff --git a/test/models/v3/schema.spec.ts b/test/models/v3/schema.spec.ts
index 59a2405..f491ea5 100644
--- a/test/models/v3/schema.spec.ts
+++ b/test/models/v3/schema.spec.ts
@@ -2,6 +2,7 @@ import { Schema } from '../../../src/models/v3/schema';
 
 import { assertExtensions, assertExternalDocumentation } from './utils';
 import { xParserSchemaId } from '../../../src/constants';
+import { getDefaultSchemaFormat } from '../../../src/schema-parser';
 
 import type { v3 } from '../../../src/spec-types';
 
@@ -732,6 +733,29 @@ describe('Schema model', function() {
     });
   });
 
+  describe('.schemaFormat()', function() {
+    it('should return the format of the schema', function() {
+      const actualSchemaFormat = 'application/vnd.apache.avro;version=1.9.0';
+      const doc = {schemaFormat: actualSchemaFormat, schema: {}};
+      
+      const d = new Schema(doc, {asyncapi: {} as any, pointer: '', });
+      expect(d.schemaFormat()).toEqual(actualSchemaFormat);
+    });
+
+    it('should return the default schema format where there is no value', function() {
+      const d = new Schema({}, {asyncapi: { semver: { version: '3.0.0' } }});
+      expect(d.schemaFormat()).toEqual(getDefaultSchemaFormat('3.0.0'));
+    });
+  });
+
+  describe('MultiFormatSchema is parsed correctly', function() {
+    it('should return any field from the underlaying schema', function() {
+      const doc = {schemaFormat: 'whatever', schema: {$comment: 'test'}};
+      const d = new Schema(doc, {asyncapi: {} as any, pointer: '', });
+      expect(d.$comment()).toEqual('test');
+    });
+  });
+
   describe('.then()', function() {
     it('should return value', function() {
       const doc = { then: {} };