diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 000000000..38ac18578
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,24 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "powershell": {
+ "version": "7.4.5",
+ "commands": [
+ "pwsh"
+ ]
+ },
+ "dotnet-coverage": {
+ "version": "17.12.6",
+ "commands": [
+ "dotnet-coverage"
+ ]
+ },
+ "nbgv": {
+ "version": "3.6.146",
+ "commands": [
+ "nbgv"
+ ]
+ }
+ }
+}
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 6ed7f6e71..9626b31b5 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,5 +1,5 @@
# Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions
-FROM mcr.microsoft.com/dotnet/sdk:8.0.300-jammy
+FROM mcr.microsoft.com/dotnet/sdk:8.0.402-jammy
# Installing mono makes `dotnet test` work without errors even for net472.
# But installing it takes a long time, so it's excluded by default.
diff --git a/.editorconfig b/.editorconfig
index c99b5fb73..e84d0f554 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -26,12 +26,17 @@ indent_size = 2
# Xml config files
[*.{ruleset,config,nuspec,resx,vsixmanifest,vsct,runsettings}]
indent_size = 2
+indent_style = space
# JSON files
[*.json]
indent_size = 2
indent_style = space
+[*.ps1]
+indent_style = space
+indent_size = 4
+
# Dotnet code style settings:
[*.{cs,vb}]
@@ -44,6 +49,7 @@ dotnet_diagnostic.SA1519.severity = silent
# Sort using and Import directives with System.* appearing first
dotnet_sort_system_directives_first = true
+dotnet_separate_import_directive_groups = false
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_property = false:silent
dotnet_style_qualification_for_method = false:silent
@@ -186,6 +192,9 @@ dotnet_diagnostic.DOC108.severity = warning
dotnet_diagnostic.DOC200.severity = warning
dotnet_diagnostic.DOC202.severity = warning
+# CA1062: Validate arguments of public methods
+dotnet_diagnostic.CA1062.severity = suggestion
+
# CS1591: Missing XML comment for publicly visible type or member
dotnet_diagnostic.CS1591.severity = suggestion
@@ -234,5 +243,23 @@ dotnet_diagnostic.SA1615.severity = suggestion
# SA1618: Document type parameters
dotnet_diagnostic.SA1618.severity = suggestion
+# CA2016: Forward the CancellationToken parameter
+dotnet_diagnostic.CA2016.severity = warning
+
+# SA1005: Single line comments should begin with single space
+dotnet_diagnostic.SA1005.severity = none
+
+# SA1507: Code should not contain multiple blank lines in a row
+dotnet_diagnostic.SA1507.severity = none
+
+# SA1508: Closing braces should not be preceded by blank line
+dotnet_diagnostic.SA1508.severity = none
+
+# SA1512: Single-line comments should not be followed by blank line
+dotnet_diagnostic.SA1512.severity = none
+
+# SA1515: Single-line comment should be preceded by blank line
+dotnet_diagnostic.SA1515.severity = none
+
[*.sln]
indent_style = tab
diff --git a/.github/actions/check-metas/action.yaml b/.github/actions/check-metas/action.yaml
new file mode 100644
index 000000000..7966a217b
--- /dev/null
+++ b/.github/actions/check-metas/action.yaml
@@ -0,0 +1,33 @@
+name: Check all .meta is commited
+description: Check all Unity .meta files are committed.
+inputs:
+ directory:
+ description: Working directory to check change
+ required: true
+ exit-on-error:
+ description: Exit on error
+ required: false
+ default: "true"
+outputs:
+ meta-exists:
+ description: If .meta file exists
+ value: ${{ steps.check-meta.outputs.meta-exists }}
+
+runs:
+ using: "composite"
+ steps:
+ - name: Check .meta exists
+ id: check-meta
+ shell: bash
+ run: |
+ if git ls-files --others --exclude-standard -t | grep --regexp='[.]meta$'; then
+ echo "Detected .meta file generated. Do you forgot commit a .meta file?"
+ echo "meta-exists=true" | tee -a "$GITHUB_OUTPUT"
+ if [[ "${{inputs.exit-on-error }}" == "true" ]]; then
+ exit 1
+ fi
+ else
+ echo "Great, all .meta files are commited."
+ echo "meta-exists=false" | tee -a "$GITHUB_OUTPUT"
+ fi
+ working-directory: ${{ inputs.directory }}
diff --git a/.github/actions/setup-dotnet/action.yaml b/.github/actions/setup-dotnet/action.yaml
new file mode 100644
index 000000000..e44880788
--- /dev/null
+++ b/.github/actions/setup-dotnet/action.yaml
@@ -0,0 +1,52 @@
+name: Setup .NET SDKs
+description: Setup .NET SDKs and environment variables
+inputs:
+ global-json-file:
+ description: "path to the global.json file."
+ required: false
+ default: "global.json"
+ skip-env:
+ description: "Optional skip environment set."
+ required: false
+ default: "false"
+
+runs:
+ using: "composite"
+ steps:
+ # see: https://github.com/actions/setup-dotnet
+ - uses: actions/setup-dotnet@v4
+ with:
+ global-json-file: ${{ inputs.global-json-file }}
+
+ # see: https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables
+ # GitHub Actions Hosted Runner default environment contains some .NET Environment.
+ # * DOTNET_MUTILEVEL_LOOKUP=0
+ # * DOTNET_NOLOGO=1
+ # * DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
+ # Do not set the following environment variables:
+ # * NUGET_XMLDOC_MODE=skip <- pulumi and some other packge restore will fail.
+ - name: "Configure Environment Variables (.NET SDK)"
+ shell: bash
+ run: |
+ echo "::group::Configure .NET Environment Variables."
+ echo "COMPlus_EnableDiagnostics=0" | tee -a "$GITHUB_ENV"
+ echo "DOTNET_CLI_TELEMETRY_OPTOUT=1" | tee -a "$GITHUB_ENV"
+ echo "DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION=1" | tee -a "$GITHUB_ENV"
+ echo "MSBUILDDISABLENODEREUSE=1" | tee -a "$GITHUB_ENV"
+ echo "TERM=xterm" | tee -a "$GITHUB_ENV"
+ echo "::endgroup::"
+ if: ${{ inputs.skip-env == 'false' }}
+
+ - name: dotnet version
+ shell: bash
+ run: |
+ echo "::group::Show dotnet version"
+ dotnet --version
+ echo "::endgroup::"
+
+ - name: List installed .NET SDKs
+ shell: bash
+ run: |
+ echo "::group::List installed .NET SDKs"
+ dotnet --list-sdks
+ echo "::endgroup::"
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 7150f8e07..718f2612c 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,5 +1,5 @@
# Please see the documentation for all configuration options:
-# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
diff --git a/.github/workflows/_clean-packagejson-branch.yaml b/.github/workflows/_clean-packagejson-branch.yaml
new file mode 100644
index 000000000..864f968df
--- /dev/null
+++ b/.github/workflows/_clean-packagejson-branch.yaml
@@ -0,0 +1,54 @@
+name: (R) Clean package.json branch
+
+on:
+ workflow_call:
+ inputs:
+ branch:
+ description: "branch name to delete. Only delete branches that are created by github-actions[bot] and are not the default branch."
+ required: true
+ type: string
+ outputs:
+ branch-deleted:
+ description: "Indicate branch is deleted or not by boolean. true = branch deleted, false = branch not deleted."
+ value: ${{ jobs.cleanup.outputs.branch-deleted }}
+
+jobs:
+ cleanup:
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # auto generated token
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ outputs:
+ branch-deleted: ${{ steps.check-branch.outputs.deletable }}
+ steps:
+ - name: Check branch is deletable
+ id: check-branch
+ run: |
+ # Check if the branch is the default branch
+ if [[ "$(gh api /repos/${{ github.repository }} | jq -r '.default_branch')" == "${{ inputs.branch }}" ]]; then
+ echo "Branch is default, you cannot delete this branch. branch: ${{ inputs.branch }}"
+ exit 1
+ fi
+
+ # Check if the branch is created by github-actions[bot]
+ if gh api /repos/${{ github.repository }}/branches | jq -r '.[].name' | grep "${{ inputs.branch }}" >/dev/null; then
+ echo "branch exists. branch: ${{ inputs.branch }}"
+
+ # Check info of the branch
+ gh api /repos/${{ github.repository }}/branches/${{ inputs.branch }} | jq
+
+ if [[ "$(gh api /repos/${{ github.repository }}/branches/${{ inputs.branch }} | jq -r '.commit.author.login')" != "github-actions[bot]" ]]; then
+ echo "Branch is not created by github-actions[bot], you cannot delete this branch. branch: ${{ inputs.branch }}"
+ exit 1
+ fi
+
+ branch_deletable=true
+ else
+ echo "branch not exists. branch: ${{ inputs.branch }}"
+ branch_deletable=false
+ fi
+
+ echo "deletable=${branch_deletable}" | tee -a "${GITHUB_OUTPUT}"
+ - name: Delete branch
+ if: ${{ steps.check-branch.outputs.deletable == 'true' }}
+ run: gh api -X DELETE /repos/${{ github.repository }}/git/refs/heads/${{ inputs.branch }}
diff --git a/.github/workflows/_create-release.yaml b/.github/workflows/_create-release.yaml
new file mode 100644
index 000000000..ec5728191
--- /dev/null
+++ b/.github/workflows/_create-release.yaml
@@ -0,0 +1,169 @@
+name: (R) Create Release
+
+on:
+ workflow_call:
+ inputs:
+ commit-id:
+ description: "CommitId to create release & tag."
+ required: true
+ type: string
+ dry-run:
+ description: "true = no upload. false = dry run changes && delete release after 60s."
+ required: true
+ type: boolean
+ tag:
+ description: "Git tag to create. (sample 1.0.0)"
+ required: true
+ type: string
+ # nuget
+ nuget-path:
+ description: "nuget path to upload."
+ required: false
+ type: string
+ default: |
+ ./nuget/*.nupkg
+ ./nuget/*.snupkg
+ nuget-push:
+ description: "true = upload nuget package. false = not upload"
+ required: false
+ type: boolean
+ default: false
+ # release
+ release-asset-path:
+ description: "release assets path to upload. This is a list of paths separated by a newline."
+ required: false
+ type: string
+ release-upload:
+ description: "true = upload assets. false = not upload"
+ required: false
+ type: boolean
+ default: false
+
+jobs:
+ create-release:
+ name: Create Release
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # auto generated token
+ GH_REPO: ${{ github.repository }}
+ NUGET_KEY: ${{ secrets.NUGET_KEY }}
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - name: Validate inputs - unitypackage
+ shell: bash
+ if: ${{ inputs.release-upload && inputs.release-asset-path == '' }}
+ run: |
+ echo "Validation error! 'inputs.release-asset-path' cannot be blank when 'inputs.release-upload' is true."
+ exit 1
+
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ inputs.commit-id }}
+ - uses: ./.github/actions/setup-dotnet
+
+ # Download(All) Artifacts to $GITHUB_WORKSPACE
+ - name: donload artifacts
+ uses: actions/download-artifact@v4 # must sync with actions/upload-artifact@v4 in build-release
+ - name: Show download aritifacts
+ run: ls -lR
+ - name: Validate package exists in artifact - release assets
+ if: ${{ inputs.release-upload }}
+ run: |
+ while read -r asset_path; do
+ if [[ "${asset_path}" == "" ]]; then continue; fi
+ # is it a wildcard?
+ # shellcheck disable=SC2086
+ if [[ "$asset_path" == *\** || "$asset_path" == *\?* ]]; then
+ # shellcheck disable=SC2086
+ if ! ls -l ${asset_path}; then
+ echo "Specified nuget package not found. path: $asset_path"
+ if [[ "${asset_path}" == *.nupkg ]]; then
+ echo ".nupkg must be included in the artifact."
+ exit 1
+ fi
+ fi
+ continue
+ fi
+ # is it a file?
+ if [[ ! -f "${asset_path}" ]]; then
+ echo "Specified asset not found. path: ${asset_path}"
+ exit 1
+ fi
+ done <<< "${{ inputs.release-asset-path }}"
+ - name: Validate package exists in artifact - NuGet
+ if: ${{ inputs.nuget-push }}
+ run: |
+ while read -r nuget_path; do
+ if [[ "${nuget_path}" == "" ]]; then continue; fi
+ # shellcheck disable=SC2086
+ if ! ls -l ${nuget_path}; then
+ echo "Specified nuget package not found. path: $nuget_path"
+ if [[ "${nuget_path}" == *.nupkg ]]; then
+ echo ".nupkg must be included in the artifact."
+ exit 1
+ fi
+ fi
+ done <<< "${{ inputs.nuget-path }}"
+
+ # Create Releases
+ - name: Create Tag
+ run: |
+ git tag ${{ inputs.tag }}
+ git push origin ${{ inputs.tag }}
+ - name: Create Release
+ run: gh release create ${{ inputs.tag }} --draft --verify-tag --title "${{ inputs.tag }}" --generate-notes
+ - name: Wait and Verify Release Name is expected
+ run: |
+ sleep 5s
+ actual=$(gh api --paginate /repos/${{ github.repository }}/releases?per_page=100 --jq '.[] | select(.tag_name == "${{ inputs.tag }}") | .name')
+ expected="${{ inputs.tag }}"
+ if [[ "$actual" != "$expected" ]]; then
+ echo "Release name is not as expected. expected: $expected, actual: $actual"
+ exit 1
+ else
+ echo "Release name is expected! expected: $expected, actual: $actual"
+ fi
+ - name: Upload asset files to release
+ run: |
+ while read -r asset_path; do
+ if [[ "${asset_path}" == "" ]]; then continue; fi
+ # is it a wildcard?
+ # shellcheck disable=SC2086
+ if [[ "$asset_path" == *\** || "$asset_path" == *\?* ]]; then
+ for file in ${asset_path}; do
+ gh release upload ${{ inputs.tag }} "${file}"
+ done
+ continue
+ fi
+ # is it a file?
+ gh release upload ${{ inputs.tag }} "${asset_path}"
+ done <<< "${{ inputs.release-asset-path }}"
+ if: ${{ inputs.release-upload }}
+
+ # Upload to NuGet
+ - name: Upload to NuGet (DryRun=${{ inputs.dry-run }})
+ if: ${{ inputs.nuget-push }}
+ run: |
+ while read -r nuget_path; do
+ if [[ "$nuget_path" == "" ]]; then continue; fi
+ # shellcheck disable=SC2086
+ if ! ls -l ${nuget_path} >/dev/null 2>&1;then
+ echo "skipping nuget push, $nuget_path not found."
+ continue
+ fi
+
+ if [[ "${{ inputs.dry-run }}" == "true" ]]; then
+ echo "(dry run) dotnet nuget push \"${nuget_path}\" --skip-duplicate -s https://api.nuget.org/v3/index.json -k \"${{ env.NUGET_KEY }}\""
+ else
+ dotnet nuget push "${nuget_path}" --skip-duplicate -s https://api.nuget.org/v3/index.json -k "${{ env.NUGET_KEY }}"
+ fi
+ done <<< "${{ inputs.nuget-path }}"
+
+ # Clean up
+ - name: Clean up. Wait 60s and delete release if dry-run or failure. (dry-run=${{ inputs.dry-run }}})
+ if: ${{ inputs.dry-run || failure() }}
+ run: |
+ if gh release list | grep Draft | grep ${{ inputs.tag }}; then
+ sleep 60
+ gh release delete ${{ inputs.tag }} --yes --cleanup-tag
+ fi
diff --git a/.github/workflows/_update-packagejson.yaml b/.github/workflows/_update-packagejson.yaml
new file mode 100644
index 000000000..c461c9bed
--- /dev/null
+++ b/.github/workflows/_update-packagejson.yaml
@@ -0,0 +1,168 @@
+name: (R) Update package.json
+
+on:
+ workflow_call:
+ inputs:
+ file-path:
+ description: "package.json path to update. You can input multiline paths. Supported files are `package.json`, `plugin.cfg` and `Directory.Build.props`"
+ required: true
+ type: string
+ tag:
+ description: "git tag you want create. (sample v1.0.0)"
+ required: true
+ type: string
+ dry-run:
+ description: "true to simularate commit but not push change."
+ required: true
+ type: boolean
+ push-tag:
+ description: "true = push tag. false = no push tag."
+ required: false
+ type: boolean
+ default: true
+ outputs:
+ sha:
+ description: "Git commit sha after package.json has changed."
+ value: ${{ jobs.update-packagejson.outputs.sha }}
+ branch-name:
+ description: Git branch name created.
+ value: ${{ jobs.update-packagejson.outputs.branch-name }}
+ is-branch-created:
+ description: Indicate is Git branch created or not.
+ value: ${{ jobs.update-packagejson.outputs.is-branch-created }}
+ normalized_tag:
+ description: Normalized tag with out v prefix.
+ value: ${{ jobs.validate.outputs.normalized_tag }}
+
+jobs:
+ validate:
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ outputs:
+ tag: ${{ steps.trim.outputs.tag }}
+ normalized_tag: ${{ steps.trim.outputs.normalized_tag }}
+ steps:
+ - name: tag must begin with v
+ run: |
+ input_tag="${{ inputs.tag }}"
+ if [[ "$input_tag" != v* ]]; then
+ echo "Tag must begin with v. Current tag: $input_tag"
+ exit 1
+ fi
+ - name: Set version without "v" prefix
+ id: trim
+ run: |
+ input_tag="${{ inputs.tag }}"
+ normalized_tag="${input_tag:1}"
+ echo "normalized_tag=$normalized_tag" | tee -a "$GITHUB_OUTPUT"
+ echo "tag=${{ inputs.tag }}" | tee -a "$GITHUB_OUTPUT"
+
+ update-packagejson:
+ needs: [validate]
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ outputs:
+ sha: ${{ steps.commit.outputs.sha }}
+ branch-name: ${{ steps.configure.outputs.branch-name }}
+ is-branch-created: ${{ steps.commit.outputs.is-branch-created }}
+ steps:
+ - name: Configure Output variables
+ id: configure
+ run: |
+ echo "branch-name=test-release/${{ inputs.tag }}" | tee -a "$GITHUB_OUTPUT"
+
+ - uses: actions/checkout@v4
+
+ # package.json
+ # "version": 1.2.3 -> "version": 2.0.0
+ # plugin.cfg
+ # version="1.2.3" -> version="2.0.0"
+ #
+ # TIPS: `grep -v "^$"` is used to remove empty line.
+ - name: Update files to version ${{ needs.validate.outputs.normalized_tag }}
+ run: |
+ expected="${{ needs.validate.outputs.normalized_tag }}"
+ while read -r file_path; do
+ if [[ "$file_path" == "" ]]; then continue; fi
+
+ echo "Start $file_path"
+ file_name=$(basename "$file_path")
+
+ echo "::group::Before"
+ cat "$file_path"
+ echo "::endgroup::"
+
+ echo "::group::Updating"
+ if [[ "${file_name}" == "package.json" ]]; then
+ # Unity `"version": "VersionString",`
+ sed -i -e "s/\(\"version\":\) \"\(.*\)\",/\1 \"${{ needs.validate.outputs.normalized_tag }}\",/" "${file_path}"
+ elif [[ "${file_name}" == "Directory.Build.props" ]]; then
+ # .NET `VersionString`
+ sed -i -e 's|.*|${{ needs.validate.outputs.normalized_tag }}|g' "${file_path}"
+ else
+ echo "Unknown file name ${file_name} is specified."
+ exit 1
+ fi
+ echo "::endgroup::"
+
+ echo "::group::After"
+ cat "$file_path"
+ echo "::endgroup::"
+
+ echo "::group::Validate Change"
+ if [[ "${file_name}" == "package.json" ]]; then
+ actual=$(grep "version" "$file_path" | cut -d ':' -f 2 | tr -d ',' | tr -d '"' | tr -d ' ')
+ elif [[ "${file_name}" == "Directory.Build.props" ]]; then
+ # -P is for perl regex, only available in GNU grep
+ actual=$(grep -oP '\K.*(?=)' "$file_path")
+ else
+ echo "Validation for ${file_name} is not implemented."
+ exit 1
+ fi
+
+ if [[ "$actual" != "$expected" ]]; then
+ echo "Failed. Path: $file_path, Expected: $expected, Actual: $actual"
+ exit 1
+ else
+ echo "Success. Path: $file_path, Expected: $expected, Actual: $actual"
+ fi
+ echo "::endgroup::"
+ done <<< "${{ inputs.file-path }}"
+
+ - name: Check update on git
+ id: check_update
+ run: git diff --exit-code || echo "changed=1" | tee -a "$GITHUB_OUTPUT"
+
+ - name: Commit files (updated? = ${{ steps.check_update.outputs.changed == '1' }})
+ id: commit
+ run: |
+ if [[ "${{ steps.check_update.outputs.changed }}" == "1" ]]; then
+ git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git config --local user.name "github-actions[bot]"
+ git commit -m "feat: Update package.json to ${{ needs.validate.outputs.normalized_tag }}" -m "Commit by [GitHub Actions](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})" -a
+ echo "sha=$(git rev-parse HEAD)" | tee -a "$GITHUB_OUTPUT"
+ echo "is-branch-created=${{ inputs.dry-run }}" | tee -a "$GITHUB_OUTPUT"
+ else
+ echo "sha=" | tee -a "$GITHUB_OUTPUT"
+ echo "is-branch-created=false" | tee -a "$GITHUB_OUTPUT"
+ fi
+
+ - name: Create Tag
+ if: ${{ steps.check_update.outputs.changed == '1' && inputs.push-tag }}
+ run: git tag ${{ inputs.tag }}
+
+ - name: Push changes
+ if: ${{ !inputs.dry-run && steps.check_update.outputs.changed == '1' }}
+ uses: ad-m/github-push-action@master
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }} # auto generated token
+ tags: ${{ inputs.push-tag }}
+
+ - name: Push changes (dry-run)
+ if: ${{ inputs.dry-run && steps.check_update.outputs.changed == '1' }}
+ uses: ad-m/github-push-action@master
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }} # auto generated token
+ branch: "refs/heads/${{ steps.configure.outputs.branch-name }}"
+ tags: false
+ force: true
diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml
new file mode 100644
index 000000000..444bdae1a
--- /dev/null
+++ b/.github/workflows/build-release.yml
@@ -0,0 +1,75 @@
+name: Run release build and publish to NuGet
+
+on:
+ workflow_dispatch:
+ inputs:
+ tag:
+ description: "tag: git tag you want create. (sample v1.0.0)"
+ required: true
+ dry-run:
+ description: "dry-run: false = create release/nuget. true = never create release/nuget."
+ required: true
+ default: false
+ type: boolean
+
+permissions:
+ actions: write
+ contents: write
+
+jobs:
+ # for unity. need update package.json from tag
+ update-packagejson:
+ uses: ./.github/workflows/_update-packagejson.yaml
+ with:
+ file-path: |
+ ./src/MessagePack.UnityClient/Assets/Scripts/MessagePack/package.json
+ tag: ${{ inputs.tag }}
+ dry-run: ${{ inputs.dry-run }}
+ push-tag: true
+
+ # for dotnet. Build nuget package
+ build-dotnet:
+ needs: [update-packagejson]
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ steps:
+ - run: echo ${{ needs.update-packagejson.outputs.sha }}
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ needs.update-packagejson.outputs.sha }}
+ fetch-depth: 0
+ - uses: ./.github/actions/setup-dotnet
+ # pack nuget
+ - run: dotnet build -c Release -p:Version=${{ needs.update-packagejson.outputs.normalized_tag }}
+ - run: dotnet test -c Release --no-build
+ - run: dotnet pack -c Release -p:Version=${{ needs.update-packagejson.outputs.normalized_tag }} -o ./publish
+ - name: upload artifacts
+ uses: actions/upload-artifact@v4 # must sync with actions/download-artifact@v4 in create-release
+ with:
+ name: nuget
+ path: ./publish/
+ if-no-files-found: 'error' # default 'warn'
+ retention-days: 1 # expire in 1 day
+
+ # create release and upload nuget
+ create-release:
+ needs: [update-packagejson, build-dotnet]
+ uses: ./.github/workflows/_create-release.yaml
+ with:
+ commit-id: ${{ needs.update-packagejson.outputs.sha }}
+ dry-run: ${{ inputs.dry-run }}
+ nuget-push: true
+ release-upload: true
+ release-asset-path: |
+ ./nuget/*.nupkg
+ ./nuget/*.snupkg
+ tag: ${{ inputs.tag }}
+ secrets: inherit
+
+ # delete dry-run created git branch
+ cleanup:
+ if: ${{ needs.update-packagejson.outputs.is-branch-created == 'true' }}
+ needs: [update-packagejson, create-release]
+ uses: ./.github/workflows/_clean-packagejson-branch.yaml
+ with:
+ branch: ${{ needs.update-packagejson.outputs.branch-name }}
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
new file mode 100644
index 000000000..578c78cd3
--- /dev/null
+++ b/.github/workflows/dotnet.yml
@@ -0,0 +1,24 @@
+name: Run .NET Build and Test
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - master
+ - develop
+ pull_request:
+ branches:
+ - master
+ - develop
+
+jobs:
+ build-dotnet:
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
+ - uses: ./.github/actions/setup-dotnet
+ - run: dotnet build -c Release -t:build,pack
+ - run: dotnet test -c Release --no-build
diff --git a/.github/workflows/unity.yml b/.github/workflows/unity.yml
index 2bf7bcba2..332ebb593 100644
--- a/.github/workflows/unity.yml
+++ b/.github/workflows/unity.yml
@@ -1,4 +1,4 @@
-name: unity
+name: Run Unity IL2CPP UnitTest
on:
workflow_dispatch:
@@ -11,38 +11,54 @@ on:
- master
- develop
+env:
+ BUILD_CONFIG: Debug
+
jobs:
unity:
+ if: ${{ ((github.event_name == 'push' && github.repository_owner == 'MessagePack-CSharp') || startsWith(github.event.pull_request.head.label, 'MessagePack-CSharp:')) && github.triggering_actor != 'dependabot[bot]' }}
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
- - uses: actions/setup-dotnet@v3
- with:
- global-json-file: global.json
- - name: copy assets
- run: src/MessagePack.UnityClient/copy_assets.sh
- - uses: actions/cache@v3
+ - uses: ./.github/actions/setup-dotnet
+ - run: dotnet build -c ${{ env.BUILD_CONFIG }} # require dotnet build (Debug) before Unity build.
+
+ - name: restore and run local tool for NuGetForUnity
+ working-directory: ./src/MessagePack.UnityClient
+ run: |
+ dotnet tool restore
+ dotnet nugetforunity restore
+
+ # Run UnitTest
+ - uses: actions/cache@v4
with:
path: src/MessagePack.UnityClient/Library
- key: MessagePack-ubuntu
- - name: build
- uses: game-ci/unity-builder@v2
+ key: Library-MessagePack-StandaloneLinux64
+ restore-keys: |
+ Library-MessagePack-
+ Library-
+ - name: Build project
+ uses: game-ci/unity-builder@v4
env:
- UNITY_LICENSE: ${{ secrets.UNITY_LICENSE_2021 }}
+ UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
+ UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
+ UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
projectPath: src/MessagePack.UnityClient
- unityVersion: 2021.3.11f1
+ unityVersion: 2022.3.12f1
targetPlatform: StandaloneLinux64
- buildMethod: PackageExporter.Export
- customParameters: /headless /ScriptBackend mono
+ buildMethod: UnitTestBuilder.BuildUnitTest
versioning: None
- - uses: Cysharp/Actions/.github/actions/check-metas@main # check meta files
+ customParameters: "/headless /ScriptBackend IL2CPP"
+ - name: Check UnitTest file is generated
+ run: ls -lR ./src/MessagePack.UnityClient/bin/UnitTest
+ - name: Execute UnitTest
+ run: ./src/MessagePack.UnityClient/bin/UnitTest/StandaloneLinux64_IL2CPP/test
+
+ # check meta files
+ - uses: ./.github/actions/check-metas
with:
directory: src/MessagePack.UnityClient
- - uses: actions/upload-artifact@v3
- with:
- name: MessagePack.unitypackage
- path: bin/*.unitypackage
diff --git a/.gitignore b/.gitignore
index 7e74065d1..6ef3a7ca5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,9 @@ bld/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
+# Jetbrains Rider cache directory
+.idea/
+
# Visual Studio 2017 auto generated files
Generated\ Files/
@@ -65,7 +68,6 @@ StyleCopReport.xml
*_p.c
*_h.h
*.ilk
-*.meta
*.obj
*.iobj
*.pch
@@ -353,12 +355,19 @@ MigrationBackup/
# mac-created file to track user view preferences for a directory
.DS_Store
+# Analysis results
+*.sarif
+
# Unity
src/MessagePack.UnityClient/bin/*
src/MessagePack.UnityClient/Library/*
src/MessagePack.UnityClient/obj/*
src/MessagePack.UnityClient/Temp/*
+src/MessagePack.UnityClient/UserSettings/*
+src/MessagePack.UnityClient/Assets/Packages/
# BenchmarkDotNet results
BenchmarkDotNet.Artifacts/
+
+src/MessagePack.UnityClient/.vsconfig
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index ca3a2aa9d..acaf02131 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -7,6 +7,7 @@
"ms-dotnettools.csharp",
"k--kato.docomment",
"editorconfig.editorconfig",
+ "esbenp.prettier-vscode",
"pflannery.vscode-versionlens",
"davidanson.vscode-markdownlint",
"dotjoshjohnson.xml",
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 3ae1371c6..7743c118d 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -3,6 +3,17 @@
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,
"omnisharp.enableEditorConfigSupport": true,
- "omnisharp.enableImportCompletion": true,
- "omnisharp.enableRoslynAnalyzers": true
+ "omnisharp.enableRoslynAnalyzers": true,
+ "dotnet.completion.showCompletionItemsFromUnimportedNamespaces": true,
+ "editor.formatOnSave": true,
+ "[xml]": {
+ "editor.wordWrap": "off"
+ },
+ // Use Prettier as the default formatter for Azure Pipelines files.
+ // Needs to be explicitly configured: https://github.com/Microsoft/azure-pipelines-vscode#document-formatting
+ "[azure-pipelines]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
+ "editor.formatOnSave": false // enable this when they conform
+ },
+ "dotnet.defaultSolution": "MessagePack.sln"
}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 842ccfc2c..0883dcdd5 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,7 +2,7 @@
## Dependencies
-* [Visual Studio 2019](https://visualstudio.microsoft.com/)
+* [Visual Studio 2022](https://visualstudio.microsoft.com/)
* [Unity Editor](https://unity3d.com/unity/editor) (optional)
* .NET Core SDK and runtimes (run `init` to install)
@@ -14,7 +14,7 @@ To get VS to find the toolsets when launched from the Start Menu, run `init -Ins
## How to Build
-Open `MessagePack.sln` on Visual Studio 2019.
+Open `MessagePack.sln` on Visual Studio 2022.
Alternatively you may build from the command line using `msbuild.exe` or:
@@ -22,15 +22,36 @@ Alternatively you may build from the command line using `msbuild.exe` or:
## Unity
-Unity Project requires several dependency DLL's. At first, run `copy_assets.bat` under `src\MessagePack.UnityClient`.
-Then open that directory in the Unity Editor.
+See the ReadMe for the target directory `src\MessagePack.UnityClient` for information on building and managing with Unity. Unity's CI is managed in `unity.yml` in GitHub Actions.
-## Where to find our CI feed
+## How to Publish Package
-Once a change is in a shipping branch (e.g. `v1.8`, `v2.0`, `master`), our CI will build it and push the built package
-to [our CI feed](https://dev.azure.com/ils0086/MessagePack-CSharp/_packaging?_a=feed&feed=MessagePack-CI). To depend on
-one of the packages that are on our CI feed (but not yet on nuget.org) you can add this to your nuget.config file:
+Package publishing is triggered via GitHub Actions using workflow_dispatch. Follow these steps:
-```xml
-
-```
+1. Select Actions -> "Run release build and publish to NuGet"
+2. Enter a version tag (e.g., `v3.0.1`)
+3. Click "Run workflow"
+
+
+
+The workflow will:
+- Update the version in [MessagePack.UnityClient/Assets/Scripts/MessagePack/package.json](https://github.com/MessagePack-CSharp/MessagePack-CSharp/blob/master/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/package.json)
+- Commit and push the change
+- Build the .NET library
+- Publish to [NuGet/MessagePack](https://www.nuget.org/packages/MessagePack)
+- Create a draft GitHub release
+
+After CI completion, edit the release draft to add relevant release notes and announcements.
+
+### Secret
+
+The following secrets are managed at the organization level:
+
+* `UNITY_EMAIL`
+* `UNITY_LICENSE`
+* `UNITY_PASSWORD`
+* `NUGET_KEY`
+
+The `UNITY_*` secrets are personal license keys required for Unity builds.
+
+`NUGET_KEY` is a key required for releasing nupkg files, and since it has a 365-day expiration period, the key needs to be regenerated when it expires.
\ No newline at end of file
diff --git a/Directory.Build.props b/Directory.Build.props
index 2508970e4..2c647f7e6 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,3 +1,4 @@
+
Debug
@@ -5,7 +6,6 @@
$(RepoRootPath)obj\$([MSBuild]::MakeRelative($(RepoRootPath), $(MSBuildProjectDirectory)))\
$(RepoRootPath)bin\$(MSBuildProjectName)\
$(RepoRootPath)bin\Packages\$(Configuration)\
- 10
latest
true
true
@@ -18,13 +18,10 @@
false
-
- $(MSBuildThisFileDirectory)
-
embedded
- https://github.com/neuecc/MessagePack-CSharp
+ https://github.com/MessagePack-CSharp/MessagePack-CSharp
neuecc,aarnott
© Yoshifumi Kawai and contributors. All rights reserved.
MIT
@@ -43,28 +40,4 @@
-
-
- $(PackageProjectUrl)/releases/tag/v$(Version)
-
-
-
-
- false
- true
-
-
-
-
- false
- false
- false
- false
-
diff --git a/Directory.Build.targets b/Directory.Build.targets
index ea7b6e6f8..ecd71a31b 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -1,9 +1,9 @@
+
-
- false
+ 12
+ 16.9
-
diff --git a/Directory.Packages.props b/Directory.Packages.props
index cdeb77b49..6fe591f69 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -1,75 +1,78 @@
+
true
true
- 0.13.5
- 3.11.0
- 4.4.0
+ 0.14.0
+
+ 4.8.0
+ 4.3.0
+ 1.1.2
-
+
-
-
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
+
+
-
+
-
+
+
-
-
-
+
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
-
+
+
+
-
\ No newline at end of file
+
diff --git a/MessagePack.sln b/MessagePack.sln
index 2b743e8e3..77756e3c0 100644
--- a/MessagePack.sln
+++ b/MessagePack.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
-VisualStudioVersion = 17.5.33201.384
+VisualStudioVersion = 17.4.33103.184
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}"
ProjectSection(SolutionItems) = preProject
@@ -12,6 +12,10 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack", "src\MessagePack\MessagePack.csproj", "{7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{19FE674A-AC94-4E7E-B24C-2285D1D04CDE}"
+ ProjectSection(SolutionItems) = preProject
+ tests\SourceGeneratorConsumer.props = tests\SourceGeneratorConsumer.props
+ tests\SourceGeneratorConsumer.targets = tests\SourceGeneratorConsumer.targets
+ EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.Tests", "tests\MessagePack.Tests\MessagePack.Tests.csproj", "{9E1A55CA-711D-4F58-A332-735960E3434C}"
EndProject
@@ -36,8 +40,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.ReactivePropert
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.ImmutableCollection", "src\MessagePack.ImmutableCollection\MessagePack.ImmutableCollection.csproj", "{E066F547-7261-4561-AEFC-E64DBFD874F8}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePackAnalyzer", "src\MessagePackAnalyzer\MessagePackAnalyzer.csproj", "{2F9A6E0C-DE95-4460-96B7-EB72BBEAEE9E}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PerfNetFramework", "sandbox\PerfNetFramework\PerfNetFramework.csproj", "{014A3DCE-50A6-4774-A4C1-C66EEAB67133}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.AspNetCoreMvcFormatter", "src\MessagePack.AspNetCoreMvcFormatter\MessagePack.AspNetCoreMvcFormatter.csproj", "{17831017-C29C-4A48-B159-849BCE5079FB}"
@@ -49,14 +51,11 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{301F812B-8AEE-4DC2-8009-4510F02294AD}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
- azure-pipelines.yml = azure-pipelines.yml
- azure-pipelines\build.yml = azure-pipelines\build.yml
Directory.Build.props = Directory.Build.props
Directory.Packages.props = Directory.Packages.props
global.json = global.json
nuget.config = nuget.config
stylecop.json = stylecop.json
- version.json = version.json
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.AspNetCoreMvcFormatter.Tests", "tests\MessagePack.AspNetCoreMvcFormatter.Tests\MessagePack.AspNetCoreMvcFormatter.Tests.csproj", "{79C2B2CB-872A-4BA9-82DC-60F6DD77F940}"
@@ -76,15 +75,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.Internal", "san
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.Internal.Tests", "tests\MessagePack.Internal.Tests\MessagePack.Internal.Tests.csproj", "{8D9FD130-7905-47D8-A25C-7FDEE28EA0E8}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.GeneratorCore", "src\MessagePack.GeneratorCore\MessagePack.GeneratorCore.csproj", "{9962132D-A271-4E68-ACC1-18FA93462552}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.Generator", "src\MessagePack.Generator\MessagePack.Generator.csproj", "{32C91908-5CAD-4C95-B240-ACBBACAC9476}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.MSBuild.Tasks", "src\MessagePack.MSBuild.Tasks\MessagePack.MSBuild.Tasks.csproj", "{8DB135F5-A6FE-44E4-9853-7B48ED21F21B}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePackAnalyzer.Tests", "tests\MessagePackAnalyzer.Tests\MessagePackAnalyzer.Tests.csproj", "{7E5FB4B9-A0F5-4B10-A1F3-03AC0BC8265A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.SourceGenerator", "src\MessagePack.SourceGenerator\MessagePack.SourceGenerator.csproj", "{32C91908-5CAD-4C95-B240-ACBBACAC9476}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.Generator.Tests", "tests\MessagePack.Generator.Tests\MessagePack.Generator.Tests.csproj", "{6AC51E68-4681-463A-B4B6-BD53517244B2}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.SourceGenerator.Tests", "tests\MessagePack.SourceGenerator.Tests\MessagePack.SourceGenerator.Tests.csproj", "{6AC51E68-4681-463A-B4B6-BD53517244B2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExperimentalBenchmark", "benchmark\ExperimentalBenchmark\ExperimentalBenchmark.csproj", "{4C9BB260-62D8-49CD-9F9C-9AA6A8BFC637}"
EndProject
@@ -94,6 +87,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.Experimental.Te
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.GeneratedCode.Tests", "tests\MessagePack.GeneratedCode.Tests\MessagePack.GeneratedCode.Tests.csproj", "{D4CE7347-CEBE-46E5-BD12-1319573B6C5E}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.SourceGenerator.ExecutionTests", "tests\MessagePack.SourceGenerator.ExecutionTests\MessagePack.SourceGenerator.ExecutionTests.csproj", "{7908D954-15D4-4D67-B49A-4484809DA2C4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.SourceGenerator.MapModeExecutionTests", "tests\MessagePack.SourceGenerator.MapModeExecutionTests\MessagePack.SourceGenerator.MapModeExecutionTests.csproj", "{EDBA7DDC-69AF-4D5B-A8F6-3B508F8CC0FC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.Analyzers.CodeFixes", "src\MessagePack.Analyzers.CodeFixes\MessagePack.Analyzers.CodeFixes.csproj", "{7A6CB600-2393-468F-9952-84EC624D57BD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.Analyzers", "src\MessagePack.Analyzers\MessagePack.Analyzers.csproj", "{EB77463C-9D06-4AAE-84F0-470988D30DA0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CollectionsMarshalBenchmark", "benchmark\CollectionsMarshalBenchmark\CollectionsMarshalBenchmark.csproj", "{9A31C44C-9C51-4D41-B8E5-2864245F877E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -132,10 +135,6 @@ Global
{E066F547-7261-4561-AEFC-E64DBFD874F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E066F547-7261-4561-AEFC-E64DBFD874F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E066F547-7261-4561-AEFC-E64DBFD874F8}.Release|Any CPU.Build.0 = Release|Any CPU
- {2F9A6E0C-DE95-4460-96B7-EB72BBEAEE9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {2F9A6E0C-DE95-4460-96B7-EB72BBEAEE9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2F9A6E0C-DE95-4460-96B7-EB72BBEAEE9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {2F9A6E0C-DE95-4460-96B7-EB72BBEAEE9E}.Release|Any CPU.Build.0 = Release|Any CPU
{014A3DCE-50A6-4774-A4C1-C66EEAB67133}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{014A3DCE-50A6-4774-A4C1-C66EEAB67133}.Debug|Any CPU.Build.0 = Debug|Any CPU
{014A3DCE-50A6-4774-A4C1-C66EEAB67133}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -172,22 +171,10 @@ Global
{8D9FD130-7905-47D8-A25C-7FDEE28EA0E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8D9FD130-7905-47D8-A25C-7FDEE28EA0E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8D9FD130-7905-47D8-A25C-7FDEE28EA0E8}.Release|Any CPU.Build.0 = Release|Any CPU
- {9962132D-A271-4E68-ACC1-18FA93462552}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9962132D-A271-4E68-ACC1-18FA93462552}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9962132D-A271-4E68-ACC1-18FA93462552}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9962132D-A271-4E68-ACC1-18FA93462552}.Release|Any CPU.Build.0 = Release|Any CPU
{32C91908-5CAD-4C95-B240-ACBBACAC9476}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{32C91908-5CAD-4C95-B240-ACBBACAC9476}.Debug|Any CPU.Build.0 = Debug|Any CPU
{32C91908-5CAD-4C95-B240-ACBBACAC9476}.Release|Any CPU.ActiveCfg = Release|Any CPU
{32C91908-5CAD-4C95-B240-ACBBACAC9476}.Release|Any CPU.Build.0 = Release|Any CPU
- {8DB135F5-A6FE-44E4-9853-7B48ED21F21B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8DB135F5-A6FE-44E4-9853-7B48ED21F21B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8DB135F5-A6FE-44E4-9853-7B48ED21F21B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8DB135F5-A6FE-44E4-9853-7B48ED21F21B}.Release|Any CPU.Build.0 = Release|Any CPU
- {7E5FB4B9-A0F5-4B10-A1F3-03AC0BC8265A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {7E5FB4B9-A0F5-4B10-A1F3-03AC0BC8265A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {7E5FB4B9-A0F5-4B10-A1F3-03AC0BC8265A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {7E5FB4B9-A0F5-4B10-A1F3-03AC0BC8265A}.Release|Any CPU.Build.0 = Release|Any CPU
{6AC51E68-4681-463A-B4B6-BD53517244B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6AC51E68-4681-463A-B4B6-BD53517244B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6AC51E68-4681-463A-B4B6-BD53517244B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -208,6 +195,26 @@ Global
{D4CE7347-CEBE-46E5-BD12-1319573B6C5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4CE7347-CEBE-46E5-BD12-1319573B6C5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4CE7347-CEBE-46E5-BD12-1319573B6C5E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7908D954-15D4-4D67-B49A-4484809DA2C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7908D954-15D4-4D67-B49A-4484809DA2C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7908D954-15D4-4D67-B49A-4484809DA2C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7908D954-15D4-4D67-B49A-4484809DA2C4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EDBA7DDC-69AF-4D5B-A8F6-3B508F8CC0FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EDBA7DDC-69AF-4D5B-A8F6-3B508F8CC0FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EDBA7DDC-69AF-4D5B-A8F6-3B508F8CC0FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EDBA7DDC-69AF-4D5B-A8F6-3B508F8CC0FC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7A6CB600-2393-468F-9952-84EC624D57BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7A6CB600-2393-468F-9952-84EC624D57BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7A6CB600-2393-468F-9952-84EC624D57BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7A6CB600-2393-468F-9952-84EC624D57BD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EB77463C-9D06-4AAE-84F0-470988D30DA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EB77463C-9D06-4AAE-84F0-470988D30DA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EB77463C-9D06-4AAE-84F0-470988D30DA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EB77463C-9D06-4AAE-84F0-470988D30DA0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9A31C44C-9C51-4D41-B8E5-2864245F877E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9A31C44C-9C51-4D41-B8E5-2864245F877E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9A31C44C-9C51-4D41-B8E5-2864245F877E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9A31C44C-9C51-4D41-B8E5-2864245F877E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -221,7 +228,6 @@ Global
{C01E1407-7FEC-4C1D-B0B4-74D95A317AA6} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
{166A16C0-B89F-41AF-956A-235C6CA62C25} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
{E066F547-7261-4561-AEFC-E64DBFD874F8} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
- {2F9A6E0C-DE95-4460-96B7-EB72BBEAEE9E} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
{014A3DCE-50A6-4774-A4C1-C66EEAB67133} = {BF4C4202-5015-4FBD-80E6-D0F36A06F700}
{17831017-C29C-4A48-B159-849BCE5079FB} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
{814F94D6-1413-4ACB-B1B5-A3488CAA1E6B} = {BF4C4202-5015-4FBD-80E6-D0F36A06F700}
@@ -231,15 +237,17 @@ Global
{4142EA80-FEF4-44A5-8553-1AE84BEBAFED} = {51A614B0-E583-4DD2-AC7D-6A65634582E0}
{C100FBA6-4164-4D6A-A532-5984D2B8DCB0} = {BF4C4202-5015-4FBD-80E6-D0F36A06F700}
{8D9FD130-7905-47D8-A25C-7FDEE28EA0E8} = {19FE674A-AC94-4E7E-B24C-2285D1D04CDE}
- {9962132D-A271-4E68-ACC1-18FA93462552} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
{32C91908-5CAD-4C95-B240-ACBBACAC9476} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
- {8DB135F5-A6FE-44E4-9853-7B48ED21F21B} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
- {7E5FB4B9-A0F5-4B10-A1F3-03AC0BC8265A} = {19FE674A-AC94-4E7E-B24C-2285D1D04CDE}
{6AC51E68-4681-463A-B4B6-BD53517244B2} = {19FE674A-AC94-4E7E-B24C-2285D1D04CDE}
{4C9BB260-62D8-49CD-9F9C-9AA6A8BFC637} = {51A614B0-E583-4DD2-AC7D-6A65634582E0}
{AC2503A7-736D-4AE6-9355-CF35D9DF6139} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
{8AB40D1C-1134-4D77-B39A-19AEDC729450} = {19FE674A-AC94-4E7E-B24C-2285D1D04CDE}
{D4CE7347-CEBE-46E5-BD12-1319573B6C5E} = {19FE674A-AC94-4E7E-B24C-2285D1D04CDE}
+ {7908D954-15D4-4D67-B49A-4484809DA2C4} = {19FE674A-AC94-4E7E-B24C-2285D1D04CDE}
+ {EDBA7DDC-69AF-4D5B-A8F6-3B508F8CC0FC} = {19FE674A-AC94-4E7E-B24C-2285D1D04CDE}
+ {7A6CB600-2393-468F-9952-84EC624D57BD} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
+ {EB77463C-9D06-4AAE-84F0-470988D30DA0} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC}
+ {9A31C44C-9C51-4D41-B8E5-2864245F877E} = {51A614B0-E583-4DD2-AC7D-6A65634582E0}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B3911209-2DBF-47F8-98F6-BBC0EDFE63DE}
diff --git a/README.md b/README.md
index 294afa514..30cea70f9 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# MessagePack for C# (.NET Framework, .NET 6, Unity, Xamarin)
+# MessagePack for C# (.NET Framework, .NET 8, Unity, Xamarin)
[](https://www.nuget.org/packages/messagepack)
[](https://www.nuget.org/packages/messagepack)
@@ -57,19 +57,20 @@ MessagePack has a compact binary size and a full set of general purpose expressi
- [IgnoreFormatter](#ignoreformatter)
- [Reserved Extension Types](#reserved-extension-types)
- [Unity support](#unity-support)
-- [AOT Code Generation (support for Unity/Xamarin)](#aot-code-generation-support-for-unityxamarin)
+- [AOT Code Generation (support for Unity/Xamarin)](#aot)
- [RPC](#rpc)
- [MagicOnion](#magiconion)
- [StreamJsonRpc](#streamjsonrpc)
- [How to build](#how-to-build)
- [Author Info](#author-info)
+- [Code of Conduct & .NET Foundation notice](#coc)
## Installation
This library is distributed via NuGet. Special [Unity support](#unity) is available, too.
-We target .NET Standard 2.0 with special optimizations for .NET 6+, making it compatible with most reasonably recent .NET runtimes such as Core 2.0 and later, Framework 4.6.1 and later, Mono 5.4 and later and Unity 2018.3 and later.
-The library code is pure C# (with Just-In-Time IL code generation on some platforms).
+We target .NET Standard 2.0 with special optimizations for .NET 8+ and .NET Framework.
+The library code is pure C# (with Just-In-Time IL code generation on some platforms or AOT safe source generators).
### NuGet packages
@@ -79,12 +80,6 @@ To install with NuGet, just install the `MessagePack` package:
Install-Package MessagePack
```
-Install the optional C# [analyzers](doc/analyzers/index.md) package to get warnings about coding mistakes and automatic fix suggestions to save you time:
-
-```ps1
-Install-Package MessagePackAnalyzer
-```
-
There are also a range of official and third party Extension Packages available (learn more in our [extensions section](#extensions)):
```ps1
@@ -95,11 +90,12 @@ Install-Package MessagePack.AspNetCoreMvcFormatter
### Unity
-For Unity projects, the [Releases](https://github.com/MessagePack-CSharp/MessagePack-CSharp/releases) page provides downloadable `.unitypackage` files. When using in Unity IL2CPP or Xamarin AOT environments, please carefully read the [pre-code generation section](#aot).
+For Unity projects, please read the [Unity Support](#unity-support) section to install.
-### Migration notes from v1.x
+### Migration notes from prior versions
-If you were using MessagePack for C# v1.x, check out the ["How to update to our new v2.x version"](doc/migration.md) document.
+Migrating from a prior major version of MessagePack to the latest?
+Check out [these instructions](doc/migration.md).
## Quick Start
@@ -161,22 +157,23 @@ By default, a `MessagePackObject` annotation is required. This can be made optio
## Analyzer
-The MessagePackAnalyzer package aids with:
+The MessagePackAnalyzer package(includes in default) aids with:
-1. Automating definitions for your serializable objects.
1. Produces compiler warnings upon incorrect attribute use, member accessibility, and more.
+1. Automating attributing of your serializable classes and members.
+1. Optionally improving startup time through [AOT formatter generation](#aot).
-
+The first two of these features is demonstrated below:
-If you want to allow a specific custom type (for example, when registering a custom type), put `MessagePackAnalyzer.json` at the project root and change the Build Action to `AdditionalFiles`.
-
-
+
-An example `MessagePackAnalyzer.json`:
+Two assembly-level attributes exist to help with mixing in your own custom formatters with the automatically generated ones:
+- `MessagePackKnownFormatterAttribute` - Identifies classes that implement `IMessagePackFormatter`.
+The `T` type argument will _not_ produce an analyzer warning when `T` is used elsewhere in a serializable object.
+When using a source generated resolver, the resolver will refer to this formatter for the appropriate type(s).
+- `MessagePackAssumedFormattableAttribute` - Identifies types that are assumed to have an `IMessagePackFormatter` *somewhere*, and that will be combined within an `IFormatterResolver` at runtime to ensure the specified type can be serialized.
+This attribute will suppress the analyzer warning from using that type although the type does not have a `[MessagePackObject]` attribute on it.
-```json
-[ "MyNamespace.FooClass", "MyNameSpace.BarStruct" ]
-```
## Built-in supported types
@@ -348,7 +345,10 @@ You can use `[DataContract]` annotations instead of `[MessagePackObject]` ones.
Then `[DataMember(Order = int)]` will behave the same as `[Key(int)]`, `[DataMember(Name = string)]` the same as `[Key(string)]`, and `[DataMember]` the same as `[Key(nameof(member name)]`.
-Using `DataContract`, e.g. in shared libraries, makes your classes/structs independent from MessagePack for C# serialization. However, it is not supported by the analyzers nor in code generation by the `mpc` tool. Also, features like `UnionAttribute`, `MessagePackFormatter`, `SerializationConstructor`, etc can not be used. Due to this, we recommend that you use the specific MessagePack for C# annotations when possible.
+Using `DataContract`, e.g. in shared libraries, makes your classes/structs independent from MessagePack for C# serialization.
+However, it is not supported by the analyzers nor source generator.
+Also, features like `UnionAttribute`, `MessagePackFormatter`, `SerializationConstructor`, etc can not be used.
+Due to this, we recommend that you use the specific MessagePack for C# annotations when possible.
## Serializing readonly/immutable object members (SerializationConstructor)
@@ -721,7 +721,7 @@ Performance varies depending on the options used. This is a micro benchmark with
| JilString | 553.65 ns | NA | 7.62 | 0.0362 | 152 B |
| JilStreamReader | 1,408.46 ns | NA | 19.38 | 0.8450 | 3552 B |
-`ÌntKey`, `StringKey`, `Typeless_IntKey`, `Typeless_StringKey` are MessagePack for C# options. All MessagePack for C# options achieve zero memory allocations in the deserialization process. `JsonNetString`/`JilString` is deserialized from strings. `JsonNetStreamReader`/`JilStreamReader` is deserialized from UTF-8 byte arrays using `StreamReader`. Deserialization is normally read from Stream. Thus, it will be restored from byte arrays (or Stream) instead of strings.
+`IntKey`, `StringKey`, `Typeless_IntKey`, `Typeless_StringKey` are MessagePack for C# options. All MessagePack for C# options achieve zero memory allocations in the deserialization process. `JsonNetString`/`JilString` is deserialized from strings. `JsonNetStreamReader`/`JilStreamReader` is deserialized from UTF-8 byte arrays using `StreamReader`. Deserialization is normally read from Stream. Thus, it will be restored from byte arrays (or Stream) instead of strings.
MessagePack for C# `IntKey` is the fastest. `StringKey` is slower than `IntKey` because matching the character string of property names is required. `IntKey` works by reading the array length, then `for (array length) { binary decode }`. `StringKey` works by reading map length, `for (map length) { decode key, lookup key, binary decode }`, so it requires an additional two steps (decoding of keys and lookups of keys).
@@ -1529,17 +1529,49 @@ Within the *reserved* ranges, this library defines or implements extensions that
## Unity support
-Unity lowest supported version is `2018.3`, API Compatibility Level supports both `.NET 4.x` and `.NET Standard 2.0`.
+The minimum supported Unity version will be `2022.3.12f1`, as it is necessary to support IL2CPP via C# Source Generator.
+
+There are two installation steps required to use it in Unity. Do both, not just one.
+
+1. Install `MessagePack` from NuGet using [NuGetForUnity](https://github.com/GlitchEnzo/NuGetForUnity)
+ Open Window from NuGet -> Manage NuGet Packages, Search "MessagePack" and Press Install.
+
+2. Install `MessagePack.Unity` package by referencing the git URL.
+ Open Package Manager window and press `Add Package from git URL...`, enter following path
+
+ ```
+ https://github.com/MessagePack-CSharp/MessagePack-CSharp.git?path=src/MessagePack.UnityClient/Assets/Scripts/MessagePack
+ ```
+
+ MessagePack uses the ..* release tag, so you can specify a version like #v3.0.0. For example: `https://github.com/MessagePack-CSharp/MessagePack-CSharp.git?path=src/MessagePack.UnityClient/Assets/Scripts/MessagePack#v3.0.0`
+
+In Unity, MessagePackSerializer can serialize `Vector2`, `Vector3`, `Vector4`, `Quaternion`, `Color`, `Bounds`, `Rect`, `AnimationCurve`, `Keyframe`, `Matrix4x4`, `Gradient`, `Color32`, `RectOffset`, `LayerMask`, `Vector2Int`, `Vector3Int`, `RangeInt`, `RectInt`, `BoundsInt` and their nullable, array and list types with the built-in extension `UnityResolver`.
+
+`MessagePack.Unity` automatically adds `UnityResolver` to the default options Resolver when the application starts with code like this in the unity package to enable this serialization:
+
+```csharp
+[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
+private static void Init()
+{
+ MessagePackSerializer.DefaultOptions = MessagePackSerializerOptions.Standard.WithResolver(UnityResolver.InstanceWithStandardResolver);
+}
+```
+
+If you want to customize the Resolver or change the DefaultOptions, it would be good to keep this in mind.
-You can install the `unitypackage` from the [Releases](https://github.com/MessagePack-CSharp/MessagePack-CSharp/releases) page.
-If your build targets .NET Framework 4.x and runs on mono, you can use it as is.
-But if your build targets IL2CPP, you can not use `Dynamic***Resolver`, so it is required to use pre-code generation. Please see [pre-code generation section](#aot).
+### Share types with .NET
-MessagePack for C# includes some additional `System.*.dll` libraries that originally provides in NuGet. They are located under `Plugins`. If other packages use these libraries (e.g. Unity Collections package using `System.Runtime.CompilerServices.Unsafe.dll`), to avoid conflicts, please delete the DLL under `Plugins`.
+The `MessagePack.UnityShims` NuGet package is for .NET server-side serialization support to communicate with Unity. It includes shims for Vector3 etc and the Safe/Unsafe serialization extension.
-Currently `CompositeResolver.Create` does not work on IL2CPP, so it is recommended to use `StaticCompositeResolver.Instance.Register` instead.
+There are several ways to share types between .NET and Unity:
-In Unity, MessagePackSerializer can serialize `Vector2`, `Vector3`, `Vector4`, `Quaternion`, `Color`, `Bounds`, `Rect`, `AnimationCurve`, `Keyframe`, `Matrix4x4`, `Gradient`, `Color32`, `RectOffset`, `LayerMask`, `Vector2Int`, `Vector3Int`, `RangeInt`, `RectInt`, `BoundsInt` and their nullable, array and list types with the built-in extension `UnityResolver`. It is included in StandardResolver by default.
+* Share using symbolic links
+* Place the actual files on the Unity side and reference them as link files in the .NET csproj
+* Use UPM local references to reference the .NET project from the Unity side
+
+While the setup is a bit challenging, the smoothest way to share is using UPM local references. For detailed steps, please refer to the [MagicOnion Sample](https://github.com/Cysharp/MagicOnion/tree/main/samples/ChatApp).
+
+### UnsafeBlitResolver
MessagePack for C# has an additional unsafe extension. `UnsafeBlitResolver` is special resolver for extremely fast but unsafe serialization/deserialization of struct arrays.
@@ -1562,133 +1594,58 @@ var options = MessagePackSerializerOptions.Standard.WithResolver(StaticComposite
MessagePackSerializer.DefaultOptions = options;
```
-The `MessagePack.UnityShims` NuGet package is for .NET server-side serialization support to communicate with Unity. It includes shims for Vector3 etc and the Safe/Unsafe serialization extension.
-
-If you want to share a class between Unity and a server, you can use `SharedProject` or `Reference as Link` or a glob reference (with `LinkBase`), etc. Anyway, you need to share at source-code level. This is a sample project structure using a glob reference (recommended).
+## AOT Code Generation
-- ServerProject(.NET Framework 4.6/.NET/.NET Standard)
- - \[``\]
- - \[MessagePack\]
- - \[MessagePack.UnityShims\]
-- UnityProject
- - \[Concrete SharedCodes\]
- - \[MessagePack\](not dll/NuGet, use MessagePack.Unity.unitypackage's sourcecode)
+A source generator is provided in the `MessagePackAnalyzer` package, which is automatically installed when you install `MessagePack` via NuGet.
+This will source generate the formatters required for all your `[MessagePackObject]`-annotated data types during compilation for the fastest possible startup and runtime.
+An `IFormatterResolver` is also generated that bundles all source generated and user-written formatters together.
+The `StandardResolver` includes the `SourceGeneratedFormatterResolver` which discovers and uses your source generated resolver automatically.
-## AOT Code Generation (support for Unity/Xamarin)
+Therefore, in the usual scenario, it will work with AOT Safe without any special handling.
+If you prefer to restrict your resolver to source-generated formatters, you should use the `MessagePack.GeneratedMessagePackResolver`, which is source generated into your project for that purpose.
+This type's name and namespace can be customized by applying `[GeneratedMessagePackResolver]` to a `partial class` that you define, at which point that class becomes the resolver for you to use.
-By default, MessagePack for C# serializes custom objects by [generating IL](https://msdn.microsoft.com/en-us/library/system.reflection.emit.ilgenerator.aspx) on the fly at runtime to create custom, highly tuned formatters for each type. This code generation has a minor upfront performance cost.
-Because strict-AOT environments such as Xamarin and Unity IL2CPP forbid runtime code generation, MessagePack provides a way for you to run a code generator ahead of time as well.
+At runtime, if a source generated or hand-written formatter cannot be found for a given `[MessagePackObject]` type, MessagePack will generate the formatters on the fly using [Reflection.Emit](https://learn.microsoft.com/dotnet/api/system.reflection.emit.ilgenerator) to create highly-tuned formatters for each type.
+This code generation has a minor upfront performance cost.
> Note: When using Unity, dynamic code generation only works when targeting .NET Framework 4.x + mono runtime.
For all other Unity targets, AOT is required.
-If you want to avoid the upfront dynamic generation cost or you need to run on Xamarin or Unity, you need AOT code generation. `mpc` (MessagePackCompiler) is the code generator of MessagePack for C#. mpc uses [Roslyn](https://github.com/dotnet/roslyn) to analyze source code.
-
-First of all, mpc requires [.NET 6+ Runtime](https://dotnet.microsoft.com/download). The easiest way to acquire and run mpc is as a dotnet tool.
-
-```
-dotnet tool install --global MessagePack.Generator
-```
-
-Installing it as a local tool allows you to include the tools and versions that you use in your source control system. Run these commands in the root of your repo:
-
-```
-dotnet new tool-manifest
-dotnet tool install MessagePack.Generator
-```
-
-Check in your `.config\dotnet-tools.json` file. On another machine you can "restore" your tool using the `dotnet tool restore` command.
-
-Once you have the tool installed, simply invoke using `dotnet mpc` within your repo:
-
-```
-dotnet mpc --help
-
-Usage: mpc [options...]
-
-Options:
- -i, -input Input path to MSBuild project file or the directory containing Unity source files. (Required)
- -o, -output Output file path(.cs) or directory(multiple generate file). (Required)
- -c, -conditionalSymbol Conditional compiler symbols, split with ','. (Default: null)
- -r, -resolverName Set resolver name. (Default: GeneratedResolver)
- -n, -namespace Set namespace root name. (Default: MessagePack)
- -m, -useMapMode Force use map mode serialization. (Default: False)
- -ms, -multipleIfDirectiveOutputSymbols Generate #if-- files by symbols, split with ','. (Default: null)
-```
-
-`mpc` targets C# code with `[MessagePackObject]` or `[Union]` annotations.
-
-```cmd
-// Simple Sample:
-dotnet mpc -i "..\src\Sandbox.Shared.csproj" -o "MessagePackGenerated.cs"
-
-// Use force map simulate DynamicContractlessObjectResolver
-dotnet mpc -i "..\src\Sandbox.Shared.csproj" -o "MessagePackGenerated.cs" -m
-```
+### Customizations
-By default, `mpc` generates the resolver as `MessagePack.Resolvers.GeneratedResolver` and formatters as`MessagePack.Formatters.*`.
+You can customize the generated source through properties on the `GeneratedMessagePackResolverAttribute`.
-Here is the full sample code to register a generated resolver in Unity.
-
-```csharp
-using MessagePack;
-using MessagePack.Resolvers;
-using UnityEngine;
-
-public class Startup
+```cs
+[GeneratedMessagePackResolver]
+partial class MyResolver
{
- static bool serializerRegistered = false;
-
- [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
- static void Initialize()
- {
- if (!serializerRegistered)
- {
- StaticCompositeResolver.Instance.Register(
- MessagePack.Resolvers.GeneratedResolver.Instance,
- MessagePack.Resolvers.StandardResolver.Instance
- );
-
- var option = MessagePackSerializerOptions.Standard.WithResolver(StaticCompositeResolver.Instance);
-
- MessagePackSerializer.DefaultOptions = option;
- serializerRegistered = true;
- }
- }
-
-#if UNITY_EDITOR
-
-
- [UnityEditor.InitializeOnLoadMethod]
- static void EditorInitialize()
- {
- Initialize();
- }
-
-#endif
}
```
-In Unity, you can use MessagePack CodeGen windows at `Windows -> MessagePack -> CodeGenerator`.
+When exposing the generated resolver publicly, consumers outside the library should aggregate the resolver using its `Instance` property, which contains *only* the generated formatters.
-
+Two assembly-level attributes exist to help with mixing in your own custom formatters with the automatically generated ones:
+- `MessagePackKnownFormatterAttribute`
+- `MessagePackAssumedFormattableAttribute`
-Install the .NET runtime, install mpc (as a .NET Tool as described above), and execute `dotnet mpc`. Currently this tool is experimental so please tell me your opinion.
-
-In Xamarin, you can install the [the `MessagePack.MSBuild.Tasks` NuGet package](doc/msbuildtask.md) into your projects to pre-compile fast serialization code and run in environments where JIT compilation is not allowed.
-
-## RPC
-
-MessagePack advocated [MessagePack RPC](https://github.com/msgpack-rpc/msgpack-rpc), but work on it has stopped and it is not widely used.
+Learn more about using a mix of your own custom formatters and automatically generated ones in [the Analyzer section](#analyzer).
### MagicOnion
-I've created a gRPC based MessagePack HTTP/2 RPC streaming framework called [MagicOnion](https://github.com/Cysharp/MagicOnion). gRPC usually communicates with Protocol Buffers using IDL. But MagicOnion uses MessagePack for C# and does not need IDL. When communicating C# to C#, schemaless (or rather C# classes as schema) is better than using IDL.
+[MagicOnion](https://github.com/Cysharp/MagicOnion) is a code-first gRPC framework based on grpc-dotnet and MessagePack. gRPC usually communicates with Protocol Buffers using IDL. But MagicOnion uses MessagePack for C# and does not need IDL. When communicating C# to C#, schemaless (or rather C# classes as schema) is better than using IDL.
### StreamJsonRpc
The StreamJsonRpc library is based on [JSON-RPC](https://www.jsonrpc.org/) and includes [a pluggable formatter architecture](https://github.com/microsoft/vs-streamjsonrpc/blob/master/doc/extensibility.md#alternative-formatters) and as of v2.3 includes [MessagePack support](https://github.com/microsoft/vs-streamjsonrpc/blob/master/doc/extensibility.md#message-formatterss).
## How to build
-
See our [contributor's guide](CONTRIBUTING.md).
+
+## Code of Conduct
+
+This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community.
+For more information see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
+
+## .NET Foundation
+
+This project is supported by the [.NET Foundation](https://dotnetfoundation.org).
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
deleted file mode 100644
index 98cea23dd..000000000
--- a/azure-pipelines.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-trigger:
- batch: true
- branches:
- include:
- - master
- - develop
- - 'v?.*'
- - 'validate/*'
- paths:
- exclude:
- - doc/
- - '*.md'
- - .vscode/
- - .github/
- - azure-pipelines/release.yml
-
-parameters:
-- name: includeMacOS
- displayName: Build on macOS
- type: boolean
- default: false # macOS is often bogged down in Azure Pipelines
-- name: RunTests
- displayName: Run tests
- type: boolean
- default: true
-
-variables:
- MSBuildTreatWarningsAsErrors: true
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
- BuildConfiguration: Release
- ci_feed: https://pkgs.dev.azure.com/ils0086/MessagePack-CSharp/_packaging/MessagePack-CI/nuget/v3/index.json
- NUGET_PACKAGES: $(Agent.TempDirectory)/.nuget/packages/
-
-jobs:
-- template: azure-pipelines/build.yml
- parameters:
- includeMacOS: ${{ parameters.includeMacOS }}
- RunTests: ${{ parameters.RunTests }}
diff --git a/azure-pipelines/Get-ArtifactsStagingDirectory.ps1 b/azure-pipelines/Get-ArtifactsStagingDirectory.ps1
deleted file mode 100644
index 391e5713a..000000000
--- a/azure-pipelines/Get-ArtifactsStagingDirectory.ps1
+++ /dev/null
@@ -1,15 +0,0 @@
-Param(
- [switch]$CleanIfLocal
-)
-if ($env:BUILD_ARTIFACTSTAGINGDIRECTORY) {
- $ArtifactStagingFolder = $env:BUILD_ARTIFACTSTAGINGDIRECTORY
-} elseif ($env:RUNNER_TEMP) {
- $ArtifactStagingFolder = "$env:RUNNER_TEMP\_artifacts"
-} else {
- $ArtifactStagingFolder = [System.IO.Path]::GetFullPath("$PSScriptRoot/../obj/_artifacts")
- if ($CleanIfLocal -and (Test-Path $ArtifactStagingFolder)) {
- Remove-Item $ArtifactStagingFolder -Recurse -Force
- }
-}
-
-$ArtifactStagingFolder
diff --git a/azure-pipelines/Get-CodeCovTool.ps1 b/azure-pipelines/Get-CodeCovTool.ps1
deleted file mode 100644
index ca580b4db..000000000
--- a/azure-pipelines/Get-CodeCovTool.ps1
+++ /dev/null
@@ -1,86 +0,0 @@
-<#
-.SYNOPSIS
- Downloads the CodeCov.io uploader tool and returns the path to it.
-.PARAMETER AllowSkipVerify
- Allows skipping signature verification of the downloaded tool if gpg is not installed.
-#>
-[CmdletBinding()]
-Param(
- [switch]$AllowSkipVerify
-)
-
-if ($IsMacOS) {
- $codeCovUrl = "https://uploader.codecov.io/latest/macos/codecov"
- $toolName = 'codecov'
-}
-elseif ($IsLinux) {
- $codeCovUrl = "https://uploader.codecov.io/latest/linux/codecov"
- $toolName = 'codecov'
-}
-else {
- $codeCovUrl = "https://uploader.codecov.io/latest/windows/codecov.exe"
- $toolName = 'codecov.exe'
-}
-
-$shaSuffix = ".SHA256SUM"
-$sigSuffix = $shaSuffix + ".sig"
-
-Function Get-FileFromWeb([Uri]$Uri, $OutDir) {
- $OutFile = Join-Path $OutDir $Uri.Segments[-1]
- if (!(Test-Path $OutFile)) {
- Write-Verbose "Downloading $Uri..."
- if (!(Test-Path $OutDir)) { New-Item -ItemType Directory -Path $OutDir | Out-Null }
- try {
- (New-Object System.Net.WebClient).DownloadFile($Uri, $OutFile)
- } finally {
- # This try/finally causes the script to abort
- }
- }
-
- $OutFile
-}
-
-$toolsPath = & "$PSScriptRoot\Get-TempToolsPath.ps1"
-$binaryToolsPath = Join-Path $toolsPath codecov
-$testingPath = Join-Path $binaryToolsPath unverified
-$finalToolPath = Join-Path $binaryToolsPath $toolName
-
-if (!(Test-Path $finalToolPath)) {
- if (Test-Path $testingPath) {
- Remove-Item -Recurse -Force $testingPath # ensure we download all matching files
- }
- $tool = Get-FileFromWeb $codeCovUrl $testingPath
- $sha = Get-FileFromWeb "$codeCovUrl$shaSuffix" $testingPath
- $sig = Get-FileFromWeb "$codeCovUrl$sigSuffix" $testingPath
- $key = Get-FileFromWeb https://keybase.io/codecovsecurity/pgp_keys.asc $testingPath
-
- if ((Get-Command gpg -ErrorAction SilentlyContinue)) {
- Write-Host "Importing codecov key" -ForegroundColor Yellow
- gpg --import $key
- Write-Host "Verifying signature on codecov hash" -ForegroundColor Yellow
- gpg --verify $sig $sha
- } else {
- if ($AllowSkipVerify) {
- Write-Warning "gpg not found. Unable to verify hash signature."
- } else {
- throw "gpg not found. Unable to verify hash signature. Install gpg or add -AllowSkipVerify to override."
- }
- }
-
- Write-Host "Verifying hash on downloaded tool" -ForegroundColor Yellow
- $actualHash = (Get-FileHash -Path $tool -Algorithm SHA256).Hash
- $expectedHash = (Get-Content $sha).Split()[0]
- if ($actualHash -ne $expectedHash) {
- # Validation failed. Delete the tool so we can't execute it.
- #Remove-Item $codeCovPath
- throw "codecov uploader tool failed signature validation."
- }
-
- Copy-Item $tool $finalToolPath
-
- if ($IsMacOS -or $IsLinux) {
- chmod u+x $finalToolPath
- }
-}
-
-return $finalToolPath
diff --git a/azure-pipelines/Get-NuGetTool.ps1 b/azure-pipelines/Get-NuGetTool.ps1
deleted file mode 100644
index 3097c8736..000000000
--- a/azure-pipelines/Get-NuGetTool.ps1
+++ /dev/null
@@ -1,22 +0,0 @@
-<#
-.SYNOPSIS
- Downloads the NuGet.exe tool and returns the path to it.
-.PARAMETER NuGetVersion
- The version of the NuGet tool to acquire.
-#>
-Param(
- [Parameter()]
- [string]$NuGetVersion='6.4.0'
-)
-
-$toolsPath = & "$PSScriptRoot\Get-TempToolsPath.ps1"
-$binaryToolsPath = Join-Path $toolsPath $NuGetVersion
-if (!(Test-Path $binaryToolsPath)) { $null = mkdir $binaryToolsPath }
-$nugetPath = Join-Path $binaryToolsPath nuget.exe
-
-if (!(Test-Path $nugetPath)) {
- Write-Host "Downloading nuget.exe $NuGetVersion..." -ForegroundColor Yellow
- (New-Object System.Net.WebClient).DownloadFile("https://dist.nuget.org/win-x86-commandline/v$NuGetVersion/NuGet.exe", $nugetPath)
-}
-
-return (Resolve-Path $nugetPath).Path
diff --git a/azure-pipelines/Get-ProcDump.ps1 b/azure-pipelines/Get-ProcDump.ps1
deleted file mode 100644
index 1493fe4b2..000000000
--- a/azure-pipelines/Get-ProcDump.ps1
+++ /dev/null
@@ -1,14 +0,0 @@
-<#
-.SYNOPSIS
-Downloads 32-bit and 64-bit procdump executables and returns the path to where they were installed.
-#>
-$version = '0.0.1'
-$baseDir = "$PSScriptRoot\..\obj\tools"
-$procDumpToolPath = "$baseDir\procdump.$version\bin"
-if (-not (Test-Path $procDumpToolPath)) {
- if (-not (Test-Path $baseDir)) { New-Item -Type Directory -Path $baseDir | Out-Null }
- $baseDir = (Resolve-Path $baseDir).Path # Normalize it
- & (& $PSScriptRoot\Get-NuGetTool.ps1) install procdump -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir -Source https://api.nuget.org/v3/index.json | Out-Null
-}
-
-(Resolve-Path $procDumpToolPath).Path
diff --git a/azure-pipelines/Get-SymbolFiles.ps1 b/azure-pipelines/Get-SymbolFiles.ps1
deleted file mode 100644
index 0ce229fc2..000000000
--- a/azure-pipelines/Get-SymbolFiles.ps1
+++ /dev/null
@@ -1,61 +0,0 @@
-<#
-.SYNOPSIS
- Collect the list of PDBs built in this repo.
-.PARAMETER Path
- The directory to recursively search for PDBs.
-.PARAMETER Tests
- A switch indicating to find PDBs only for test binaries instead of only for shipping shipping binaries.
-#>
-[CmdletBinding()]
-param (
- [parameter(Mandatory=$true)]
- [string]$Path,
- [switch]$Tests
-)
-
-$ActivityName = "Collecting symbols from $Path"
-Write-Progress -Activity $ActivityName -CurrentOperation "Discovery PDB files"
-$PDBs = Get-ChildItem -rec "$Path/*.pdb"
-
-# Filter PDBs to product OR test related.
-$testregex = "unittest|tests|\.test\."
-
-Write-Progress -Activity $ActivityName -CurrentOperation "De-duplicating symbols"
-$PDBsByHash = @{}
-$i = 0
-$PDBs |% {
- Write-Progress -Activity $ActivityName -CurrentOperation "De-duplicating symbols" -PercentComplete (100 * $i / $PDBs.Length)
- $hash = Get-FileHash $_
- $i++
- Add-Member -InputObject $_ -MemberType NoteProperty -Name Hash -Value $hash.Hash
- Write-Output $_
-} | Sort-Object CreationTime |% {
- # De-dupe based on hash. Prefer the first match so we take the first built copy.
- if (-not $PDBsByHash.ContainsKey($_.Hash)) {
- $PDBsByHash.Add($_.Hash, $_.FullName)
- Write-Output $_
- }
-} |? {
- if ($Tests) {
- $_.FullName -match $testregex
- } else {
- $_.FullName -notmatch $testregex
- }
-} |% {
- # Collect the DLLs/EXEs as well.
- $dllPath = "$($_.Directory)/$($_.BaseName).dll"
- $exePath = "$($_.Directory)/$($_.BaseName).exe"
- if (Test-Path $dllPath) {
- $BinaryImagePath = $dllPath
- } elseif (Test-Path $exePath) {
- $BinaryImagePath = $exePath
- } else {
- Write-Warning "`"$_`" found with no matching binary file."
- $BinaryImagePath = $null
- }
-
- if ($BinaryImagePath) {
- Write-Output $BinaryImagePath
- Write-Output $_.FullName
- }
-}
diff --git a/azure-pipelines/Get-nbgv.ps1 b/azure-pipelines/Get-nbgv.ps1
deleted file mode 100644
index a5be2cf7c..000000000
--- a/azure-pipelines/Get-nbgv.ps1
+++ /dev/null
@@ -1,24 +0,0 @@
-<#
-.SYNOPSIS
- Gets the path to the nbgv CLI tool, installing it if necessary.
-#>
-Param(
-)
-
-$existingTool = Get-Command "nbgv" -ErrorAction SilentlyContinue
-if ($existingTool) {
- return $existingTool.Path
-}
-
-$toolInstallDir = & "$PSScriptRoot/Get-TempToolsPath.ps1"
-
-$toolPath = "$toolInstallDir/nbgv"
-if (!(Test-Path $toolInstallDir)) { New-Item -Path $toolInstallDir -ItemType Directory | Out-Null }
-
-if (!(Get-Command $toolPath -ErrorAction SilentlyContinue)) {
- Write-Host "Installing nbgv to $toolInstallDir"
- dotnet tool install --tool-path "$toolInstallDir" nbgv --configfile "$PSScriptRoot/justnugetorg.nuget.config" | Out-Null
-}
-
-# Normalize the path on the way out.
-return (Get-Command $toolPath).Path
diff --git a/azure-pipelines/Merge-CodeCoverage.ps1 b/azure-pipelines/Merge-CodeCoverage.ps1
deleted file mode 100644
index 02ff12b00..000000000
--- a/azure-pipelines/Merge-CodeCoverage.ps1
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/env pwsh
-
-<#
-.SYNOPSIS
- Merges code coverage reports.
-.PARAMETER Path
- The path(s) to search for Cobertura code coverage reports.
-.PARAMETER Format
- The format for the merged result. The default is Cobertura
-.PARAMETER OutputDir
- The directory the merged result will be written to. The default is `coveragereport` in the root of this repo.
-#>
-[CmdletBinding()]
-Param(
- [Parameter(Mandatory=$true)]
- [string[]]$Path,
- [ValidateSet('Badges', 'Clover', 'Cobertura', 'CsvSummary', 'Html', 'Html_Dark', 'Html_Light', 'HtmlChart', 'HtmlInline', 'HtmlInline_AzurePipelines', 'HtmlInline_AzurePipelines_Dark', 'HtmlInline_AzurePipelines_Light', 'HtmlSummary', 'JsonSummary', 'Latex', 'LatexSummary', 'lcov', 'MarkdownSummary', 'MHtml', 'PngChart', 'SonarQube', 'TeamCitySummary', 'TextSummary', 'Xml', 'XmlSummary')]
- [string]$Format='Cobertura',
- [string]$OutputFile=("$PSScriptRoot/../coveragereport/merged.cobertura.xml")
-)
-
-$RepoRoot = [string](Resolve-Path $PSScriptRoot/..)
-
-if (!(Test-Path $RepoRoot/obj/dotnet-coverage*)) {
- dotnet tool install --tool-path $RepoRoot/obj dotnet-coverage --version 17.4.3 --configfile $PSScriptRoot/justnugetorg.nuget.config
-}
-
-Write-Verbose "Searching $Path for *.cobertura.xml files"
-$reports = Get-ChildItem -Recurse $Path -Filter *.cobertura.xml
-
-if ($reports) {
- $reports |% { $_.FullName } |% {
- # In addition to replacing {reporoot}, we also normalize on one kind of slash so that the report aggregates data for a file whether data was collected on Windows or not.
- $xml = [xml](Get-Content -Path $_)
- $xml.coverage.packages.package.classes.class |? { $_.filename} |% {
- $_.filename = $_.filename.Replace('{reporoot}', $RepoRoot).Replace([IO.Path]::AltDirectorySeparatorChar, [IO.Path]::DirectorySeparatorChar)
- }
-
- $xml.Save($_)
- }
-
- $Inputs = $reports |% { Resolve-Path -relative $_.FullName }
-
- if ((Split-Path $OutputFile) -and -not (Test-Path (Split-Path $OutputFile))) {
- New-Item -Type Directory -Path (Split-Path $OutputFile) | Out-Null
- }
-
- & "$RepoRoot/obj/dotnet-coverage" merge $Inputs -o $OutputFile -f cobertura
-} else {
- Write-Error "No reports found to merge."
-}
diff --git a/azure-pipelines/artifacts/Variables.ps1 b/azure-pipelines/artifacts/Variables.ps1
deleted file mode 100644
index 4bc6d2165..000000000
--- a/azure-pipelines/artifacts/Variables.ps1
+++ /dev/null
@@ -1,43 +0,0 @@
-# This artifact captures all variables defined in the ..\variables folder.
-# It "snaps" the values of these variables where we can compute them during the build,
-# and otherwise captures the scripts to run later during an Azure Pipelines environment release.
-
-$RepoRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot/../..")
-$ArtifactBasePath = "$RepoRoot/obj/_artifacts"
-$VariablesArtifactPath = Join-Path $ArtifactBasePath variables
-if (-not (Test-Path $VariablesArtifactPath)) { New-Item -ItemType Directory -Path $VariablesArtifactPath | Out-Null }
-
-# Copy variables, either by value if the value is calculable now, or by script
-Get-ChildItem "$PSScriptRoot/../variables" |% {
- $value = $null
- if (-not $_.BaseName.StartsWith('_')) { # Skip trying to interpret special scripts
- # First check the environment variables in case the variable was set in a queued build
- # Always use all caps for env var access because Azure Pipelines converts variables to upper-case for env vars,
- # and on non-Windows env vars are case sensitive.
- $envVarName = $_.BaseName.ToUpper()
- if (Test-Path env:$envVarName) {
- $value = Get-Content "env:$envVarName"
- }
-
- # If that didn't give us anything, try executing the script right now from its original position
- if (-not $value) {
- $value = & $_.FullName
- }
-
- if ($value) {
- # We got something, so wrap it with quotes so it's treated like a literal value.
- $value = "'$value'"
- }
- }
-
- # If that didn't get us anything, just copy the script itself
- if (-not $value) {
- $value = Get-Content -Path $_.FullName
- }
-
- Set-Content -Path "$VariablesArtifactPath/$($_.Name)" -Value $value
-}
-
-@{
- "$VariablesArtifactPath" = (Get-ChildItem $VariablesArtifactPath -Recurse);
-}
diff --git a/azure-pipelines/artifacts/_all.ps1 b/azure-pipelines/artifacts/_all.ps1
deleted file mode 100755
index 9a22a1d08..000000000
--- a/azure-pipelines/artifacts/_all.ps1
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env pwsh
-
-<#
-.SYNOPSIS
- This script returns all the artifacts that should be collected after a build.
- Each powershell artifact is expressed as an object with these properties:
- Source - the full path to the source file
- ArtifactName - the name of the artifact to upload to
- ContainerFolder - the relative path within the artifact in which the file should appear
- Each artifact aggregating .ps1 script should return a hashtable:
- Key = path to the directory from which relative paths within the artifact should be calculated
- Value = an array of paths (absolute or relative to the BaseDirectory) to files to include in the artifact.
- FileInfo objects are also allowed.
-.PARAMETER Force
- Executes artifact scripts even if they have already been staged.
-#>
-
-[CmdletBinding(SupportsShouldProcess = $true)]
-param (
- [string]$ArtifactNameSuffix,
- [switch]$Force
-)
-
-Function EnsureTrailingSlash($path) {
- if ($path.length -gt 0 -and !$path.EndsWith('\') -and !$path.EndsWith('/')) {
- $path = $path + [IO.Path]::DirectorySeparatorChar
- }
-
- $path.Replace('\', [IO.Path]::DirectorySeparatorChar)
-}
-
-Function Test-ArtifactStaged($artifactName) {
- $varName = "ARTIFACTSTAGED_$($artifactName.ToUpper())"
- Test-Path "env:$varName"
-}
-
-Get-ChildItem "$PSScriptRoot\*.ps1" -Exclude "_*" -Recurse | % {
- $ArtifactName = $_.BaseName
- if ($Force -or !(Test-ArtifactStaged($ArtifactName + $ArtifactNameSuffix))) {
- $totalFileCount = 0
- Write-Verbose "Collecting file list for artifact $($_.BaseName)"
- $fileGroups = & $_
- if ($fileGroups) {
- $fileGroups.GetEnumerator() | % {
- $BaseDirectory = New-Object Uri ((EnsureTrailingSlash $_.Key.ToString()), [UriKind]::Absolute)
- $_.Value | ? { $_ } | % {
- if ($_.GetType() -eq [IO.FileInfo] -or $_.GetType() -eq [IO.DirectoryInfo]) {
- $_ = $_.FullName
- }
-
- $artifact = New-Object -TypeName PSObject
- Add-Member -InputObject $artifact -MemberType NoteProperty -Name ArtifactName -Value $ArtifactName
-
- $SourceFullPath = New-Object Uri ($BaseDirectory, $_)
- Add-Member -InputObject $artifact -MemberType NoteProperty -Name Source -Value $SourceFullPath.LocalPath
-
- $RelativePath = [Uri]::UnescapeDataString($BaseDirectory.MakeRelative($SourceFullPath))
- Add-Member -InputObject $artifact -MemberType NoteProperty -Name ContainerFolder -Value (Split-Path $RelativePath)
-
- Write-Output $artifact
- $totalFileCount += 1
- }
- }
- }
-
- if ($totalFileCount -eq 0) {
- Write-Warning "No files found for the `"$ArtifactName`" artifact."
- }
- } else {
- Write-Host "Skipping $ArtifactName because it has already been staged." -ForegroundColor DarkGray
- }
-}
diff --git a/azure-pipelines/artifacts/_pipelines.ps1 b/azure-pipelines/artifacts/_pipelines.ps1
deleted file mode 100644
index 2d3338b24..000000000
--- a/azure-pipelines/artifacts/_pipelines.ps1
+++ /dev/null
@@ -1,44 +0,0 @@
-<#
-.SYNOPSIS
- This script translates all the artifacts described by _all.ps1
- into commands that instruct Azure Pipelines to actually collect those artifacts.
-#>
-
-[CmdletBinding()]
-param (
- [string]$ArtifactNameSuffix,
- [switch]$StageOnly
-)
-
-Function Set-PipelineVariable($name, $value) {
- if ((Test-Path "Env:\$name") -and (Get-Item "Env:\$name").Value -eq $value) {
- return # already set
- }
-
- #New-Item -Path "Env:\$name".ToUpper() -Value $value -Force | Out-Null
- Write-Host "##vso[task.setvariable variable=$name]$value"
-}
-
-Function Test-ArtifactUploaded($artifactName) {
- $varName = "ARTIFACTUPLOADED_$($artifactName.ToUpper())"
- Test-Path "env:$varName"
-}
-
-& "$PSScriptRoot/_stage_all.ps1" -ArtifactNameSuffix $ArtifactNameSuffix |% {
- # Set a variable which will out-live this script so that a subsequent attempt to collect and upload artifacts
- # will skip this one from a check in the _all.ps1 script.
- Set-PipelineVariable "ARTIFACTSTAGED_$($_.Name.ToUpper())" 'true'
- Write-Host "Staged artifact $($_.Name) to $($_.Path)"
-
- if (!$StageOnly) {
- if (Test-ArtifactUploaded $_.Name) {
- Write-Host "Skipping $($_.Name) because it has already been uploaded." -ForegroundColor DarkGray
- } else {
- Write-Host "##vso[artifact.upload containerfolder=$($_.Name);artifactname=$($_.Name);]$($_.Path)"
-
- # Set a variable which will out-live this script so that a subsequent attempt to collect and upload artifacts
- # will skip this one from a check in the _all.ps1 script.
- Set-PipelineVariable "ARTIFACTUPLOADED_$($_.Name.ToUpper())" 'true'
- }
- }
-}
diff --git a/azure-pipelines/artifacts/_stage_all.ps1 b/azure-pipelines/artifacts/_stage_all.ps1
deleted file mode 100644
index d81d16d46..000000000
--- a/azure-pipelines/artifacts/_stage_all.ps1
+++ /dev/null
@@ -1,60 +0,0 @@
-<#
-.SYNOPSIS
- This script links all the artifacts described by _all.ps1
- into a staging directory, reading for uploading to a cloud build artifact store.
- It returns a sequence of objects with Name and Path properties.
-#>
-
-[CmdletBinding()]
-param (
- [string]$ArtifactNameSuffix
-)
-
-$ArtifactStagingFolder = & "$PSScriptRoot/../Get-ArtifactsStagingDirectory.ps1" -CleanIfLocal
-
-function Create-SymbolicLink {
- param (
- $Link,
- $Target
- )
-
- if ($Link -eq $Target) {
- return
- }
-
- if (Test-Path $Link) { Remove-Item $Link }
- $LinkContainer = Split-Path $Link -Parent
- if (!(Test-Path $LinkContainer)) { mkdir $LinkContainer }
- if ($IsMacOS -or $IsLinux) {
- ln $Target $Link | Out-Null
- } else {
- cmd /c "mklink `"$Link`" `"$Target`"" | Out-Null
- }
-}
-
-# Stage all artifacts
-$Artifacts = & "$PSScriptRoot\_all.ps1" -ArtifactNameSuffix $ArtifactNameSuffix
-$Artifacts |% {
- $DestinationFolder = [System.IO.Path]::GetFullPath("$ArtifactStagingFolder/$($_.ArtifactName)$ArtifactNameSuffix/$($_.ContainerFolder)").TrimEnd('\')
- $Name = "$(Split-Path $_.Source -Leaf)"
-
- #Write-Host "$($_.Source) -> $($_.ArtifactName)\$($_.ContainerFolder)" -ForegroundColor Yellow
-
- if (-not (Test-Path $DestinationFolder)) { New-Item -ItemType Directory -Path $DestinationFolder | Out-Null }
- if (Test-Path -PathType Leaf $_.Source) { # skip folders
- Create-SymbolicLink -Link (Join-Path $DestinationFolder $Name) -Target $_.Source
- }
-}
-
-$ArtifactNames = $Artifacts |% { "$($_.ArtifactName)$ArtifactNameSuffix" }
-$ArtifactNames += Get-ChildItem env:ARTIFACTSTAGED_* |% {
- # Return from ALLCAPS to the actual capitalization used for the artifact.
- $artifactNameAllCaps = "$($_.Name.Substring('ARTIFACTSTAGED_'.Length))"
- (Get-ChildItem $ArtifactStagingFolder\$artifactNameAllCaps* -Filter $artifactNameAllCaps).Name
-}
-$ArtifactNames | Get-Unique |% {
- $artifact = New-Object -TypeName PSObject
- Add-Member -InputObject $artifact -MemberType NoteProperty -Name Name -Value $_
- Add-Member -InputObject $artifact -MemberType NoteProperty -Name Path -Value (Join-Path $ArtifactStagingFolder $_)
- Write-Output $artifact
-}
diff --git a/azure-pipelines/artifacts/build_logs.ps1 b/azure-pipelines/artifacts/build_logs.ps1
deleted file mode 100644
index f05358e03..000000000
--- a/azure-pipelines/artifacts/build_logs.ps1
+++ /dev/null
@@ -1,7 +0,0 @@
-$ArtifactStagingFolder = & "$PSScriptRoot/../Get-ArtifactsStagingDirectory.ps1"
-
-if (!(Test-Path $ArtifactStagingFolder/build_logs)) { return }
-
-@{
- "$ArtifactStagingFolder/build_logs" = (Get-ChildItem -Recurse "$ArtifactStagingFolder/build_logs")
-}
diff --git a/azure-pipelines/artifacts/coverageResults.ps1 b/azure-pipelines/artifacts/coverageResults.ps1
deleted file mode 100644
index d2fee5016..000000000
--- a/azure-pipelines/artifacts/coverageResults.ps1
+++ /dev/null
@@ -1,23 +0,0 @@
-$RepoRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..")
-
-$coverageFiles = @(Get-ChildItem "$RepoRoot/tests/*.cobertura.xml" -Recurse | Where {$_.FullName -notlike "*/In/*" -and $_.FullName -notlike "*\In\*" })
-
-# Prepare code coverage reports for merging on another machine
-if ($env:SYSTEM_DEFAULTWORKINGDIRECTORY) {
- Write-Host "Substituting $env:SYSTEM_DEFAULTWORKINGDIRECTORY with `"{reporoot}`""
- $coverageFiles |% {
- $content = Get-Content -Path $_ |% { $_ -Replace [regex]::Escape($env:SYSTEM_DEFAULTWORKINGDIRECTORY), "{reporoot}" }
- Set-Content -Path $_ -Value $content -Encoding UTF8
- }
-} else {
- Write-Warning "coverageResults: Azure Pipelines not detected. Machine-neutral token replacement skipped."
-}
-
-if (!((Test-Path $RepoRoot\bin) -and (Test-Path $RepoRoot\obj))) { return }
-
-@{
- $RepoRoot = (
- $coverageFiles +
- (Get-ChildItem "$RepoRoot\obj\*.cs" -Recurse)
- );
-}
diff --git a/azure-pipelines/artifacts/deployables.ps1 b/azure-pipelines/artifacts/deployables.ps1
deleted file mode 100644
index 94c48cdd9..000000000
--- a/azure-pipelines/artifacts/deployables.ps1
+++ /dev/null
@@ -1,13 +0,0 @@
-$RepoRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..")
-$BuildConfiguration = $env:BUILDCONFIGURATION
-if (!$BuildConfiguration) {
- $BuildConfiguration = 'Debug'
-}
-
-$PackagesRoot = "$RepoRoot/bin/Packages/$BuildConfiguration"
-
-if (!(Test-Path $PackagesRoot)) { return }
-
-@{
- "$PackagesRoot" = (Get-ChildItem $PackagesRoot -Recurse)
-}
diff --git a/azure-pipelines/artifacts/projectAssetsJson.ps1 b/azure-pipelines/artifacts/projectAssetsJson.ps1
deleted file mode 100644
index d2e85ffbe..000000000
--- a/azure-pipelines/artifacts/projectAssetsJson.ps1
+++ /dev/null
@@ -1,9 +0,0 @@
-$ObjRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..\obj")
-
-if (!(Test-Path $ObjRoot)) { return }
-
-@{
- "$ObjRoot" = (
- (Get-ChildItem "$ObjRoot\project.assets.json" -Recurse)
- );
-}
diff --git a/azure-pipelines/artifacts/symbols.ps1 b/azure-pipelines/artifacts/symbols.ps1
deleted file mode 100644
index 9e2c7bd5b..000000000
--- a/azure-pipelines/artifacts/symbols.ps1
+++ /dev/null
@@ -1,7 +0,0 @@
-$BinPath = [System.IO.Path]::GetFullPath("$PSScriptRoot/../../bin")
-if (!(Test-Path $BinPath)) { return }
-$symbolfiles = & "$PSScriptRoot/../Get-SymbolFiles.ps1" -Path $BinPath | Get-Unique
-
-@{
- "$BinPath" = $SymbolFiles;
-}
diff --git a/azure-pipelines/artifacts/testResults.ps1 b/azure-pipelines/artifacts/testResults.ps1
deleted file mode 100644
index 6c042043a..000000000
--- a/azure-pipelines/artifacts/testResults.ps1
+++ /dev/null
@@ -1,15 +0,0 @@
-[CmdletBinding()]
-Param(
-)
-
-$result = @{}
-
-$testRoot = Resolve-Path "$PSScriptRoot\..\..\tests"
-$result[$testRoot] = (Get-ChildItem "$testRoot\TestResults" -Recurse -Directory | Get-ChildItem -Recurse -File)
-
-$testlogsPath = "$env:BUILD_ARTIFACTSTAGINGDIRECTORY\test_logs"
-if (Test-Path $testlogsPath) {
- $result[$testlogsPath] = Get-ChildItem "$testlogsPath\*";
-}
-
-$result
diff --git a/azure-pipelines/artifacts/test_symbols.ps1 b/azure-pipelines/artifacts/test_symbols.ps1
deleted file mode 100644
index ce2b6481c..000000000
--- a/azure-pipelines/artifacts/test_symbols.ps1
+++ /dev/null
@@ -1,7 +0,0 @@
-$BinPath = [System.IO.Path]::GetFullPath("$PSScriptRoot/../../bin")
-if (!(Test-Path $BinPath)) { return }
-$symbolfiles = & "$PSScriptRoot/../Get-SymbolFiles.ps1" -Path $BinPath -Tests | Get-Unique
-
-@{
- "$BinPath" = $SymbolFiles;
-}
diff --git a/azure-pipelines/build.yml b/azure-pipelines/build.yml
deleted file mode 100644
index 4021879d8..000000000
--- a/azure-pipelines/build.yml
+++ /dev/null
@@ -1,93 +0,0 @@
-parameters:
-- name: windowsPool
- type: object
- default:
- vmImage: windows-2022
-- name: includeMacOS
-- name: RunTests
- type: boolean
- default: true
-
-jobs:
-- job: Windows
- pool: ${{ parameters.windowsPool }}
- steps:
- - checkout: self
- fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
- clean: true
- - template: install-dependencies.yml
-
- - powershell: '& (./azure-pipelines/Get-nbgv.ps1) cloud -c'
- displayName: ⚙ Set build number
-
- - template: dotnet.yml
- parameters:
- RunTests: ${{ parameters.RunTests }}
-
-- job: Linux
- pool:
- vmImage: Ubuntu 20.04
- steps:
- - checkout: self
- fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
- clean: true
- - template: install-dependencies.yml
- - template: dotnet.yml
- parameters:
- RunTests: ${{ parameters.RunTests }}
-
-- job: macOS
- condition: ${{ parameters.includeMacOS }}
- pool:
- vmImage: macOS-12
- steps:
- - checkout: self
- fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
- clean: true
- - template: install-dependencies.yml
- - template: dotnet.yml
- parameters:
- RunTests: ${{ parameters.RunTests }}
-
-# This job ensures that we're running mpc regularly on the generated code that we check in.
-# It also helps exercise mpc so bugs don't go unnoticed.
-- job: codegen_diff
- pool:
- vmImage: ubuntu-22.04
- steps:
- - checkout: self
- clean: true
- - template: install-dependencies.yml
- - pwsh: sandbox/codegen.ps1
- displayName: 🏭 Regenerate checked-in code
- - bash: |
- git add -u . # compare after applying git EOL normalization
- git diff --cached --exit-code --stat \
- || (echo "##[error] found changed files after build. Please run 'sandbox/codegen.ps1'" \
- "and check in all changes" \
- && git diff --cached \
- && exit 1)
- displayName: 🔍 Check for uncommitted changes
-
-- job: WrapUp
- dependsOn:
- - Windows
- - Linux
- - macOS
- pool: ${{ parameters.windowsPool }} # Use Windows agent because PublishSymbols task requires it (https://github.com/microsoft/azure-pipelines-tasks/issues/13821).
- condition: succeededOrFailed()
- steps:
- - checkout: self
- fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
- clean: true
- - template: install-dependencies.yml
- parameters:
- initArgs: -NoRestore
- - template: publish-symbols.yml
- parameters:
- includeMacOS: ${{ parameters.includeMacOS }}
- - ${{ if parameters.RunTests }}:
- - template: publish-codecoverage.yml
- parameters:
- includeMacOS: ${{ parameters.includeMacOS }}
- - template: publish-deployables.yml
diff --git a/azure-pipelines/dotnet-test-cloud.ps1 b/azure-pipelines/dotnet-test-cloud.ps1
deleted file mode 100644
index 13f973cd4..000000000
--- a/azure-pipelines/dotnet-test-cloud.ps1
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env pwsh
-
-<#
-.SYNOPSIS
- Runs tests as they are run in cloud test runs.
-.PARAMETER Configuration
- The configuration within which to run tests
-.PARAMETER Agent
- The name of the agent. This is used in preparing test run titles.
-.PARAMETER PublishResults
- A switch to publish results to Azure Pipelines.
-.PARAMETER x86
- A switch to run the tests in an x86 process.
-.PARAMETER dotnet32
- The path to a 32-bit dotnet executable to use.
-#>
-[CmdletBinding()]
-Param(
- [string]$Configuration='Debug',
- [string]$Agent='Local',
- [switch]$PublishResults,
- [switch]$x86,
- [string]$dotnet32
-)
-
-$RepoRoot = (Resolve-Path "$PSScriptRoot/..").Path
-$ArtifactStagingFolder = & "$PSScriptRoot/Get-ArtifactsStagingDirectory.ps1"
-
-$dotnet = 'dotnet'
-if ($x86) {
- $x86RunTitleSuffix = ", x86"
- if ($dotnet32) {
- $dotnet = $dotnet32
- } else {
- $dotnet32Possibilities = "$PSScriptRoot\../obj/tools/x86/.dotnet/dotnet.exe", "$env:AGENT_TOOLSDIRECTORY/x86/dotnet/dotnet.exe", "${env:ProgramFiles(x86)}\dotnet\dotnet.exe"
- $dotnet32Matches = $dotnet32Possibilities |? { Test-Path $_ }
- if ($dotnet32Matches) {
- $dotnet = Resolve-Path @($dotnet32Matches)[0]
- Write-Host "Running tests using `"$dotnet`"" -ForegroundColor DarkGray
- } else {
- Write-Error "Unable to find 32-bit dotnet.exe"
- return 1
- }
- }
-}
-
-& $dotnet test $RepoRoot `
- --no-build `
- -c $Configuration `
- --filter "TestCategory!=FailsInCloudTest" `
- --collect "Code Coverage;Format=cobertura" `
- --settings "$PSScriptRoot/test.runsettings" `
- --blame-hang-timeout 60s `
- --blame-crash `
- -bl:"$ArtifactStagingFolder/build_logs/test.binlog" `
- --diag "$ArtifactStagingFolder/test_logs/diag.log;TraceLevel=info" `
- --logger trx `
-
-$unknownCounter = 0
-Get-ChildItem -Recurse -Path $RepoRoot\tests\*.trx |% {
- Copy-Item $_ -Destination $ArtifactStagingFolder/test_logs/
-
- if ($PublishResults) {
- $x = [xml](Get-Content -Path $_)
- $runTitle = $null
- if ($x.TestRun.TestDefinitions -and $x.TestRun.TestDefinitions.GetElementsByTagName('UnitTest')) {
- $storage = $x.TestRun.TestDefinitions.GetElementsByTagName('UnitTest')[0].storage -replace '\\','/'
- if ($storage -match '/(?net[^/]+)/(?:(?[^/]+)/)?(?[^/]+)\.dll$') {
- if ($matches.rid) {
- $runTitle = "$($matches.lib) ($($matches.tfm), $($matches.rid), $Agent)"
- } else {
- $runTitle = "$($matches.lib) ($($matches.tfm)$x86RunTitleSuffix, $Agent)"
- }
- }
- }
- if (!$runTitle) {
- $unknownCounter += 1;
- $runTitle = "unknown$unknownCounter ($Agent$x86RunTitleSuffix)";
- }
-
- Write-Host "##vso[results.publish type=VSTest;runTitle=$runTitle;publishRunAttachments=true;resultFiles=$_;failTaskOnFailedTests=true;testRunSystem=VSTS - PTR;]"
- }
-}
diff --git a/azure-pipelines/dotnet.yml b/azure-pipelines/dotnet.yml
deleted file mode 100644
index 79babd4d4..000000000
--- a/azure-pipelines/dotnet.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-parameters:
- RunTests:
-
-steps:
-
-- script: dotnet build -t:build,pack --no-restore -c $(BuildConfiguration) /bl:"$(Build.ArtifactStagingDirectory)/build_logs/build.binlog"
- displayName: 🛠 dotnet build
-
-- powershell: azure-pipelines/dotnet-test-cloud.ps1 -Configuration $(BuildConfiguration) -Agent $(Agent.JobName) -PublishResults
- displayName: 🧪 dotnet test
- condition: and(succeeded(), ${{ parameters.RunTests }})
-
-- powershell: azure-pipelines/variables/_pipelines.ps1
- failOnStderr: true
- displayName: ⚙ Update pipeline variables based on build outputs
- condition: succeededOrFailed()
-
-- powershell: azure-pipelines/artifacts/_pipelines.ps1 -ArtifactNameSuffix "-$(Agent.JobName)" -Verbose
- failOnStderr: true
- displayName: 📢 Publish artifacts
- condition: succeededOrFailed()
-
-- ${{ if and(ne(variables['codecov_token'], ''), parameters.RunTests) }}:
- - powershell: |
- $ArtifactStagingFolder = & "azure-pipelines/Get-ArtifactsStagingDirectory.ps1"
- $CoverageResultsFolder = Join-Path $ArtifactStagingFolder "coverageResults-$(Agent.JobName)"
- azure-pipelines/publish-CodeCov.ps1 -CodeCovToken "$(codecov_token)" -PathToCodeCoverage "$CoverageResultsFolder" -Name "$(Agent.JobName) Coverage Results" -Flags "$(Agent.JobName)Host,$(BuildConfiguration)"
- displayName: 📢 Publish code coverage results to codecov.io
- timeoutInMinutes: 3
- continueOnError: true
diff --git a/azure-pipelines/install-dependencies.yml b/azure-pipelines/install-dependencies.yml
deleted file mode 100644
index 817826689..000000000
--- a/azure-pipelines/install-dependencies.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-parameters:
- initArgs:
-
-steps:
-
-- task: NuGetAuthenticate@1
- displayName: 🔏 Authenticate NuGet feeds
- inputs:
- forceReinstallCredentialProvider: true
-
-- powershell: |
- $AccessToken = '$(System.AccessToken)' # Avoid specifying the access token directly on the init.ps1 command line to avoid it showing up in errors
- .\init.ps1 -AccessToken $AccessToken ${{ parameters['initArgs'] }} -UpgradePrerequisites -NoNuGetCredProvider
- dotnet --info
-
- # Print mono version if it is present.
- if (Get-Command mono -ErrorAction SilentlyContinue) {
- mono --version
- }
- displayName: ⚙ Install prerequisites
-
-- powershell: azure-pipelines/variables/_pipelines.ps1
- failOnStderr: true
- displayName: ⚙ Set pipeline variables based on source
- name: SetPipelineVariables
diff --git a/azure-pipelines/justnugetorg.nuget.config b/azure-pipelines/justnugetorg.nuget.config
deleted file mode 100644
index 765346e53..000000000
--- a/azure-pipelines/justnugetorg.nuget.config
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/azure-pipelines/publish-CodeCov.ps1 b/azure-pipelines/publish-CodeCov.ps1
deleted file mode 100644
index 9926f0188..000000000
--- a/azure-pipelines/publish-CodeCov.ps1
+++ /dev/null
@@ -1,30 +0,0 @@
-<#
-.SYNOPSIS
- Uploads code coverage to codecov.io
-.PARAMETER CodeCovToken
- Code coverage token to use
-.PARAMETER PathToCodeCoverage
- Path to root of code coverage files
-.PARAMETER Name
- Name to upload with codecoverge
-.PARAMETER Flags
- Flags to upload with codecoverge
-#>
-[CmdletBinding()]
-Param (
- [Parameter(Mandatory=$true)]
- [string]$CodeCovToken,
- [Parameter(Mandatory=$true)]
- [string]$PathToCodeCoverage,
- [string]$Name,
- [string]$Flags
-)
-
-$RepoRoot = (Resolve-Path "$PSScriptRoot/..").Path
-
-Get-ChildItem -Recurse -Path $PathToCodeCoverage -Filter "*.cobertura.xml" | % {
- $relativeFilePath = Resolve-Path -relative $_.FullName
-
- Write-Host "Uploading: $relativeFilePath" -ForegroundColor Yellow
- & (& "$PSScriptRoot/Get-CodeCovTool.ps1") -t $CodeCovToken -f $relativeFilePath -R $RepoRoot -F $Flags -n $Name
-}
diff --git a/azure-pipelines/publish-codecoverage.yml b/azure-pipelines/publish-codecoverage.yml
deleted file mode 100644
index fbb6a39a7..000000000
--- a/azure-pipelines/publish-codecoverage.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-parameters:
- includeMacOS:
-
-steps:
-- download: current
- artifact: coverageResults-Windows
- displayName: 🔻 Download Windows code coverage results
- continueOnError: true
-- download: current
- artifact: coverageResults-Linux
- displayName: 🔻 Download Linux code coverage results
- continueOnError: true
-- download: current
- artifact: coverageResults-macOS
- displayName: 🔻 Download macOS code coverage results
- continueOnError: true
- condition: and(succeeded(), ${{ parameters.includeMacOS }})
-- powershell: azure-pipelines/Merge-CodeCoverage.ps1 -Path '$(Pipeline.Workspace)' -OutputFile coveragereport/merged.cobertura.xml -Format Cobertura -Verbose
- displayName: ⚙ Merge coverage
-- task: PublishCodeCoverageResults@1
- displayName: 📢 Publish code coverage results to Azure DevOps
- inputs:
- codeCoverageTool: cobertura
- summaryFileLocation: coveragereport/merged.cobertura.xml
- failIfCoverageEmpty: true
diff --git a/azure-pipelines/publish-deployables.yml b/azure-pipelines/publish-deployables.yml
deleted file mode 100644
index 31e80a437..000000000
--- a/azure-pipelines/publish-deployables.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-steps:
-- download: current
- displayName: 🔻 Download deployables
- artifact: deployables-Windows
-
-- powershell: dotnet nuget push "$(Resolve-Path '$(Pipeline.Workspace)\deployables-Windows\')*.nupkg" -s $(ci_feed) -k azdo --skip-duplicate
- displayName: 📦 Push packages to CI feed
- condition: and(succeeded(), ne(variables['ci_feed'], ''), ne(variables['Build.Reason'], 'PullRequest'))
diff --git a/azure-pipelines/publish-symbols.yml b/azure-pipelines/publish-symbols.yml
deleted file mode 100644
index 00c188fc3..000000000
--- a/azure-pipelines/publish-symbols.yml
+++ /dev/null
@@ -1,59 +0,0 @@
-parameters:
- includeMacOS:
-
-steps:
-- task: DownloadPipelineArtifact@2
- inputs:
- artifact: symbols-Windows
- path: $(Pipeline.Workspace)/symbols/Windows
- displayName: 🔻 Download Windows symbols
- continueOnError: true
-- task: DownloadPipelineArtifact@2
- inputs:
- artifact: symbols-Linux
- path: $(Pipeline.Workspace)/symbols/Linux
- displayName: 🔻 Download Linux symbols
- continueOnError: true
-- task: DownloadPipelineArtifact@2
- inputs:
- artifact: symbols-macOS
- path: $(Pipeline.Workspace)/symbols/macOS
- displayName: 🔻 Download macOS symbols
- continueOnError: true
- condition: ${{ parameters.includeMacOS }}
-
-- task: DownloadPipelineArtifact@2
- inputs:
- artifact: test_symbols-Windows
- path: $(Pipeline.Workspace)/test_symbols/Windows
- displayName: 🔻 Download Windows test symbols
- continueOnError: true
-- task: DownloadPipelineArtifact@2
- inputs:
- artifact: test_symbols-Linux
- path: $(Pipeline.Workspace)/test_symbols/Linux
- displayName: 🔻 Download Linux test symbols
- continueOnError: true
-- task: DownloadPipelineArtifact@2
- inputs:
- artifact: test_symbols-macOS
- path: $(Pipeline.Workspace)/test_symbols/macOS
- displayName: 🔻 Download macOS test symbols
- continueOnError: true
- condition: ${{ parameters.includeMacOS }}
-
-- task: PublishSymbols@2
- inputs:
- SymbolsFolder: $(Pipeline.Workspace)/symbols
- SearchPattern: '**/*.pdb'
- IndexSources: false
- SymbolServerType: TeamServices
- displayName: 📢 Publish symbols
-
-- task: PublishSymbols@2
- inputs:
- SymbolsFolder: $(Pipeline.Workspace)/test_symbols
- SearchPattern: '**/*.pdb'
- IndexSources: false
- SymbolServerType: TeamServices
- displayName: 📢 Publish test symbols
diff --git a/azure-pipelines/release.yml b/azure-pipelines/release.yml
deleted file mode 100644
index be5c4f614..000000000
--- a/azure-pipelines/release.yml
+++ /dev/null
@@ -1,62 +0,0 @@
-trigger: none # We only want to trigger manually or based on resources
-pr: none
-
-resources:
- pipelines:
- - pipeline: CI
- source: MessagePack-CSharp-CI
- trigger:
- tags:
- - auto-release
-
-variables:
-- group: Publishing secrets
-
-jobs:
-- job: release
- pool:
- vmImage: ubuntu-latest
- steps:
- - checkout: none
- - powershell: |
- Write-Host "##vso[build.updatebuildnumber]$(resources.pipeline.CI.runName)"
- if ('$(resources.pipeline.CI.runName)'.Contains('-')) {
- Write-Host "##vso[task.setvariable variable=IsPrerelease]true"
- } else {
- Write-Host "##vso[task.setvariable variable=IsPrerelease]false"
- }
- displayName: ⚙ Set up pipeline
- - task: UseDotNet@2
- displayName: ⚙ Install .NET SDK
- inputs:
- packageType: sdk
- version: 6.x
- - download: CI
- artifact: deployables-Windows
- displayName: 🔻 Download deployables-Windows artifact
- patterns: 'deployables-Windows/*'
- - task: GitHubRelease@1
- displayName: 📢 GitHub release (create)
- inputs:
- gitHubConnection: AArnott github
- repositoryName: $(Build.Repository.Name)
- target: $(resources.pipeline.CI.sourceCommit)
- tagSource: userSpecifiedTag
- tag: v$(resources.pipeline.CI.runName)
- title: v$(resources.pipeline.CI.runName)
- isDraft: true # After running this step, visit the new draft release, edit, and publish.
- isPreRelease: $(IsPrerelease)
- assets: |
- $(Pipeline.Workspace)/CI/deployables-Windows/*.nupkg
- $(Pipeline.Workspace)/CI/unity/*.unitypackage
- changeLogCompareToRelease: lastNonDraftRelease
- changeLogType: issueBased
- changeLogLabels: |
- [
- { "label" : "breaking change", "displayName" : "Breaking changes", "state" : "closed" },
- { "label" : "bug", "displayName" : "Fixes", "state" : "closed" },
- { "label" : "enhancement", "displayName": "Enhancements", "state" : "closed" }
- ]
- - script: dotnet nuget push $(Pipeline.Workspace)/CI/deployables-Windows/*.nupkg -s https://api.nuget.org/v3/index.json --api-key $(NuGetOrgApiKey) --skip-duplicate
- displayName: 📦 Push packages to nuget.org
- condition: and(succeeded(), ne(variables['NuGetOrgApiKey'], ''))
diff --git a/azure-pipelines/test.runsettings b/azure-pipelines/test.runsettings
deleted file mode 100644
index 4e24a0a65..000000000
--- a/azure-pipelines/test.runsettings
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
-
-
-
- \.dll$
- \.exe$
-
-
- xunit\..*
-
-
-
-
- ^System\.Diagnostics\.DebuggerHiddenAttribute$
- ^System\.Diagnostics\.DebuggerNonUserCodeAttribute$
- ^System\.CodeDom\.Compiler\.GeneratedCodeAttribute$
- ^System\.Diagnostics\.CodeAnalysis\.ExcludeFromCodeCoverageAttribute$
-
-
-
-
- True
-
- True
-
- True
-
- False
-
- False
-
- False
-
- True
-
-
-
-
-
-
diff --git a/azure-pipelines/variables/DotNetSdkVersion.ps1 b/azure-pipelines/variables/DotNetSdkVersion.ps1
deleted file mode 100644
index b213fbc27..000000000
--- a/azure-pipelines/variables/DotNetSdkVersion.ps1
+++ /dev/null
@@ -1,2 +0,0 @@
-$globalJson = Get-Content -Path "$PSScriptRoot\..\..\global.json" | ConvertFrom-Json
-$globalJson.sdk.version
diff --git a/azure-pipelines/variables/_all.ps1 b/azure-pipelines/variables/_all.ps1
deleted file mode 100755
index cc6e88105..000000000
--- a/azure-pipelines/variables/_all.ps1
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env pwsh
-
-<#
-.SYNOPSIS
- This script returns a hashtable of build variables that should be set
- at the start of a build or release definition's execution.
-#>
-
-[CmdletBinding(SupportsShouldProcess = $true)]
-param (
-)
-
-$vars = @{}
-
-Get-ChildItem "$PSScriptRoot\*.ps1" -Exclude "_*" |% {
- Write-Host "Computing $($_.BaseName) variable"
- $vars[$_.BaseName] = & $_
-}
-
-$vars
diff --git a/azure-pipelines/variables/_pipelines.ps1 b/azure-pipelines/variables/_pipelines.ps1
deleted file mode 100644
index 11748b81b..000000000
--- a/azure-pipelines/variables/_pipelines.ps1
+++ /dev/null
@@ -1,31 +0,0 @@
-<#
-.SYNOPSIS
- This script translates the variables returned by the _all.ps1 script
- into commands that instruct Azure Pipelines to actually set those variables for other pipeline tasks to consume.
-
- The build or release definition may have set these variables to override
- what the build would do. So only set them if they have not already been set.
-#>
-
-[CmdletBinding()]
-param (
-)
-
-(& "$PSScriptRoot\_all.ps1").GetEnumerator() |% {
- # Always use ALL CAPS for env var names since Azure Pipelines converts variable names to all caps and on non-Windows OS, env vars are case sensitive.
- $keyCaps = $_.Key.ToUpper()
- if ((Test-Path "env:$keyCaps") -and (Get-Content "env:$keyCaps")) {
- Write-Host "Skipping setting $keyCaps because variable is already set to '$(Get-Content env:$keyCaps)'." -ForegroundColor Cyan
- } else {
- Write-Host "$keyCaps=$($_.Value)" -ForegroundColor Yellow
- if ($env:TF_BUILD) {
- # Create two variables: the first that can be used by its simple name and accessible only within this job.
- Write-Host "##vso[task.setvariable variable=$keyCaps]$($_.Value)"
- # and the second that works across jobs and stages but must be fully qualified when referenced.
- Write-Host "##vso[task.setvariable variable=$keyCaps;isOutput=true]$($_.Value)"
- } elseif ($env:GITHUB_ACTIONS) {
- Add-Content -Path $env:GITHUB_ENV -Value "$keyCaps=$($_.Value)"
- }
- Set-Item -Path "env:$keyCaps" -Value $_.Value
- }
-}
diff --git a/benchmark/CollectionsMarshalBenchmark/CollectionsMarshalBenchmark.csproj b/benchmark/CollectionsMarshalBenchmark/CollectionsMarshalBenchmark.csproj
new file mode 100644
index 000000000..3d1ccb4be
--- /dev/null
+++ b/benchmark/CollectionsMarshalBenchmark/CollectionsMarshalBenchmark.csproj
@@ -0,0 +1,22 @@
+
+
+
+ Exe
+ net8.0
+ Benchmark
+ enable
+ true
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/benchmark/CollectionsMarshalBenchmark/OldListFormatter`1.cs b/benchmark/CollectionsMarshalBenchmark/OldListFormatter`1.cs
new file mode 100644
index 000000000..2d706c7fc
--- /dev/null
+++ b/benchmark/CollectionsMarshalBenchmark/OldListFormatter`1.cs
@@ -0,0 +1,67 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Buffers;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+namespace MessagePack.Formatters;
+
+public sealed class OldListFormatter
+ : IMessagePackFormatter?>
+{
+ public void Serialize(ref MessagePackWriter writer, List? value, MessagePackSerializerOptions options)
+ {
+ if (value == null)
+ {
+ writer.WriteNil();
+ }
+ else
+ {
+ IMessagePackFormatter formatter = options.Resolver.GetFormatterWithVerify();
+
+ var c = value.Count;
+ writer.WriteArrayHeader(c);
+ for (int i = 0; i < c; i++)
+ {
+ writer.CancellationToken.ThrowIfCancellationRequested();
+ formatter.Serialize(ref writer, value[i], options);
+ }
+ }
+ }
+
+ public List? Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
+ {
+ if (reader.TryReadNil())
+ {
+ return default;
+ }
+ else
+ {
+ IMessagePackFormatter formatter = options.Resolver.GetFormatterWithVerify();
+
+ var len = reader.ReadArrayHeader();
+ var list = new List((int)len);
+ options.Security.DepthStep(ref reader);
+ try
+ {
+ for (int i = 0; i < len; i++)
+ {
+ reader.CancellationToken.ThrowIfCancellationRequested();
+ list.Add(formatter.Deserialize(ref reader, options));
+ }
+ }
+ finally
+ {
+ reader.Depth--;
+ }
+
+ return list;
+ }
+ }
+}
diff --git a/benchmark/CollectionsMarshalBenchmark/Program.cs b/benchmark/CollectionsMarshalBenchmark/Program.cs
new file mode 100644
index 000000000..ed60f5337
--- /dev/null
+++ b/benchmark/CollectionsMarshalBenchmark/Program.cs
@@ -0,0 +1,16 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using Benchmark;
+using BenchmarkDotNet.Running;
+
+namespace CollectionsMarshalBenchmark;
+
+internal class Program
+{
+ private static void Main()
+ {
+ BenchmarkRunner.Run();
+ BenchmarkRunner.Run();
+ }
+}
diff --git a/benchmark/CollectionsMarshalBenchmark/RandomByteBenchmark.cs b/benchmark/CollectionsMarshalBenchmark/RandomByteBenchmark.cs
new file mode 100644
index 000000000..9b16526e0
--- /dev/null
+++ b/benchmark/CollectionsMarshalBenchmark/RandomByteBenchmark.cs
@@ -0,0 +1,86 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using BenchmarkDotNet.Attributes;
+using MessagePack;
+using MessagePack.Formatters;
+
+#pragma warning disable SA1402 // File may only contain a single type
+#pragma warning disable SA1649 // File name should match first type name
+
+namespace Benchmark;
+
+[MessagePackObject]
+public struct OldTypeByte(List value)
+{
+ public OldTypeByte()
+ : this([])
+ {
+ }
+
+ [Key(0)]
+ [MessagePackFormatter(typeof(OldListFormatter))]
+ public List Value = value;
+}
+
+[MessagePackObject]
+public struct NewTypeByte(List value)
+{
+ public NewTypeByte()
+ : this([])
+ {
+ }
+
+ [Key(0)]
+ [MessagePackFormatter(typeof(ListFormatter))]
+ public List Value = value;
+}
+
+public class RandomByteBenchmark
+{
+ [Params(1, 64, 1024, 16 * 1024 * 1024)]
+ public int Size { get; set; }
+
+ private List input = [];
+ private byte[] serialized = [];
+
+ [GlobalSetup]
+ public void SetUp()
+ {
+ input = new(Size);
+ for (var i = 0; i < Size; i++)
+ {
+ input.Add((byte)Random.Shared.Next());
+ }
+
+ serialized = MessagePackSerializer.Serialize(new NewTypeByte(input));
+ }
+
+ [Benchmark]
+ public byte[] SerializeNew()
+ {
+ return MessagePackSerializer.Serialize(new NewTypeByte(input));
+ }
+
+ [Benchmark]
+ public byte[] SerializeOld()
+ {
+ return MessagePackSerializer.Serialize(new OldTypeByte(input));
+ }
+
+ [Benchmark]
+ public List DeserializeNew()
+ {
+ return MessagePackSerializer.Deserialize(serialized).Value;
+ }
+
+ [Benchmark]
+ public List DeserializeOld()
+ {
+ return MessagePackSerializer.Deserialize(serialized).Value;
+ }
+}
diff --git a/benchmark/CollectionsMarshalBenchmark/RandomMatrix4x4Benchmark.cs b/benchmark/CollectionsMarshalBenchmark/RandomMatrix4x4Benchmark.cs
new file mode 100644
index 000000000..754637bf9
--- /dev/null
+++ b/benchmark/CollectionsMarshalBenchmark/RandomMatrix4x4Benchmark.cs
@@ -0,0 +1,128 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using BenchmarkDotNet.Attributes;
+using MessagePack;
+using MessagePack.Formatters;
+
+#pragma warning disable SA1402 // File may only contain a single type
+#pragma warning disable SA1649 // File name should match first type name
+
+namespace Benchmark;
+
+[MessagePack.MessagePackObjectAttribute]
+public struct Matrix4x4
+{
+ [MessagePack.Key(0)] public float M11;
+ [MessagePack.Key(1)] public float M12;
+ [MessagePack.Key(2)] public float M13;
+ [MessagePack.Key(3)] public float M14;
+ [MessagePack.Key(4)] public float M21;
+ [MessagePack.Key(5)] public float M22;
+ [MessagePack.Key(6)] public float M23;
+ [MessagePack.Key(7)] public float M24;
+ [MessagePack.Key(8)] public float M31;
+ [MessagePack.Key(9)] public float M32;
+ [MessagePack.Key(10)] public float M33;
+ [MessagePack.Key(11)] public float M34;
+ [MessagePack.Key(12)] public float M41;
+ [MessagePack.Key(13)] public float M42;
+ [MessagePack.Key(14)] public float M43;
+ [MessagePack.Key(15)] public float M44;
+
+ public Matrix4x4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
+ {
+ M11 = m11;
+ M12 = m12;
+ M13 = m13;
+ M14 = m14;
+ M21 = m21;
+ M22 = m22;
+ M23 = m23;
+ M24 = m24;
+ M31 = m31;
+ M32 = m32;
+ M33 = m33;
+ M34 = m34;
+ M41 = m41;
+ M42 = m42;
+ M43 = m43;
+ M44 = m44;
+ }
+}
+
+[MessagePackObject]
+public struct OldTypeMatrix4x4(List value)
+{
+ public OldTypeMatrix4x4()
+ : this([])
+ {
+ }
+
+ [Key(0)]
+ [MessagePackFormatter(typeof(OldListFormatter))]
+ public List Value = value;
+}
+
+[MessagePackObject]
+public struct NewTypeMatrix4x4(List value)
+{
+ public NewTypeMatrix4x4()
+ : this([])
+ {
+ }
+
+ [Key(0)]
+ [MessagePackFormatter(typeof(ListFormatter))]
+ public List Value = value;
+}
+
+public class RandomMatrix4x4Benchmark
+{
+ [Params(1, 64, 1024, 16 * 1024 * 1024)]
+ public int Size { get; set; }
+
+ private List input = [];
+ private byte[] serialized = [];
+
+ [GlobalSetup]
+ public void SetUp()
+ {
+ input = new(Size);
+ var r = new Random();
+ for (var i = 0; i < Size; i++)
+ {
+ input.Add(new((float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble()));
+ }
+
+ serialized = MessagePackSerializer.Serialize(new NewTypeMatrix4x4(input));
+ }
+
+ [Benchmark]
+ public byte[] SerializeNew()
+ {
+ return MessagePackSerializer.Serialize(new NewTypeMatrix4x4(input));
+ }
+
+ [Benchmark]
+ public byte[] SerializeOld()
+ {
+ return MessagePackSerializer.Serialize(new OldTypeMatrix4x4(input));
+ }
+
+ [Benchmark]
+ public List DeserializeNew()
+ {
+ return MessagePackSerializer.Deserialize(serialized).Value;
+ }
+
+ [Benchmark]
+ public List DeserializeOld()
+ {
+ return MessagePackSerializer.Deserialize(serialized).Value;
+ }
+}
diff --git a/benchmark/ExperimentalBenchmark/BoolDeserializeTest.cs b/benchmark/ExperimentalBenchmark/BoolDeserializeTest.cs
new file mode 100644
index 000000000..68365844c
--- /dev/null
+++ b/benchmark/ExperimentalBenchmark/BoolDeserializeTest.cs
@@ -0,0 +1,76 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+extern alias e;
+
+namespace Benchmark;
+
+public class BoolDeserializeTest
+{
+#pragma warning disable SA1117
+ [Params(
+ "0",
+ "1 true", "1 false", "1 rand",
+ "3 true", "3 false", "3 rand",
+ "8 rand",
+ "16 rand",
+ "31 rand",
+ "64 rand",
+ "4096 rand",
+ "4194304 rand")]
+ public string Setting { get; set; } = string.Empty;
+#pragma warning restore SA1117
+
+ private byte[] binary = [];
+
+ [GlobalSetup]
+ public void SetUp()
+ {
+ var span = Setting.AsSpan();
+ var firstSpace = span.IndexOf(' ');
+ var sizeSpan = span;
+ if (firstSpace >= 0)
+ {
+ sizeSpan = sizeSpan[..firstSpace];
+ }
+
+ var size = int.Parse(sizeSpan);
+ var input = size == 0 ? [] : new bool[size];
+ if (input.Length != 0)
+ {
+ span = span[(firstSpace + 1)..];
+ switch (span)
+ {
+ case "true":
+ Array.Fill(input, true);
+ break;
+ case "false":
+ Array.Fill(input, false);
+ break;
+ default:
+ foreach (ref var item in input.AsSpan())
+ {
+ item = (Random.Shared.Next() & 1) == 0;
+ }
+
+ break;
+ }
+ }
+
+ binary = MessagePackSerializer.Serialize(input);
+ }
+
+ [Benchmark(Baseline = true)]
+ public bool[]? Old()
+ {
+ MessagePackReader reader = new(binary);
+ return BooleanArrayFormatter.Instance.Deserialize(ref reader, default!);
+ }
+
+ [Benchmark]
+ public bool[]? Simd()
+ {
+ MessagePackReader reader = new(binary);
+ return e::MessagePack.Formatters.BooleanArrayFormatter.Instance.Deserialize(ref reader, default!);
+ }
+}
diff --git a/benchmark/ExperimentalBenchmark/BoolSerializeTest.cs b/benchmark/ExperimentalBenchmark/BoolSerializeTest.cs
new file mode 100644
index 000000000..bdf779971
--- /dev/null
+++ b/benchmark/ExperimentalBenchmark/BoolSerializeTest.cs
@@ -0,0 +1,82 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+extern alias e;
+
+namespace Benchmark;
+
+public class BoolSerializeTest
+{
+#pragma warning disable SA1117
+ [Params(
+ "0",
+ "1 true", "1 false", "1 rand",
+ "3 true", "3 false", "3 rand",
+ "8 rand",
+ "16 rand",
+ "31 rand",
+ "64 rand",
+ "4096 rand",
+ "4194304 rand")]
+ public string Setting { get; set; } = string.Empty;
+#pragma warning restore SA1117
+
+ private bool[] input = [];
+
+ [GlobalSetup]
+ public void SetUp()
+ {
+ var span = Setting.AsSpan();
+ var firstSpace = span.IndexOf(' ');
+ var sizeSpan = span;
+ if (firstSpace >= 0)
+ {
+ sizeSpan = sizeSpan[..firstSpace];
+ }
+
+ var size = int.Parse(sizeSpan);
+ input = size == 0 ? [] : new bool[size];
+ if (input.Length == 0)
+ {
+ return;
+ }
+
+ span = span[(firstSpace + 1)..];
+ switch (span)
+ {
+ case "true":
+ Array.Fill(input, true);
+ break;
+ case "false":
+ Array.Fill(input, false);
+ break;
+ default:
+ foreach (ref var item in input.AsSpan())
+ {
+ item = (Random.Shared.Next() & 1) == 0;
+ }
+
+ break;
+ }
+ }
+
+ [Benchmark(Baseline = true)]
+ public ReadOnlyMemory Old()
+ {
+ ArrayBufferWriter bufferWriter = new();
+ MessagePackWriter writer = new(bufferWriter);
+ BooleanArrayFormatter.Instance.Serialize(ref writer, input, default!);
+ writer.Flush();
+ return bufferWriter.WrittenMemory;
+ }
+
+ [Benchmark]
+ public ReadOnlyMemory Simd()
+ {
+ ArrayBufferWriter bufferWriter = new();
+ MessagePackWriter writer = new(bufferWriter);
+ e::MessagePack.Formatters.BooleanArrayFormatter.Instance.Serialize(ref writer, input, default!);
+ writer.Flush();
+ return bufferWriter.WrittenMemory;
+ }
+}
diff --git a/benchmark/ExperimentalBenchmark/DoubleTest.cs b/benchmark/ExperimentalBenchmark/DoubleTest.cs
new file mode 100644
index 000000000..5bede4035
--- /dev/null
+++ b/benchmark/ExperimentalBenchmark/DoubleTest.cs
@@ -0,0 +1,44 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+extern alias e;
+
+namespace Benchmark;
+
+public class DoubleTest
+{
+ [Params(0, 1, 3, 8, 31, 64, 1024, 16777216)]
+ public int Size { get; set; }
+
+ private double[] input = [];
+
+ [GlobalSetup]
+ public void SetUp()
+ {
+ input = new double[Size];
+ for (var i = 0; i < input.Length; i++)
+ {
+ input[i] = Random.Shared.NextDouble();
+ }
+ }
+
+ [Benchmark(Baseline = true)]
+ public ReadOnlyMemory Old()
+ {
+ ArrayBufferWriter bufferWriter = new();
+ MessagePackWriter writer = new(bufferWriter);
+ DoubleArrayFormatter.Instance.Serialize(ref writer, input, default!);
+ writer.Flush();
+ return bufferWriter.WrittenMemory;
+ }
+
+ [Benchmark]
+ public ReadOnlyMemory Simd()
+ {
+ ArrayBufferWriter bufferWriter = new();
+ MessagePackWriter writer = new(bufferWriter);
+ e::MessagePack.Formatters.DoubleArrayFormatter.Instance.Serialize(ref writer, input, default!);
+ writer.Flush();
+ return bufferWriter.WrittenMemory;
+ }
+}
diff --git a/benchmark/ExperimentalBenchmark/ExperimentalBenchmark.csproj b/benchmark/ExperimentalBenchmark/ExperimentalBenchmark.csproj
index 08cce028b..2bd081277 100644
--- a/benchmark/ExperimentalBenchmark/ExperimentalBenchmark.csproj
+++ b/benchmark/ExperimentalBenchmark/ExperimentalBenchmark.csproj
@@ -1,11 +1,12 @@
-
+
Exe
- net6.0
+ net8.0
Benchmark
true
$(NoWarn);MSB3243
+ enable
@@ -15,23 +16,19 @@
- newmsgpack
-
-
- newmsgpack
-
-
- newmsgpack
+ e
+
+
-
- MessagePack_2_1_165.dll
- oldmsgpack
- true
- false
-
+
+
+
+
+
+
diff --git a/benchmark/ExperimentalBenchmark/IntTest.cs b/benchmark/ExperimentalBenchmark/IntTest.cs
new file mode 100644
index 000000000..4b21f08d7
--- /dev/null
+++ b/benchmark/ExperimentalBenchmark/IntTest.cs
@@ -0,0 +1,75 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+extern alias e;
+
+namespace Benchmark;
+
+public class IntTest
+{
+#pragma warning disable SA1117
+ [Params(
+ "0",
+ "1 rand", "1 0",
+ "3 rand", "3 0",
+ "8 rand", "8 0",
+ "16 rand", "16 0",
+ "31 rand", "31 0",
+ "64 rand", "64 0",
+ "4096 rand", "4096 0",
+ "4194304 rand", "4194304 0")]
+ public string Setting { get; set; } = string.Empty;
+#pragma warning restore SA1117
+
+ private int[] input = [];
+
+ [GlobalSetup]
+ public void SetUp()
+ {
+ var span = Setting.AsSpan();
+ var firstSpace = span.IndexOf(' ');
+ var sizeSpan = span;
+ if (firstSpace >= 0)
+ {
+ sizeSpan = sizeSpan[..firstSpace];
+ }
+
+ var size = int.Parse(sizeSpan);
+ input = size == 0 ? [] : new int[size];
+ if (input.Length == 0)
+ {
+ return;
+ }
+
+ span = span[(firstSpace + 1)..];
+ switch (span)
+ {
+ case "rand":
+ Random.Shared.NextBytes(MemoryMarshal.AsBytes(input.AsSpan()));
+ break;
+ default:
+ Array.Fill(input, int.Parse(span));
+ break;
+ }
+ }
+
+ [Benchmark(Baseline = true)]
+ public ReadOnlyMemory Old()
+ {
+ ArrayBufferWriter bufferWriter = new();
+ MessagePackWriter writer = new(bufferWriter);
+ Int32ArrayFormatter.Instance.Serialize(ref writer, input, default!);
+ writer.Flush();
+ return bufferWriter.WrittenMemory;
+ }
+
+ [Benchmark]
+ public ReadOnlyMemory Simd()
+ {
+ ArrayBufferWriter bufferWriter = new();
+ MessagePackWriter writer = new(bufferWriter);
+ e::MessagePack.Formatters.Int32ArrayFormatter.Instance.Serialize(ref writer, input, default!);
+ writer.Flush();
+ return bufferWriter.WrittenMemory;
+ }
+}
diff --git a/benchmark/ExperimentalBenchmark/MessagePack_2_1_165.dll b/benchmark/ExperimentalBenchmark/MessagePack_2_1_165.dll
deleted file mode 100644
index 7dabd586c..000000000
Binary files a/benchmark/ExperimentalBenchmark/MessagePack_2_1_165.dll and /dev/null differ
diff --git a/benchmark/ExperimentalBenchmark/Program.cs b/benchmark/ExperimentalBenchmark/Program.cs
index 6e3e18511..7e667e8ad 100644
--- a/benchmark/ExperimentalBenchmark/Program.cs
+++ b/benchmark/ExperimentalBenchmark/Program.cs
@@ -1,22 +1,41 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-using Benchmark;
+#if NET7_0_OR_GREATER
+using System.Runtime.Intrinsics;
+#else
+using System.Runtime.Intrinsics.Arm;
+using System.Runtime.Intrinsics.X86;
+#endif
+using BenchmarkDotNet.Columns;
+using BenchmarkDotNet.Configs;
+using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
-namespace HardwareIntrinsicsBenchmark
+namespace Benchmark;
+
+internal class Program
{
- internal class Program
+ private static void Main(string[] args)
{
- private static void Main()
+ var noDynamicPGO = new EnvironmentVariable("DOTNET_TieredPGO", "0");
+ IConfig config = DefaultConfig.Instance
+ .HideColumns(Column.EnvironmentVariables, Column.RatioSD, Column.Error)
+ .AddJob(Job.Default.WithEnvironmentVariables([
+ new("DOTNET_EnableHWIntrinsic", "0"),
+ noDynamicPGO
+ ]).WithId("Scalar").AsBaseline());
+
+#if NET7_0_OR_GREATER
+ if (Vector128.IsHardwareAccelerated)
+#else
+ if (Sse42.IsSupported || AdvSimd.IsSupported)
+#endif
{
- BenchmarkRunner.Run();
- BenchmarkRunner.Run();
- BenchmarkRunner.Run();
- BenchmarkRunner.Run();
- BenchmarkRunner.Run();
- BenchmarkRunner.Run();
- BenchmarkRunner.Run();
+ config = config.AddJob(Job.Default.WithEnvironmentVariable(noDynamicPGO).WithId("Vector"));
}
+
+ BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly)
+ .Run(args, config);
}
}
diff --git a/benchmark/ExperimentalBenchmark/SByteTest.cs b/benchmark/ExperimentalBenchmark/SByteTest.cs
new file mode 100644
index 000000000..4d60f6fad
--- /dev/null
+++ b/benchmark/ExperimentalBenchmark/SByteTest.cs
@@ -0,0 +1,75 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+extern alias e;
+
+namespace Benchmark;
+
+public class SByteTest
+{
+#pragma warning disable SA1117
+ [Params(
+ "0",
+ "1 rand", "1 127", "1 -35",
+ "3 rand", "3 127", "3 -35",
+ "8 rand", "8 127", "8 -35",
+ "16 rand", "16 127", "16 -35",
+ "31 rand", "31 127", "31 -35",
+ "64 rand", "64 127", "64 -35",
+ "4096 rand", "4096 127", "4096 -35",
+ "4194304 rand", "4194304 127", "4194304 -35")]
+ public string Setting { get; set; } = string.Empty;
+#pragma warning restore SA1117
+
+ private sbyte[] input = [];
+
+ [GlobalSetup]
+ public void SetUp()
+ {
+ var span = Setting.AsSpan();
+ var firstSpace = span.IndexOf(' ');
+ var sizeSpan = span;
+ if (firstSpace >= 0)
+ {
+ sizeSpan = sizeSpan[..firstSpace];
+ }
+
+ var size = int.Parse(sizeSpan);
+ input = size == 0 ? [] : new sbyte[size];
+ if (input.Length == 0)
+ {
+ return;
+ }
+
+ span = span[(firstSpace + 1)..];
+ switch (span)
+ {
+ case "rand":
+ Random.Shared.NextBytes(MemoryMarshal.AsBytes(input.AsSpan()));
+ break;
+ default:
+ Array.Fill(input, sbyte.Parse(span));
+ break;
+ }
+ }
+
+ [Benchmark(Baseline = true)]
+ public ReadOnlyMemory Old()
+ {
+ ArrayBufferWriter bufferWriter = new();
+ MessagePackWriter writer = new(bufferWriter);
+ SByteArrayFormatter.Instance.Serialize(ref writer, input, default!);
+ writer.Flush();
+ return bufferWriter.WrittenMemory;
+ }
+
+ [Benchmark]
+ public ReadOnlyMemory Simd()
+ {
+ ArrayBufferWriter bufferWriter = new();
+ MessagePackWriter writer = new(bufferWriter);
+ e::MessagePack.Formatters.SByteArrayFormatter.Instance.Serialize(ref writer, input, default!);
+ writer.Flush();
+ return bufferWriter.WrittenMemory;
+ }
+}
diff --git a/benchmark/ExperimentalBenchmark/ShortTest.cs b/benchmark/ExperimentalBenchmark/ShortTest.cs
new file mode 100644
index 000000000..4b2fa8300
--- /dev/null
+++ b/benchmark/ExperimentalBenchmark/ShortTest.cs
@@ -0,0 +1,75 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+extern alias e;
+
+namespace Benchmark;
+
+public class ShortTest
+{
+#pragma warning disable SA1117
+ [Params(
+ "0",
+ "1 rand", "1 127", "1 -135",
+ "3 rand", "3 127", "3 -135",
+ "8 rand", "8 127", "8 -135",
+ "16 rand", "16 127", "16 -135",
+ "31 rand", "31 127", "31 -135",
+ "64 rand", "64 127", "64 -135",
+ "4096 rand", "4096 127", "4096 -135",
+ "4194304 rand", "4194304 127", "4194304 -135")]
+ public string Setting { get; set; } = string.Empty;
+#pragma warning restore SA1117
+
+ private short[] input = [];
+
+ [GlobalSetup]
+ public void SetUp()
+ {
+ var span = Setting.AsSpan();
+ var firstSpace = span.IndexOf(' ');
+ var sizeSpan = span;
+ if (firstSpace >= 0)
+ {
+ sizeSpan = sizeSpan[..firstSpace];
+ }
+
+ var size = int.Parse(sizeSpan);
+ input = size == 0 ? [] : new short[size];
+ if (input.Length == 0)
+ {
+ return;
+ }
+
+ span = span[(firstSpace + 1)..];
+ switch (span)
+ {
+ case "rand":
+ Random.Shared.NextBytes(MemoryMarshal.AsBytes(input.AsSpan()));
+ break;
+ default:
+ Array.Fill(input, short.Parse(span));
+ break;
+ }
+ }
+
+ [Benchmark(Baseline = true)]
+ public ReadOnlyMemory Old()
+ {
+ ArrayBufferWriter bufferWriter = new();
+ MessagePackWriter writer = new(bufferWriter);
+ Int16ArrayFormatter.Instance.Serialize(ref writer, input, default!);
+ writer.Flush();
+ return bufferWriter.WrittenMemory;
+ }
+
+ [Benchmark]
+ public ReadOnlyMemory Simd()
+ {
+ ArrayBufferWriter bufferWriter = new();
+ MessagePackWriter writer = new(bufferWriter);
+ e::MessagePack.Formatters.Int16ArrayFormatter.Instance.Serialize(ref writer, input, default!);
+ writer.Flush();
+ return bufferWriter.WrittenMemory;
+ }
+}
diff --git a/benchmark/ExperimentalBenchmark/SingleTest.cs b/benchmark/ExperimentalBenchmark/SingleTest.cs
new file mode 100644
index 000000000..094e111c3
--- /dev/null
+++ b/benchmark/ExperimentalBenchmark/SingleTest.cs
@@ -0,0 +1,44 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+extern alias e;
+
+namespace Benchmark;
+
+public class SingleTest
+{
+ [Params(0, 1, 3, 4, 8, 64, 1024, 16 * 1024 * 1024)]
+ public int Size { get; set; }
+
+ private float[] input = [];
+
+ [GlobalSetup]
+ public void SetUp()
+ {
+ input = new float[Size];
+ for (var i = 0; i < input.Length; i++)
+ {
+ input[i] = Random.Shared.NextSingle();
+ }
+ }
+
+ [Benchmark(Baseline = true)]
+ public ReadOnlyMemory Old()
+ {
+ ArrayBufferWriter bufferWriter = new();
+ MessagePackWriter writer = new(bufferWriter);
+ SingleArrayFormatter.Instance.Serialize(ref writer, input, default!);
+ writer.Flush();
+ return bufferWriter.WrittenMemory;
+ }
+
+ [Benchmark]
+ public ReadOnlyMemory Simd()
+ {
+ ArrayBufferWriter bufferWriter = new();
+ MessagePackWriter writer = new(bufferWriter);
+ e::MessagePack.Formatters.SingleArrayFormatter.Instance.Serialize(ref writer, input, default!);
+ writer.Flush();
+ return bufferWriter.WrittenMemory;
+ }
+}
diff --git a/benchmark/ExperimentalBenchmark/Tests.cs b/benchmark/ExperimentalBenchmark/Tests.cs
deleted file mode 100644
index e51837b1b..000000000
--- a/benchmark/ExperimentalBenchmark/Tests.cs
+++ /dev/null
@@ -1,487 +0,0 @@
-// Copyright (c) All contributors. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-extern alias oldmsgpack;
-extern alias newmsgpack;
-
-using System;
-using System.Linq;
-using System.Runtime.InteropServices;
-using BenchmarkDotNet.Attributes;
-
-#pragma warning disable SA1402 // File may only contain a single type
-#pragma warning disable SA1649 // File name should match first type name
-
-namespace Benchmark
-{
- [newmsgpack::MessagePack.MessagePackObjectAttribute]
- public struct Matrix4x4
- {
- [newmsgpack::MessagePack.Key(0)] public float M11;
- [newmsgpack::MessagePack.Key(1)] public float M12;
- [newmsgpack::MessagePack.Key(2)] public float M13;
- [newmsgpack::MessagePack.Key(3)] public float M14;
- [newmsgpack::MessagePack.Key(4)] public float M21;
- [newmsgpack::MessagePack.Key(5)] public float M22;
- [newmsgpack::MessagePack.Key(6)] public float M23;
- [newmsgpack::MessagePack.Key(7)] public float M24;
- [newmsgpack::MessagePack.Key(8)] public float M31;
- [newmsgpack::MessagePack.Key(9)] public float M32;
- [newmsgpack::MessagePack.Key(10)] public float M33;
- [newmsgpack::MessagePack.Key(11)] public float M34;
- [newmsgpack::MessagePack.Key(12)] public float M41;
- [newmsgpack::MessagePack.Key(13)] public float M42;
- [newmsgpack::MessagePack.Key(14)] public float M43;
- [newmsgpack::MessagePack.Key(15)] public float M44;
-
- public Matrix4x4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
- {
- M11 = m11;
- M12 = m12;
- M13 = m13;
- M14 = m14;
- M21 = m21;
- M22 = m22;
- M23 = m23;
- M24 = m24;
- M31 = m31;
- M32 = m32;
- M33 = m33;
- M34 = m34;
- M41 = m41;
- M42 = m42;
- M43 = m43;
- M44 = m44;
- }
- }
-
- [ShortRunJob]
- public class UnsafeUnmanagedStructArrayBenchmark
- {
- [Params(1, 64, 1024, 16 * 1024 * 1024)]
- public int Size { get; set; }
-
- private Matrix4x4[] input;
- private byte[] inputSerializedUnsafe;
- private byte[] inputSerializedNormal;
-
- private newmsgpack::MessagePack.MessagePackSerializerOptions options;
-
- [GlobalSetup]
- public void SetUp()
- {
- var resolver = newmsgpack::MessagePack.Resolvers.CompositeResolver.Create(new newmsgpack::MessagePack.Formatters.IMessagePackFormatter[] { new newmsgpack::MessagePack.Formatters.UnsafeUnmanagedStructArrayFormatter(50) }, new[] { newmsgpack::MessagePack.Resolvers.StandardResolver.Instance });
- options = newmsgpack::MessagePack.MessagePackSerializerOptions.Standard.WithResolver(resolver);
-
- input = new Matrix4x4[Size];
- var r = new Random();
- for (var i = 0; i < input.Length; i++)
- {
- input[i] = new Matrix4x4((float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble(), (float)r.NextDouble());
- }
-
- inputSerializedUnsafe = newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options);
- inputSerializedNormal = newmsgpack::MessagePack.MessagePackSerializer.Serialize(input);
- }
-
- [Benchmark]
- public byte[] SerializeUnsafe()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options);
- }
-
- [Benchmark]
- public byte[] SerializeNormal()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(input);
- }
-
- [Benchmark]
- public Matrix4x4[] DeserializeUnsafe()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Deserialize(inputSerializedUnsafe, options);
- }
-
- [Benchmark]
- public Matrix4x4[] DeserializeNormal()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Deserialize(inputSerializedNormal);
- }
- }
-
- [ShortRunJob]
- public class BooleanArrayBenchmarkMessagePackNoSingleInstructionMultipleDataVsMessagePackSingleInstructionMultipleData
- {
- [Params(64, 1024, 16 * 1024 * 1024)]
- public int Size { get; set; }
-
- private bool[] input;
- private byte[] inputSerialized;
- private bool[] inputTrue;
- private bool[] inputFalse;
- private newmsgpack::MessagePack.MessagePackSerializerOptions options;
-
- [GlobalSetup]
- public void SetUp()
- {
- var resolver = newmsgpack::MessagePack.Resolvers.CompositeResolver.Create(newmsgpack::MessagePack.Resolvers.PrimitiveArrayResolver.Instance, newmsgpack::MessagePack.Resolvers.StandardResolver.Instance);
- options = newmsgpack::MessagePack.MessagePackSerializerOptions.Standard.WithResolver(resolver);
-
- inputFalse = new bool[Size];
- inputTrue = new bool[Size];
- input = new bool[Size];
-
- var r = new Random();
- for (var i = 0; i < inputTrue.Length; i++)
- {
- inputTrue[i] = true;
- input[i] = r.Next(0, 2) == 0;
- }
-
- inputSerialized = newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options);
-
- if (!oldmsgpack::MessagePack.MessagePackSerializer.Serialize(input).SequenceEqual(inputSerialized))
- {
- throw new InvalidProgramException();
- }
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleData()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleData()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(input);
- }
-
- [Benchmark]
- public bool[] DeSerializeSingleInstructionMultipleData()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Deserialize(inputSerialized, options);
- }
-
- [Benchmark]
- public bool[] DeserializeNoSingleInstructionMultipleData()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Deserialize(inputSerialized);
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleDataFalse()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(inputFalse, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleDataFalse()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(inputFalse);
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleDataTrue()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(inputTrue, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleDataTrue()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(inputTrue);
- }
- }
-
- [ShortRunJob]
- public class Int8ArrayBenchmarkMessagePackNoSingleInstructionMultipleDataVsMessagePackSingleInstructionMultipleData
- {
- [Params(64, 1024, 16 * 1024 * 1024)]
- public int Size { get; set; }
-
- private sbyte[] input;
- private sbyte[] inputM32;
- private sbyte[] inputM33;
- private sbyte[] zero;
- private newmsgpack::MessagePack.MessagePackSerializerOptions options;
-
- [GlobalSetup]
- public void SetUp()
- {
- var resolver = newmsgpack::MessagePack.Resolvers.CompositeResolver.Create(newmsgpack::MessagePack.Resolvers.PrimitiveArrayResolver.Instance, newmsgpack::MessagePack.Resolvers.StandardResolver.Instance);
- options = newmsgpack::MessagePack.MessagePackSerializerOptions.Standard.WithResolver(resolver);
-
- zero = new sbyte[Size];
- inputM33 = new sbyte[Size];
- inputM32 = new sbyte[Size];
- input = new sbyte[Size];
-
- var r = new Random();
- r.NextBytes(MemoryMarshal.AsBytes(input.AsSpan()));
- for (var i = 0; i < inputM32.Length; i++)
- {
- inputM32[i] = -32;
- inputM33[i] = -33;
- }
-
- if (!oldmsgpack::MessagePack.MessagePackSerializer.Serialize(input).SequenceEqual(newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options)))
- {
- throw new InvalidProgramException();
- }
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleData()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleData()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(input);
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleDataZero()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(zero, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleDataZero()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(zero);
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleDataM32()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(inputM32, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleDataM32()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(inputM32);
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleDataM33()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(inputM33, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleDataM33()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(inputM33);
- }
- }
-
- [ShortRunJob]
- public class Int16ArrayBenchmarkMessagePackNoSingleInstructionMultipleDataVsMessagePackSingleInstructionMultipleData
- {
- [Params(16, 1024, 16 * 1024 * 1024)]
- public int Size { get; set; }
-
- private newmsgpack::MessagePack.MessagePackSerializerOptions options;
- private short[] input;
- private short[] zero;
-
- [GlobalSetup]
- public void SetUp()
- {
- var resolver = newmsgpack::MessagePack.Resolvers.CompositeResolver.Create(newmsgpack::MessagePack.Resolvers.PrimitiveArrayResolver.Instance, newmsgpack::MessagePack.Resolvers.StandardResolver.Instance);
- options = newmsgpack::MessagePack.MessagePackSerializerOptions.Standard.WithResolver(resolver);
-
- input = new short[Size];
- zero = new short[Size];
- var r = new Random();
- r.NextBytes(MemoryMarshal.AsBytes(input.AsSpan()));
-
- if (!oldmsgpack::MessagePack.MessagePackSerializer.Serialize(input).SequenceEqual(newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options)))
- {
- throw new InvalidProgramException();
- }
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleData()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleData()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(input);
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleDataZero()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(zero, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleDataZero()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(zero);
- }
- }
-
- [ShortRunJob]
- public class Int32ArrayBenchmarkMessagePackNoSingleInstructionMultipleDataVsMessagePackSingleInstructionMultipleData
- {
- [Params(8, 1024, 16 * 1024 * 1024)]
- public int Size { get; set; }
-
- private newmsgpack::MessagePack.MessagePackSerializerOptions options;
- private int[] input;
- private int[] zero;
- private int[] inputShortMin;
-
- [GlobalSetup]
- public void SetUp()
- {
- var resolver = newmsgpack::MessagePack.Resolvers.CompositeResolver.Create(newmsgpack::MessagePack.Resolvers.PrimitiveArrayResolver.Instance, newmsgpack::MessagePack.Resolvers.StandardResolver.Instance);
- options = newmsgpack::MessagePack.MessagePackSerializerOptions.Standard.WithResolver(resolver);
-
- input = new int[Size];
- zero = new int[Size];
- inputShortMin = new int[Size];
- var r = new Random();
- r.NextBytes(MemoryMarshal.AsBytes(input.AsSpan()));
- for (var i = 0; i < inputShortMin.Length; i++)
- {
- inputShortMin[i] = short.MinValue;
- }
-
- if (!oldmsgpack::MessagePack.MessagePackSerializer.Serialize(input).SequenceEqual(newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options)))
- {
- throw new InvalidProgramException();
- }
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleData()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleData()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(input);
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleDataZero()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(zero, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleDataZero()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(zero);
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleDataShortMin()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(inputShortMin, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleDataShortMin()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(inputShortMin);
- }
- }
-
- [ShortRunJob]
- public class SingleArrayBenchmarkMessagePackNoSingleInstructionMultipleDataVsMessagePackSingleInstructionMultipleData
- {
- [Params(64, 1024, 16 * 1024 * 1024)]
- public int Size { get; set; }
-
- private newmsgpack::MessagePack.MessagePackSerializerOptions options;
- private float[] input;
-
- [GlobalSetup]
- public void SetUp()
- {
- var resolver = newmsgpack::MessagePack.Resolvers.CompositeResolver.Create(newmsgpack::MessagePack.Resolvers.PrimitiveArrayResolver.Instance, newmsgpack::MessagePack.Resolvers.StandardResolver.Instance);
- options = newmsgpack::MessagePack.MessagePackSerializerOptions.Standard.WithResolver(resolver);
- input = new float[Size];
-
- var r = new Random();
- for (var i = 0; i < input.Length; i++)
- {
- input[i] = (float)r.NextDouble();
- }
-
- if (!oldmsgpack::MessagePack.MessagePackSerializer.Serialize(input).SequenceEqual(newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options)))
- {
- throw new InvalidProgramException();
- }
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleData()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleData()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(input);
- }
- }
-
- [ShortRunJob]
- public class DoubleArrayBenchmarkMessagePackNoSingleInstructionMultipleDataVsMessagePackSingleInstructionMultipleData
- {
- [Params(64, 1024, 16 * 1024 * 1024)]
- public int Size { get; set; }
-
- private newmsgpack::MessagePack.MessagePackSerializerOptions options;
- private double[] input;
-
- [GlobalSetup]
- public void SetUp()
- {
- var resolver = newmsgpack::MessagePack.Resolvers.CompositeResolver.Create(newmsgpack::MessagePack.Resolvers.PrimitiveArrayResolver.Instance, newmsgpack::MessagePack.Resolvers.StandardResolver.Instance);
- options = newmsgpack::MessagePack.MessagePackSerializerOptions.Standard.WithResolver(resolver);
- input = new double[Size];
-
- var r = new Random();
- for (var i = 0; i < input.Length; i++)
- {
- input[i] = r.NextDouble();
- }
-
- if (!oldmsgpack::MessagePack.MessagePackSerializer.Serialize(input).SequenceEqual(newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options)))
- {
- throw new InvalidProgramException();
- }
- }
-
- [Benchmark]
- public byte[] SerializeSingleInstructionMultipleData()
- {
- return newmsgpack::MessagePack.MessagePackSerializer.Serialize(input, options);
- }
-
- [Benchmark]
- public byte[] SerializeNoSingleInstructionMultipleData()
- {
- return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(input);
- }
- }
-}
diff --git a/benchmark/SerializerBenchmark/BenchmarkConfig.cs b/benchmark/SerializerBenchmark/BenchmarkConfig.cs
index 750d4f2d2..987a1a770 100644
--- a/benchmark/SerializerBenchmark/BenchmarkConfig.cs
+++ b/benchmark/SerializerBenchmark/BenchmarkConfig.cs
@@ -16,6 +16,7 @@
using BenchmarkDotNet.Order;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Running;
+using Perfolizer.Metrology;
namespace Benchmark
{
@@ -27,7 +28,7 @@ public BenchmarkConfig()
Job baseConfig = Job.ShortRun.WithIterationCount(1).WithWarmupCount(1);
// Add(baseConfig.With(Runtime.Clr).With(Jit.RyuJit).With(Platform.X64));
- this.AddJob(baseConfig.WithRuntime(CoreRuntime.Core31).WithJit(Jit.RyuJit).WithPlatform(Platform.X64));
+ this.AddJob(baseConfig.WithEnvironmentVariable(new("DOTNET_TieredPGO", "0")).WithRuntime(CoreRuntime.Core80).WithJit(Jit.RyuJit).WithPlatform(Platform.X64));
this.AddExporter(MarkdownExporter.GitHub);
this.AddExporter(CsvExporter.Default);
@@ -110,7 +111,7 @@ public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyl
var cultureInfo = summary.GetCultureInfo();
if (style.PrintUnitsInContent)
{
- return SizeValue.FromBytes(byteSize).ToString(style.SizeUnit, cultureInfo);
+ return SizeValue.FromBytes(byteSize).ToString(style.SizeUnit, null, cultureInfo);
}
return byteSize.ToString("0.##", cultureInfo);
diff --git a/benchmark/SerializerBenchmark/Models/AccessToken.cs b/benchmark/SerializerBenchmark/Models/AccessToken.cs
index a4884aabe..e5d90923a 100644
--- a/benchmark/SerializerBenchmark/Models/AccessToken.cs
+++ b/benchmark/SerializerBenchmark/Models/AccessToken.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using System.Collections.Generic;
diff --git a/benchmark/SerializerBenchmark/Models/AccountMerge.cs b/benchmark/SerializerBenchmark/Models/AccountMerge.cs
index e3ab86292..e209bf133 100644
--- a/benchmark/SerializerBenchmark/Models/AccountMerge.cs
+++ b/benchmark/SerializerBenchmark/Models/AccountMerge.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/Answer.cs b/benchmark/SerializerBenchmark/Models/Answer.cs
index 442fe8526..56979a7b3 100644
--- a/benchmark/SerializerBenchmark/Models/Answer.cs
+++ b/benchmark/SerializerBenchmark/Models/Answer.cs
@@ -5,9 +5,8 @@
#pragma warning disable IDE1006
#pragma warning disable SA1516
-extern alias oldmsgpack;
extern alias newmsgpack;
-
+extern alias oldmsgpack;
using System;
using System.Collections.Generic;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/Badge.cs b/benchmark/SerializerBenchmark/Models/Badge.cs
index fbe6d9d5d..a2f793b5e 100644
--- a/benchmark/SerializerBenchmark/Models/Badge.cs
+++ b/benchmark/SerializerBenchmark/Models/Badge.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/Comment.cs b/benchmark/SerializerBenchmark/Models/Comment.cs
index e923671df..eb0dc9767 100644
--- a/benchmark/SerializerBenchmark/Models/Comment.cs
+++ b/benchmark/SerializerBenchmark/Models/Comment.cs
@@ -5,9 +5,8 @@
#pragma warning disable IDE1006
#pragma warning disable SA1516
-extern alias oldmsgpack;
extern alias newmsgpack;
-
+extern alias oldmsgpack;
using System;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/Error.cs b/benchmark/SerializerBenchmark/Models/Error.cs
index 1137cd9da..73e73c6dc 100644
--- a/benchmark/SerializerBenchmark/Models/Error.cs
+++ b/benchmark/SerializerBenchmark/Models/Error.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/Event.cs b/benchmark/SerializerBenchmark/Models/Event.cs
index 570e08ad8..5169698a7 100644
--- a/benchmark/SerializerBenchmark/Models/Event.cs
+++ b/benchmark/SerializerBenchmark/Models/Event.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/Feed.cs b/benchmark/SerializerBenchmark/Models/Feed.cs
index 196b2a4c8..d27274e2b 100644
--- a/benchmark/SerializerBenchmark/Models/Feed.cs
+++ b/benchmark/SerializerBenchmark/Models/Feed.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System.Collections.Generic;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/FlagOption.cs b/benchmark/SerializerBenchmark/Models/FlagOption.cs
index 95328086f..0bdb24fce 100644
--- a/benchmark/SerializerBenchmark/Models/FlagOption.cs
+++ b/benchmark/SerializerBenchmark/Models/FlagOption.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System.Collections.Generic;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/InboxItem.cs b/benchmark/SerializerBenchmark/Models/InboxItem.cs
index 30d33a8ef..aaa6e5e2f 100644
--- a/benchmark/SerializerBenchmark/Models/InboxItem.cs
+++ b/benchmark/SerializerBenchmark/Models/InboxItem.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/Info.cs b/benchmark/SerializerBenchmark/Models/Info.cs
index 26662d0e9..dc46daaf8 100644
--- a/benchmark/SerializerBenchmark/Models/Info.cs
+++ b/benchmark/SerializerBenchmark/Models/Info.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using System.Collections.Generic;
diff --git a/benchmark/SerializerBenchmark/Models/NetworkUser.cs b/benchmark/SerializerBenchmark/Models/NetworkUser.cs
index 76a7fd9be..7c0b6682e 100644
--- a/benchmark/SerializerBenchmark/Models/NetworkUser.cs
+++ b/benchmark/SerializerBenchmark/Models/NetworkUser.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/Notification.cs b/benchmark/SerializerBenchmark/Models/Notification.cs
index 677cd3952..e413b4126 100644
--- a/benchmark/SerializerBenchmark/Models/Notification.cs
+++ b/benchmark/SerializerBenchmark/Models/Notification.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/Post.cs b/benchmark/SerializerBenchmark/Models/Post.cs
index 4ec6b4ba7..c91dcd33f 100644
--- a/benchmark/SerializerBenchmark/Models/Post.cs
+++ b/benchmark/SerializerBenchmark/Models/Post.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using System.Collections.Generic;
diff --git a/benchmark/SerializerBenchmark/Models/Privilege.cs b/benchmark/SerializerBenchmark/Models/Privilege.cs
index 77978c4c5..2260df8b2 100644
--- a/benchmark/SerializerBenchmark/Models/Privilege.cs
+++ b/benchmark/SerializerBenchmark/Models/Privilege.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/Question.cs b/benchmark/SerializerBenchmark/Models/Question.cs
index 2b2198ce6..5ede917fd 100644
--- a/benchmark/SerializerBenchmark/Models/Question.cs
+++ b/benchmark/SerializerBenchmark/Models/Question.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using System.Collections.Generic;
diff --git a/benchmark/SerializerBenchmark/Models/QuestionTimeline.cs b/benchmark/SerializerBenchmark/Models/QuestionTimeline.cs
index 5d69bd5d0..a74bd05cd 100644
--- a/benchmark/SerializerBenchmark/Models/QuestionTimeline.cs
+++ b/benchmark/SerializerBenchmark/Models/QuestionTimeline.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/Reputation.cs b/benchmark/SerializerBenchmark/Models/Reputation.cs
index d750dfd7b..637577aed 100644
--- a/benchmark/SerializerBenchmark/Models/Reputation.cs
+++ b/benchmark/SerializerBenchmark/Models/Reputation.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/ReputationHistory.cs b/benchmark/SerializerBenchmark/Models/ReputationHistory.cs
index a084eb3e2..28205064e 100644
--- a/benchmark/SerializerBenchmark/Models/ReputationHistory.cs
+++ b/benchmark/SerializerBenchmark/Models/ReputationHistory.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/Revision.cs b/benchmark/SerializerBenchmark/Models/Revision.cs
index b76d385c8..74da971f3 100644
--- a/benchmark/SerializerBenchmark/Models/Revision.cs
+++ b/benchmark/SerializerBenchmark/Models/Revision.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using System.Collections.Generic;
diff --git a/benchmark/SerializerBenchmark/Models/SearchExcerpt.cs b/benchmark/SerializerBenchmark/Models/SearchExcerpt.cs
index a5d85e31a..07235c429 100644
--- a/benchmark/SerializerBenchmark/Models/SearchExcerpt.cs
+++ b/benchmark/SerializerBenchmark/Models/SearchExcerpt.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using System.Collections.Generic;
diff --git a/benchmark/SerializerBenchmark/Models/ShallowUser.cs b/benchmark/SerializerBenchmark/Models/ShallowUser.cs
index 1c0b07055..3cda7b2ca 100644
--- a/benchmark/SerializerBenchmark/Models/ShallowUser.cs
+++ b/benchmark/SerializerBenchmark/Models/ShallowUser.cs
@@ -5,9 +5,8 @@
#pragma warning disable IDE1006
#pragma warning disable SA1516
-extern alias oldmsgpack;
extern alias newmsgpack;
-
+extern alias oldmsgpack;
using ProtoBuf;
namespace Benchmark.Models
diff --git a/benchmark/SerializerBenchmark/Models/SuggestedEdit.cs b/benchmark/SerializerBenchmark/Models/SuggestedEdit.cs
index f774655ad..dcf317d61 100644
--- a/benchmark/SerializerBenchmark/Models/SuggestedEdit.cs
+++ b/benchmark/SerializerBenchmark/Models/SuggestedEdit.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using System.Collections.Generic;
diff --git a/benchmark/SerializerBenchmark/Models/Tag.cs b/benchmark/SerializerBenchmark/Models/Tag.cs
index 586f60ffa..8ffc40d73 100644
--- a/benchmark/SerializerBenchmark/Models/Tag.cs
+++ b/benchmark/SerializerBenchmark/Models/Tag.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using System.Collections.Generic;
diff --git a/benchmark/SerializerBenchmark/Models/TagScore.cs b/benchmark/SerializerBenchmark/Models/TagScore.cs
index b377008e2..976966731 100644
--- a/benchmark/SerializerBenchmark/Models/TagScore.cs
+++ b/benchmark/SerializerBenchmark/Models/TagScore.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/TagSynonym.cs b/benchmark/SerializerBenchmark/Models/TagSynonym.cs
index 615226d1c..841e00ca4 100644
--- a/benchmark/SerializerBenchmark/Models/TagSynonym.cs
+++ b/benchmark/SerializerBenchmark/Models/TagSynonym.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/TagWiki.cs b/benchmark/SerializerBenchmark/Models/TagWiki.cs
index aa37ca22a..c02558ba3 100644
--- a/benchmark/SerializerBenchmark/Models/TagWiki.cs
+++ b/benchmark/SerializerBenchmark/Models/TagWiki.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/TopTag.cs b/benchmark/SerializerBenchmark/Models/TopTag.cs
index 2fc0c8e87..20939c30d 100644
--- a/benchmark/SerializerBenchmark/Models/TopTag.cs
+++ b/benchmark/SerializerBenchmark/Models/TopTag.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/User.cs b/benchmark/SerializerBenchmark/Models/User.cs
index f78a43f43..6919b5627 100644
--- a/benchmark/SerializerBenchmark/Models/User.cs
+++ b/benchmark/SerializerBenchmark/Models/User.cs
@@ -4,9 +4,8 @@
#pragma warning disable IDE1006
#pragma warning disable SA1516
-extern alias oldmsgpack;
extern alias newmsgpack;
-
+extern alias oldmsgpack;
using System;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/UserTimeline.cs b/benchmark/SerializerBenchmark/Models/UserTimeline.cs
index 1e4410db2..f4e0119c4 100644
--- a/benchmark/SerializerBenchmark/Models/UserTimeline.cs
+++ b/benchmark/SerializerBenchmark/Models/UserTimeline.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using System;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/Models/WritePermission.cs b/benchmark/SerializerBenchmark/Models/WritePermission.cs
index f450ec2aa..f82768d8f 100644
--- a/benchmark/SerializerBenchmark/Models/WritePermission.cs
+++ b/benchmark/SerializerBenchmark/Models/WritePermission.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
using ProtoBuf;
diff --git a/benchmark/SerializerBenchmark/SerializerBenchmark.cs b/benchmark/SerializerBenchmark/SerializerBenchmark.cs
index cd58a1641..e47b42a76 100644
--- a/benchmark/SerializerBenchmark/SerializerBenchmark.cs
+++ b/benchmark/SerializerBenchmark/SerializerBenchmark.cs
@@ -35,7 +35,6 @@ public class AllSerializerBenchmark_BytesInOut
new ProtobufNetSerializer(),
new JsonNetSerializer(),
new BsonNetSerializer(),
- new BinaryFormatterSerializer(),
new DataContractSerializer(),
new HyperionSerializer(),
new JilSerializer(),
@@ -1116,7 +1115,6 @@ public class ShortRun_AllSerializerBenchmark_BytesInOut
new ProtobufNetSerializer(),
new JsonNetSerializer(),
new BsonNetSerializer(),
- new BinaryFormatterSerializer(),
new DataContractSerializer(),
new HyperionSerializer(),
new JilSerializer(),
diff --git a/benchmark/SerializerBenchmark/SerializerBenchmark.csproj b/benchmark/SerializerBenchmark/SerializerBenchmark.csproj
index a6ea965ee..e573add58 100644
--- a/benchmark/SerializerBenchmark/SerializerBenchmark.csproj
+++ b/benchmark/SerializerBenchmark/SerializerBenchmark.csproj
@@ -2,7 +2,7 @@
Exe
- net7.0
+ net8.0
SerializerBenchmark
Benchmark
true
diff --git a/benchmark/SerializerBenchmark/Serializers/BinaryFormatterSerializer.cs b/benchmark/SerializerBenchmark/Serializers/BinaryFormatterSerializer.cs
deleted file mode 100644
index ec3891178..000000000
--- a/benchmark/SerializerBenchmark/Serializers/BinaryFormatterSerializer.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) All contributors. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System.IO;
-using System.Runtime.Serialization.Formatters.Binary;
-
-namespace Benchmark.Serializers
-{
-#pragma warning disable SYSLIB0011 // Type or member is obsolete
-
- public class BinaryFormatterSerializer : SerializerBase
- {
- public override T Deserialize(object input)
- {
- using (var ms = new MemoryStream((byte[])input))
- {
- return (T)new BinaryFormatter().Deserialize(ms);
- }
- }
-
- public override object Serialize(T input)
- {
- using (var ms = new MemoryStream())
- {
- new BinaryFormatter().Serialize(ms, input);
- ms.Flush();
- return ms.ToArray();
- }
- }
-
- public override string ToString()
- {
- return "BinaryFormatter";
- }
- }
-}
diff --git a/benchmark/SerializerBenchmark/Serializers/MessagePackSerializer.cs b/benchmark/SerializerBenchmark/Serializers/MessagePackSerializer.cs
index f9438c98c..95618ba97 100644
--- a/benchmark/SerializerBenchmark/Serializers/MessagePackSerializer.cs
+++ b/benchmark/SerializerBenchmark/Serializers/MessagePackSerializer.cs
@@ -1,8 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-extern alias oldmsgpack;
extern alias newmsgpack;
+extern alias oldmsgpack;
#pragma warning disable SA1402 // File may only contain a single type
#pragma warning disable SA1649 // File name should match first type name
@@ -206,9 +206,9 @@ private OptimizedResolver()
private static class Cache
{
- #pragma warning disable SA1401 // Fields should be private
+#pragma warning disable SA1401 // Fields should be private
public static newmsgpack::MessagePack.Formatters.IMessagePackFormatter Formatter;
- #pragma warning restore SA1401 // Fields should be private
+#pragma warning restore SA1401 // Fields should be private
static Cache()
{
diff --git a/bin/MessagePack/Debug/netstandard2.1/MessagePack.Analyzers.CodeFixes.dll.meta b/bin/MessagePack/Debug/netstandard2.1/MessagePack.Analyzers.CodeFixes.dll.meta
new file mode 100644
index 000000000..0b2f22a5e
--- /dev/null
+++ b/bin/MessagePack/Debug/netstandard2.1/MessagePack.Analyzers.CodeFixes.dll.meta
@@ -0,0 +1,71 @@
+fileFormatVersion: 2
+guid: 891c05d4b21294248acbe7e80ae1a4fb
+labels:
+- RoslynAnalyzer
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 1
+ isExplicitlyReferenced: 1
+ validateReferences: 0
+ platformData:
+ - first:
+ : Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Editor: 1
+ Exclude Linux64: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ DefaultValueInitialized: true
+ OS: AnyOS
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/bin/MessagePack/Debug/netstandard2.1/MessagePack.Analyzers.CodeFixes.xml.meta b/bin/MessagePack/Debug/netstandard2.1/MessagePack.Analyzers.CodeFixes.xml.meta
new file mode 100644
index 000000000..7ab33553f
--- /dev/null
+++ b/bin/MessagePack/Debug/netstandard2.1/MessagePack.Analyzers.CodeFixes.xml.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 4f2de8ccc64b20e4c9a0396761e4833a
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/bin/MessagePack/Debug/netstandard2.1/MessagePack.Analyzers.dll.meta b/bin/MessagePack/Debug/netstandard2.1/MessagePack.Analyzers.dll.meta
new file mode 100644
index 000000000..3f2b25b6c
--- /dev/null
+++ b/bin/MessagePack/Debug/netstandard2.1/MessagePack.Analyzers.dll.meta
@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: 892214273c923364eb684f3d7859fe0b
+labels:
+- RoslynAnalyzer
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 1
+ isExplicitlyReferenced: 1
+ validateReferences: 0
+ platformData:
+ - first:
+ : Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Editor: 1
+ Exclude Linux64: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/bin/MessagePack/Debug/netstandard2.1/MessagePack.Analyzers.xml.meta b/bin/MessagePack/Debug/netstandard2.1/MessagePack.Analyzers.xml.meta
new file mode 100644
index 000000000..40a2450ee
--- /dev/null
+++ b/bin/MessagePack/Debug/netstandard2.1/MessagePack.Analyzers.xml.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 88463aa60e4b9b441adcbe51a85df913
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/bin/MessagePack/Debug/netstandard2.1/MessagePack.Annotations.dll.meta b/bin/MessagePack/Debug/netstandard2.1/MessagePack.Annotations.dll.meta
new file mode 100644
index 000000000..a0cde4960
--- /dev/null
+++ b/bin/MessagePack/Debug/netstandard2.1/MessagePack.Annotations.dll.meta
@@ -0,0 +1,33 @@
+fileFormatVersion: 2
+guid: 3f561a38e71988440b2d52ebba1a0521
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 1
+ isExplicitlyReferenced: 0
+ validateReferences: 1
+ platformData:
+ - first:
+ Any:
+ second:
+ enabled: 1
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/bin/MessagePack/Debug/netstandard2.1/MessagePack.Annotations.xml.meta b/bin/MessagePack/Debug/netstandard2.1/MessagePack.Annotations.xml.meta
new file mode 100644
index 000000000..3807f7c74
--- /dev/null
+++ b/bin/MessagePack/Debug/netstandard2.1/MessagePack.Annotations.xml.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 540772e8d33295746891820d923d6eff
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/bin/MessagePack/Debug/netstandard2.1/MessagePack.SourceGenerator.dll.meta b/bin/MessagePack/Debug/netstandard2.1/MessagePack.SourceGenerator.dll.meta
new file mode 100644
index 000000000..c0b1f55ec
--- /dev/null
+++ b/bin/MessagePack/Debug/netstandard2.1/MessagePack.SourceGenerator.dll.meta
@@ -0,0 +1,45 @@
+fileFormatVersion: 2
+guid: 9842f348649c87c4f8dd184cac2508aa
+labels:
+- RoslynAnalyzer
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 1
+ isExplicitlyReferenced: 1
+ validateReferences: 0
+ platformData:
+ - first:
+ : Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Editor: 1
+ Exclude Linux64: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/bin/MessagePack/Debug/netstandard2.1/MessagePack.SourceGenerator.xml.meta b/bin/MessagePack/Debug/netstandard2.1/MessagePack.SourceGenerator.xml.meta
new file mode 100644
index 000000000..5e478298d
--- /dev/null
+++ b/bin/MessagePack/Debug/netstandard2.1/MessagePack.SourceGenerator.xml.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 5b419071c2e21e9469fa6971585b48f3
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/bin/MessagePack/Debug/netstandard2.1/MessagePack.deps.json.meta b/bin/MessagePack/Debug/netstandard2.1/MessagePack.deps.json.meta
new file mode 100644
index 000000000..c56c26511
--- /dev/null
+++ b/bin/MessagePack/Debug/netstandard2.1/MessagePack.deps.json.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 2aa609d1a0a772b4791a8bfabc13df17
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/bin/MessagePack/Debug/netstandard2.1/MessagePack.dll.meta b/bin/MessagePack/Debug/netstandard2.1/MessagePack.dll.meta
new file mode 100644
index 000000000..348efd133
--- /dev/null
+++ b/bin/MessagePack/Debug/netstandard2.1/MessagePack.dll.meta
@@ -0,0 +1,33 @@
+fileFormatVersion: 2
+guid: 28339a892bc291940a4a15f087c29fde
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 1
+ isExplicitlyReferenced: 0
+ validateReferences: 1
+ platformData:
+ - first:
+ Any:
+ second:
+ enabled: 1
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/bin/MessagePack/Debug/netstandard2.1/MessagePack.xml.meta b/bin/MessagePack/Debug/netstandard2.1/MessagePack.xml.meta
new file mode 100644
index 000000000..f717945b2
--- /dev/null
+++ b/bin/MessagePack/Debug/netstandard2.1/MessagePack.xml.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 7fb1b483dd594c143bfd6495d9e9b234
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/bin/MessagePack/Debug/netstandard2.1/package.json b/bin/MessagePack/Debug/netstandard2.1/package.json
new file mode 100644
index 000000000..98e6a4380
--- /dev/null
+++ b/bin/MessagePack/Debug/netstandard2.1/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "com.github.messagepack.internal",
+ "displayName": "MessagePack Internal",
+ "author": { "name": "MessagePack-CSharp", "url": "https://github.com/MessagePack-CSharp/MessagePack-CSharp" },
+ "version": "1.0.0",
+ "unity": "2021.3",
+ "description": "Internal Package of MessagePack for development time.",
+ "keywords": [ "Serialization" ],
+ "license": "MIT",
+ "category": "Scripting",
+ "dependencies": {}
+}
diff --git a/bin/MessagePack/Debug/netstandard2.1/package.json.meta b/bin/MessagePack/Debug/netstandard2.1/package.json.meta
new file mode 100644
index 000000000..8878a36ef
--- /dev/null
+++ b/bin/MessagePack/Debug/netstandard2.1/package.json.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: b958014f8e837e34aa1a78db9cd582de
+PackageManifestImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/doc/analyzers/MsgPack003.md b/doc/analyzers/MsgPack003.md
index 799e2baf5..65fa74c1f 100644
--- a/doc/analyzers/MsgPack003.md
+++ b/doc/analyzers/MsgPack003.md
@@ -1,3 +1,47 @@
# MsgPack003 Use MessagePackObjectAttribute
-Type must be marked with `MessagePackObjectAttribute`.
+Types referenced by serializable fields and properties must themselves be attributed with the `[MessagePackObject]`.
+
+## Examples of patterns that are flagged by this analyzer
+
+```cs
+[MessagePackObject]
+public class A {
+ [Key(0)]
+ public B b;
+}
+
+public class B {
+ public int Count;
+}
+```
+
+## Example fix
+
+Add the required attributes to the `B` class so that a dynamic formatter can be generated for it:
+
+```cs
+[MessagePackObject]
+public class A {
+ [Key(0)]
+ public B b;
+}
+
+[MessagePackObject]
+public class B {
+ [Key(0)]
+ public int Count;
+}
+```
+
+An automated code fix is offered for this.
+
+## Alternative fix
+
+When `B` is formattable via a custom formatter, the diagnostic may be suppressed by declaring this attribute:
+
+```cs
+[assembly: MessagePackAssumedFormattable(typeof(B))]
+```
+
+When doing so, it becomes your responsibility to ensure that the custom formatter for `B` is discoverable via the `IFormatterResolver` object accessible through `MessagePackSerializerOptions.Resolver`.
diff --git a/doc/analyzers/MsgPack004.md b/doc/analyzers/MsgPack004.md
index 5ced79ef2..94bcdc10c 100644
--- a/doc/analyzers/MsgPack004.md
+++ b/doc/analyzers/MsgPack004.md
@@ -1,3 +1,47 @@
# MsgPack004 Attribute public members of MessagePack objects
Public members of `MessagePackObjectAttribute`-attributed types require either `KeyAttribute` or `IgnoreMemberAttribute`.
+
+## Examples of patterns that are flagged by this analyzer
+
+```cs
+[MessagePackObject]
+public class C {
+ [Key(0)]
+ public int A { get; set; }
+
+ public int B { get; set; } // MsgPack004
+}
+```
+
+## Typical fix
+
+Indicate that the unattributed member should be serialized:
+
+```cs
+[MessagePackObject]
+public class C {
+ [Key(0)]
+ public int A { get; set; }
+
+ [Key(1)]
+ public int B { get; set; }
+}
+```
+
+An automated code fix is available for this.
+
+## Alternative fix
+
+If the unattributed member should _not_ be serialized, apply the `[IgnoreMember]` attribute:
+
+```cs
+[MessagePackObject]
+public class C {
+ [Key(0)]
+ public int A { get; set; }
+
+ [IgnoreMember]
+ public int B { get; set; }
+}
+```
diff --git a/doc/analyzers/MsgPack005.md b/doc/analyzers/MsgPack005.md
index 9d209e2f9..1a8783fa0 100644
--- a/doc/analyzers/MsgPack005.md
+++ b/doc/analyzers/MsgPack005.md
@@ -1,3 +1,6 @@
# MsgPack005 MessagePackObject validation
Invalid MessagePackObject definition.
+
+There are a variety of conditions that can produce this diagnostic.
+Examine the specific message to understand what is wrong and how to correct it.
diff --git a/doc/analyzers/MsgPack006.md b/doc/analyzers/MsgPack006.md
new file mode 100644
index 000000000..397b6eec6
--- /dev/null
+++ b/doc/analyzers/MsgPack006.md
@@ -0,0 +1,36 @@
+# MsgPack006 Type must be of `IMessagePackFormatter`
+
+This diganostic appears when the type passed to `MesssagePackFormatterAttribute` does not actually implement some `IMessagePackFormatter`.
+
+## Examples of patterns that are flagged by this analyzer
+
+```cs
+[MessagePackObject]
+public class A {
+ [Key(0), MessagePackFormatter(typeof(CustomBFormatter))]
+ public B b;
+}
+
+public class CustomBFormatter {}
+```
+
+## Typical fix
+
+Change the attribute to point to a valid formatter, or update the referenced class to be a valid formatter.
+The following example takes the latter approach.
+
+```cs
+[MessagePackObject]
+public class A {
+ [Key(0), MessagePackFormatter(typeof(CustomBFormatter))]
+ public B b;
+}
+
+public class CustomBFormatter : IMessagePackFormatter {
+ void Serialize(ref MessagePackWriter writer, B value, MessagePackSerializerOptions options)
+ => throw new NotImplementedException();
+
+ B Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
+ => throw new NotImplementedException();
+}
+```
diff --git a/doc/analyzers/MsgPack007.md b/doc/analyzers/MsgPack007.md
new file mode 100644
index 000000000..096162795
--- /dev/null
+++ b/doc/analyzers/MsgPack007.md
@@ -0,0 +1,4 @@
+# MsgPack007 Deserializing constructors
+
+There are a variety of conditions that can produce this diagnostic.
+Examine the specific message to understand what is wrong and how to correct it.
diff --git a/doc/analyzers/MsgPack008.md b/doc/analyzers/MsgPack008.md
new file mode 100644
index 000000000..6ee013a3a
--- /dev/null
+++ b/doc/analyzers/MsgPack008.md
@@ -0,0 +1,6 @@
+# MsgPack008 AOT limitations
+
+AOT source generated formatters do not support certain features that formatters generated dynamically at runtime may support.
+
+There are a variety of conditions that can produce this diagnostic.
+Examine the specific message to understand what is wrong and how to correct it.
diff --git a/doc/analyzers/MsgPack009.md b/doc/analyzers/MsgPack009.md
new file mode 100644
index 000000000..db6cebd89
--- /dev/null
+++ b/doc/analyzers/MsgPack009.md
@@ -0,0 +1,9 @@
+# MsgPack009 Colliding Formatters
+
+All formatters in a compilation are automatically added to a source generated resolver so that it can be found at runtime.
+
+When two formatters implement `IMessagePackFormatter` for the same `T`, it cannot be statically determined which formatter should be used, and this diagnostic results.
+
+## Typical fix
+
+Either remove all but one of the conflicting formatters, or exclude all but one from inclusion in the source generated resolver by applying the `[ExcludeFormatterFromSourceGeneratedResolver]` attribute to some of the formatters.
diff --git a/doc/analyzers/MsgPack010.md b/doc/analyzers/MsgPack010.md
new file mode 100644
index 000000000..5512b3f2c
--- /dev/null
+++ b/doc/analyzers/MsgPack010.md
@@ -0,0 +1,35 @@
+# MsgPack010 Inaccessible Formatter
+
+Formatters must be declared with `internal` or `public` visibility so that the source generated resolver can access them.
+
+This tends to happen when a formatter is declared as a nested type, where C# defaults to `private` visibility.
+
+## Examples of patterns that are flagged by this analyzer
+
+```cs
+class Outer {
+ /*private*/ class CustomBFormatter : IMessagePackFormatter { // MsgPack010
+ void Serialize(ref MessagePackWriter writer, B value, MessagePackSerializerOptions options)
+ => throw new NotImplementedException();
+
+ B Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
+ => throw new NotImplementedException();
+ }
+}
+```
+
+## Typical fix
+
+Add the `internal` or `public` modifier to the nested formatter:
+
+```cs
+class Outer {
+ internal class CustomBFormatter : IMessagePackFormatter {
+ void Serialize(ref MessagePackWriter writer, B value, MessagePackSerializerOptions options)
+ => throw new NotImplementedException();
+
+ B Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
+ => throw new NotImplementedException();
+ }
+}
+```
diff --git a/doc/analyzers/MsgPack011.md b/doc/analyzers/MsgPack011.md
new file mode 100644
index 000000000..2b6e8750e
--- /dev/null
+++ b/doc/analyzers/MsgPack011.md
@@ -0,0 +1,39 @@
+# MsgPack011 Partial type required
+
+When a `[MessagePackObject]` includes serializable members with less than `internal` visibility, the declaring type must use the `partial` modifier, so that the source generated formatter can be emitted as a member of that type and thus gain access to its private members.
+
+## Examples of patterns that are flagged by this analyzer
+
+```cs
+[MessagePackObject]
+public class A {
+ [Key(0)]
+ private B b;
+}
+```
+
+## Typical fix
+
+Add the `partial` keyword:
+
+```cs
+[MessagePackObject]
+public partial class A {
+ [Key(0)]
+ private B b;
+}
+```
+
+An automated code fix is available for this.
+
+## Alternative fix
+
+Alternatively, make all private/protected serializable members `internal` instead so that a formatter declared elsewhere in the compilation can reach them:
+
+```cs
+[MessagePackObject]
+public class A {
+ [Key(0)]
+ internal B b;
+}
+```
diff --git a/doc/analyzers/MsgPack012.md b/doc/analyzers/MsgPack012.md
new file mode 100644
index 000000000..3ffb8223c
--- /dev/null
+++ b/doc/analyzers/MsgPack012.md
@@ -0,0 +1,24 @@
+# MsgPack012 Inaccessible data type
+
+Serializable data types must have at least `internal` accessibility so that a source generated formatter elsewhere in the compilation can access it.
+C# defaults to `internal` visibility except for nested types, which receive `private` visibility by default.
+
+## Examples of patterns that are flagged by this analyzer
+
+```cs
+class Outer {
+ [MessagePackObject]
+ /*private*/ class DataType { }
+}
+```
+
+## Typical fix
+
+Add the `internal` or `public` modifier to the nested data type:
+
+```cs
+class Outer {
+ [MessagePackObject]
+ internal class DataType { }
+}
+```
diff --git a/doc/analyzers/MsgPack013.md b/doc/analyzers/MsgPack013.md
new file mode 100644
index 000000000..85dd67572
--- /dev/null
+++ b/doc/analyzers/MsgPack013.md
@@ -0,0 +1,52 @@
+# MsgPack013 Inaccessible formatter instance
+
+A custom `IMessagePackFormatter` implementation must have an accessible instance to be included in the source generated resolver.
+
+This instance can be exposed by any of the following:
+
+1. A public default constructor.
+1. A public static readonly field called `Instance`.
+
+## Examples of patterns that are flagged by this analyzer
+
+```cs
+class CustomBFormatter : IMessagePackFormatter { // MsgPack013
+ private CustomBFormatter { } // hides the default public constructor
+
+ void Serialize(ref MessagePackWriter writer, B value, MessagePackSerializerOptions options)
+ => throw new NotImplementedException();
+
+ B Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
+ => throw new NotImplementedException();
+}
+```
+
+## Typical fix
+
+Delete the non-public default constructor so that C# can access it:
+
+```cs
+class CustomBFormatter : IMessagePackFormatter {
+ void Serialize(ref MessagePackWriter writer, B value, MessagePackSerializerOptions options)
+ => throw new NotImplementedException();
+
+ B Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
+ => throw new NotImplementedException();
+}
+```
+
+Or make a singleton instance available:
+
+```cs
+class CustomBFormatter : IMessagePackFormatter {
+ public static readonly CustomBFormatter Instance = new();
+
+ private CustomBFormatter { } // hides the default public constructor
+
+ void Serialize(ref MessagePackWriter writer, B value, MessagePackSerializerOptions options)
+ => throw new NotImplementedException();
+
+ B Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
+ => throw new NotImplementedException();
+}
+```
diff --git a/doc/analyzers/MsgPack014.md b/doc/analyzers/MsgPack014.md
new file mode 100644
index 000000000..b0cbf1b02
--- /dev/null
+++ b/doc/analyzers/MsgPack014.md
@@ -0,0 +1,51 @@
+# MsgPack014 Nullable reference type formatter
+
+Custom formatters of reference types should be prepared to handle `null` references.
+
+## Examples of patterns that are flagged by this analyzer
+
+```cs
+class B { }
+
+class CustomBFormatter : IMessagePackFormatter { // MsgPack014
+ void Serialize(ref MessagePackWriter writer, B value, MessagePackSerializerOptions options) {
+ writer.WriteArrayHeader(0);
+ }
+
+ B Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) {
+ int count = reader.ReadArrayHeader();
+ for (int i = 0; i < count; i++)
+ reader.Skip();
+ }
+}
+```
+
+## Typical fix
+
+
+```cs
+class B { }
+
+class CustomBFormatter : IMessagePackFormatter {
+ void Serialize(ref MessagePackWriter writer, B? value, MessagePackSerializerOptions options) {
+ if (value is null) {
+ writer.WriteNil();
+ return;
+ }
+
+ writer.WriteArrayHeader(0);
+ }
+
+ B? Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) {
+ if (reader.TryReadNil()) return null;
+
+ int count = reader.ReadArrayHeader();
+ for (int i = 0; i < count; i++)
+ reader.Skip();
+ }
+}
+```
+
+An automated code fix will add the nullable ref annotations.
+But it does not automatically add the null handling to the method bodies.
+This must be done by hand.
diff --git a/doc/analyzers/MsgPack015.md b/doc/analyzers/MsgPack015.md
new file mode 100644
index 000000000..87e8d9dd1
--- /dev/null
+++ b/doc/analyzers/MsgPack015.md
@@ -0,0 +1,42 @@
+# MsgPack015 MessagePackObjectAttribute.AllowPrivate should be set
+
+When a `[MessagePackObject]`-attributed type cannot be serialized without access to non-public members, the `AllowPrivate` property should be set on the `MessagePackObjectAttribute` so that:
+
+- Dynamically generated formatters can serialize the type, even if `DynamicObjectResolver` is used instead of `DynamicObjectResolverAllowPrivate`.
+- Analyzers can help ensure proper annotation of non-public members.
+
+## Examples of patterns that are flagged by this analyzer
+
+### Internal members
+
+```cs
+[MessagePackObject]
+public class MyData {
+ [Key(0)]
+ internal int Foo { get; set; }
+}
+```
+
+### Internal type
+
+```cs
+[MessagePackObject]
+internal class MyData {
+ [Key(0)]
+ public int Foo { get; set; }
+}
+```
+
+## Typical fix
+
+Simply add the `AllowPrivate = true` syntax to the `[MessagePackObject]` attribute:
+
+```cs
+[MessagePackObject(AllowPrivate = true)]
+internal class MyData {
+ [Key(0)]
+ internal int Foo { get; set; }
+}
+```
+
+An automated code fix is offered for this diagnostic.
diff --git a/doc/analyzers/MsgPack016.md b/doc/analyzers/MsgPack016.md
new file mode 100644
index 000000000..b38584880
--- /dev/null
+++ b/doc/analyzers/MsgPack016.md
@@ -0,0 +1,54 @@
+# MsgPack016 KeyAttribute-derived attributes are not supported by AOT formatters
+
+When a `[MessagePackObject]`-attributed type attributes its fields and properties with attributes that derive from `KeyAttribute` rather than from `KeyAttribute` itself, that type is incompatible with AOT source generated formatters.
+
+## Examples of patterns that are flagged by this analyzer
+
+```cs
+[MessagePackObject]
+public class A
+{
+ [CompositeKey(0, 1)]
+ public string Prop1 { get; set; }
+
+ [CompositeKey(0, 2)]
+ public string Prop2 { get; set; }
+}
+
+public class CompositeKeyAttribute : KeyAttribute
+{
+ public CompositeKeyAttribute(byte level, int index)
+ : base(CreateKey(level, index)) { }
+
+ private static string CreateKey(byte level, int index)
+ {
+ var c = (char)('A' + level);
+ return c + index.ToString("x");
+ }
+}
+```
+
+## Typical fix
+
+If you intend to keep using the derived attributes type, suppress the warning by turning off source generated formatter generation for that type:
+
+```diff
+-[MessagePackObject]
++[MessagePackObject(SuppressSourceGeneration = true)]
+ public class A
+```
+
+Alternatively, enable propery AOT formatter source generation by switching to the standard `KeyAttribute`:
+
+```cs
+[MessagePackObject]
+public class A
+{
+ [Key("A1")]
+ public string Prop1 { get; set; }
+
+ [Key("A2")]
+ public string Prop2 { get; set; }
+}
+```
+
diff --git a/doc/analyzers/MsgPack017.md b/doc/analyzers/MsgPack017.md
new file mode 100644
index 000000000..32bdd84c9
--- /dev/null
+++ b/doc/analyzers/MsgPack017.md
@@ -0,0 +1,87 @@
+# MsgPack017 Property with init accessor and initializer
+
+When a `[MessagePackObject]`-attributed type declares a serialized property with an `init` setter (as opposed to a typical `set` setter) and
+defines an initializer on that property, the default assigned by that initializer will be replaced with the default value for the type upon deserialization.
+
+## Examples of patterns that are flagged by this analyzer
+
+```cs
+[MessagePackObject]
+public class A
+{
+ [Key("Prop1")]
+ public string Prop1 { get; init; } = "This is the default."; // Diagnostic emitted here
+
+ [Key("Prop2")]
+ public string Prop2 { get; set; } = "Another default."
+
+ [Key("Prop3")]
+ public string Prop3 { get; set; }
+}
+```
+
+Deserializing this class may have unexpected behavior when a value is not given for `Prop1` during deserialization.
+Consider the case of deserializing the msgpack equivalent of the following data payload:
+
+```json
+{ "Prop3": "hello" }
+```
+
+One might expect that when `A` is deserialized, it will have the following data:
+
+Property | Value
+--|--
+Prop1 | "This is the default."
+Prop2 | "Another default.
+Prop3 | "hello"
+
+But in fact it will have the following values:
+
+Property | Value
+--|--
+Prop1 | null
+Prop2 | "Another default.
+Prop3 | "hello"
+
+This is because as an `init` property, the only way the AOT source generated formatter can set the property's value is in an object initializer, like this:
+
+```cs
+// Values here are replaced if a value is given in deserialized data.
+string deserializedProp1Value = default(string);
+string deserializedProp2Value = default(string);
+
+// Keep track of which values are actually specified.
+bool deserializedProp2Value_specified = false;
+
+// process msgpack data here, possibly replacing deserializedProp1Value with an actual value.
+
+A deserializedResult = new A
+{
+ Prop1 = deserializedProp1Value;
+}
+
+if (deserializedProp2Value_specified)
+ deserializedResult.Prop2 = deserializedProp2Value;
+
+return deserializedResult;
+```
+
+Notice how a property with a `set` setter may be conditionally set, and therefore it is only set when a value was specified by the data.
+But the property with an `init` setter may only be set in the object initializer, for which C# provides no means to set conditionally.
+
+## Typical fix
+
+If it is important to specify a default value that is different from the default value for the type (e.g. `null` for reference types or `0` for integers), you should declare a `set` accessor instead of an `init` accessor.
+
+```diff
+- public string Prop1 { get; init; } = "This is the default.";
++ public string Prop1 { get; set; } = "This is the default.";
+```
+
+Alternatively, disable source generated formatters for this type, forcing a dynamic one to be created at runtime which *does* have the ability to conditionally set the property.
+
+```diff
+-[MessagePackObject]
++[MessagePackObject(SuppressSourceGeneration = true)]
+ public class A
+```
diff --git a/doc/analyzers/MsgPack018.md b/doc/analyzers/MsgPack018.md
new file mode 100644
index 000000000..be7dc72f2
--- /dev/null
+++ b/doc/analyzers/MsgPack018.md
@@ -0,0 +1,56 @@
+# MsgPack018 Unique names required in force map mode
+
+`[MessagePackObject]`-attributed types may omit attributing each member with a `[Key]` attribute using forced map mode.
+In that mode, all serialized members *must* have unique names or a key collision would result in the serialized object.
+
+## Examples of patterns that are flagged by this analyzer
+
+```cs
+[MessagePackObject]
+public class A
+{
+ public string Prop1 { get; set; }
+}
+
+[MessagePackObject]
+public class B : A
+{
+ public new string Prop1 { get; set; } // Diagnostic reported here due to redefinition of Prop1
+}
+```
+
+## Typical fix
+
+Rename one of the colliding properties:
+
+```cs
+[MessagePackObject]
+public class A
+{
+ public string Prop1 { get; set; }
+}
+
+[MessagePackObject]
+public class B : A
+{
+ public string Prop2 { get; set; }
+}
+```
+
+Or add a `[Key]` attribute that assigns a unique serialized key to that member:
+
+
+```cs
+[MessagePackObject]
+public class A
+{
+ public string Prop1 { get; set; }
+}
+
+[MessagePackObject]
+public class B : A
+{
+ [Key("B_Prop1")]
+ public new string Prop1 { get; set; }
+}
+```
diff --git a/doc/analyzers/index.md b/doc/analyzers/index.md
index 0d2b17edb..38365b681 100644
--- a/doc/analyzers/index.md
+++ b/doc/analyzers/index.md
@@ -10,5 +10,18 @@ ID | Title
[MsgPack003](MsgPack003.md) | Use MessagePackObjectAttribute
[MsgPack004](MsgPack004.md) | Attribute public members of MessagePack objects
[MsgPack005](MsgPack005.md) | MessagePackObject validation
+[MsgPack006](MsgPack006.md) | Type must be of `IMessagePackFormatter`
+[MsgPack007](MsgPack007.md) | Deserializing constructors
+[MsgPack008](MsgPack008.md) | AOT limitations
+[MsgPack009](MsgPack009.md) | Colliding Formatters
+[MsgPack010](MsgPack010.md) | Inaccessible Formatter
+[MsgPack011](MsgPack011.md) | Partial type required
+[MsgPack012](MsgPack012.md) | Inaccessible data type
+[MsgPack013](MsgPack013.md) | Inaccessible formatter instance
+[MsgPack014](MsgPack014.md) | Nullable reference type formatter
+[MsgPack015](MsgPack015.md) | MessagePackObjectAttribute.AllowPrivate should be set
+[MsgPack016](MsgPack016.md) | KeyAttribute-derived attributes are not supported by AOT formatters
+[MsgPack017](MsgPack017.md) | Property with init accessor and initializer
+[MsgPack018](MsgPack018.md) | Unique names required in force map mode
[1]: https://nuget.org/packages/MessagePackAnalyzer
diff --git a/doc/mark_of_the_web.png b/doc/mark_of_the_web.png
new file mode 100644
index 000000000..634ea6123
Binary files /dev/null and b/doc/mark_of_the_web.png differ
diff --git a/doc/migrating_v1-v2.md b/doc/migrating_v1-v2.md
new file mode 100644
index 000000000..30bd34e47
--- /dev/null
+++ b/doc/migrating_v1-v2.md
@@ -0,0 +1,393 @@
+# Migrating from MessagePack v1.x to MessagePack v2.x
+
+MessagePack 2.0 contains many breaking changes since the 1.x versions.
+These include both binary and source breaking changes, meaning you may need to update your source code as well as recompile against the 2.x version.
+
+The v1.x version will still be serviced for security fixes, but new features will tend to only be offered in the 2.x versions.
+
+Update your package references from the 1.x version you use to the 2.x version. If your project compiles, you may be done.
+Otherwise work through each compiler error. Some common ones you may face are listed below with suggested fixes.
+
+If you own an application that has a mix of MessagePack consumers and not all of them can be upgraded to v2.x at once, you can offer both MessagePack v1.x and v2.x assemblies with your application so that each user can find the one it needs. [Here is a sample](https://github.com/AArnott/MessagePackDualVersions).
+
+## API changes
+
+### MessagePackSerializerOptions
+
+A new `MessagePackSerializerOptions` class becomes a first class citizen in this library.
+It encapsulates the `IFormatterResolver` that used to be passed around by itself.
+It also includes several other settings that may influence how `MessagePackSerializerOptions` or some of the
+formatters may operate.
+
+Because this new class tends to get saved to public static properties, it is immutable to ensure it can be shared safely.
+Each property `Foo` on the class includes a `WithFoo` method which clones the instance and returns the new instance with just that one property changed.
+
+To support this new options class and avoid unnecessary allocations from the copy-and-mutate methods, many of the popular resolvers now expose a public static `Options` property with the resolver preset to itself. So for example, you may use:
+
+```cs
+var msgpack = MessagePackSerializer.Serialize(objectGraph, StandardResolverAllowPrivate.Options);
+var deserializedGraph = MessagePackSerializer.Deserialize(msgpack, StandardResolverAllowPrivate.Options);
+```
+
+If you want to combine a particular resolver with other options changes (e.g. enabling LZ4 compression), you may do that too:
+
+```cs
+var options = StandardResolverAllowPrivate.Options.WithCompression(MessagePackCompression.Lz4BlockArray);
+var msgpack = MessagePackSerializer.Serialize(objectGraph, options);
+var deserializedGraph = MessagePackSerializer.Deserialize(msgpack, options);
+```
+
+An equivalent options instance can be created manually:
+
+```cs
+var options = MessagePackSerializerOptions.Standard
+ .WithCompression(MessagePackCompression.Lz4BlockArray)
+ .WithResolver(StandardResolverAllowPrivate.Instance);
+```
+
+### MessagePackSerializer class
+
+#### Serialization
+
+Serializing object graphs to msgpack is now based on `IBufferWriter` instead of `ref byte[]`.
+This allows for serializing very large object graphs without repeatedly allocating ever-larger arrays and copying the previously serialized msgpack bytes from the smaller buffer to the larger one.
+`IBufferWriter` can direct the written msgpack bytes directly to a pipe, a file, or anywhere else you choose, allowing you to avoid a buffer copy within your own code as well.
+
+An `IBufferWriter` is always wrapped by the new `MessagePackWriter` struct.
+
+Many overloads of the `Serialize` method exist which ultimately all call the overload that accepts a `MessagePackWriter`.
+
+#### Deserialization
+
+Deserializing msgpack sequences is now much more flexible.
+Instead of deserializing from `byte[]` or `ArraySegment` only, you can deserialize from any `ReadOnlyMemory` or `ReadOnlySequence` instance.
+
+`ReadOnlyMemory` is like `ArraySegment` but more friendly and can refer to contiguous memory anywhere including native pointers. You can pass a `byte[]` or `ArraySegment` in anywhere that `ReadOnlyMemory` is expected and C# will implicitly cast for you (without any buffer copying).
+
+`ReadOnlySequence` allows for deserialization from non-continguously allocated memory, enabling you to deserialize very large msgpack sequences without risking an `OutOfMemoryException` due simply to the inability to find large amounts of free contiguous memory.
+
+Many overloads of the `Deserialize` method exists which ultimately all call the overload that accepts a `MessagePackReader`.
+
+#### Deserializing from a Stream
+
+Deserializing from a `Stream` has changed from v1.x to v2.0. The `readStrict` parameter has been removed and in v2.x
+the `MessagePackSerializer.Deserialize{Async}(Stream)` methods act as if `readStrict: false` in v1.x.
+This works great and is the preferred API to use when the entire `Stream` is expected to contain exactly one
+top-level messagepack structure that you want to deserialize.
+
+For performance reasons, the entire `Stream` is read into memory before deserialization begins.
+If there is more data on the `Stream` than the messagepack structure to be deserialized,
+the deserialization will ignore the excess data, but the excess data wouldn't be on the `Stream`
+any more to be read later.
+
+If the `Stream` is seekable (that is, its `CanSeek` property returns `true`) then after deserialization
+is complete the `Stream` will be repositioned to the first byte after the messagepack data structure
+that was deserialized. This means you'll get the `Stream` back as you might expect it, but only after
+you paid a perf cost of "reading" more data than was necessary to deserialize.
+
+If the `Stream` is *not* seekable (e.g. a network stream) or contains multiple top-level messagepack
+data structures consecutively, MessagePack 2.0 adds a new, more performant way to read each
+messagepack structure. It's analogous to v1.x's `readStrict: true` mode, but is much more performant.
+It comes in the form of the new `MessagePackStreamReader` class, and can be easily used as follows:
+
+```cs
+static async Task> DeserializeListFromStreamAsync(Stream stream, CancellationToken cancellationToken)
+{
+ var dataStructures = new List();
+ using (var streamReader = new MessagePackStreamReader(stream))
+ {
+ while (await streamReader.ReadAsync(cancellationToken) is ReadOnlySequence msgpack)
+ {
+ dataStructures.Add(MessagePackSerializer.Deserialize(msgpack, cancellationToken: cancellationToken));
+ }
+ }
+
+ return dataStructures;
+}
+```
+
+#### Default behavior
+
+The `DefaultResolver` static property has been replaced with the `DefaultOptions` static property.
+Just as with v1.x, in v2.x this static property influences how serialization occurs
+when the value is not explicitly specified when invoking one of the `MessagePackSerializer` methods.
+
+**WARNING**: When developing a simple application where you control all MessagePack-related code it may be safe to rely on this mutable static to control behavior.
+For all other libraries or multi-purpose applications that use `MessagePackSerializer` you should explicitly specify the `MessagePackSerializerOptions` to use with each method invocation to guarantee your code behaves as you expect even when sharing an `AppDomain` or process with other MessagePack users that may change this static property.
+
+#### Non-generic methods
+
+In v1.x non-generic methods for serialization/deserialization were exposed on the nested `MessagePackSerializer.NonGeneric` class.
+In v2.x these overloads are moved to the `MessagePackSerializer` class itself.
+
+The `MessagePackSerializer.Typeless` nested class in v1.x remains in v2.x, but with a modified set of overloads.
+
+#### JSON converting methods
+
+In v1.x the `MessagePackSerializer` class exposed methods both to serialize an object graph to JSON,
+as well as converting between msgpack and JSON. These two translations were very different but were mere overloads of each other.
+In v2.x these methods have been renamed for clarity.
+The methods `ConvertFromJson` and `ConvertToJson` translates between JSON and msgpack binary.
+The method `SerializeToJson` translates an object graph to JSON.
+
+#### LZ4MessagePackSerializer
+
+The `LZ4MessagePackSerializer` class has been removed.
+Instead, use `MessagePackSerializer` and pass in a `MessagePackSerializerOptions` with `WithCompression` set to `MessagePackCompression.Lz4Block` or `MessagePackCompression.Lz4BlockArray`.
+
+For example, make this change:
+
+```diff
+-byte[] buffer = LZ4MessagePackSerializer.Serialize("hi");
++static readonly lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray);
++byte[] buffer = MessagePackSerializer.Serialize("hi", lz4Options);
+```
+
+`Lz4Block` is same as v1 LZ4MessagePackSerializer. `Lz4BlockArray` is new compression mode of v2. Regardless of which Lz4 option is set at the deserialization, both data can be deserialized. For example, when the option is `Lz4BlockArray`, binary data of both `Lz4Block` and `Lz4BlockArray` can be deserialized.
+
+### Thrown exceptions
+
+In v1.x any exception thrown during serialization or deserialization was uncaught and propagated to the application.
+In v2.x all exceptions are caught by the `MessagePackSerializer` and rethrown as an inner exception of `MessagePackSerializationException`.
+This makes it easier to write code to catch exceptions during serialization since you can now catch just one specific type of exception.
+
+### Built-in resolvers
+
+The following resolvers have been *removed*:
+
+| Removed v1.x formatter | v2.x alternative |
+|--|--|
+| `UnsafeBinaryResolver` | `NativeDecimalResolver`, `NativeGuidResolver`
+
+#### CompositeResolver
+
+In v1.x the `CompositeResolver` type could only be used once and mutated a static property.
+In v2.x the `CompositeResolver` type no longer mutates any statics and thus can be used safely by many callers that simply want to aggregate many formatters and/or resolvers into one resolver. This often removes the need for you to define your own `IFormatterResolver`.
+
+For example if you have written a custom formatter and want to use that in addition to what the `StandardResolver` offers, you can easily compose an aggregate resolver like this:
+
+```cs
+var resolver = CompositeResolver.Create(
+ new IMessagePackFormatter[] { MyCustomFormatter.Instance },
+ new IFormatterResolver[] { StandardResolver.Instance }
+);
+var options = MessagePackSerializerOptions.Standard.WithResolver(resolver);
+var msgpack = MessagePackSerializer.Serialize(objectGraph, options);
+var deserializedGraph = MessagePackSerializer.Deserialize(msgpack, options);
+```
+
+### Built-in formatters
+
+The following formatters have been *removed*:
+
+| Removed v1.x formatter | v2.x alternative |
+|--|--|
+| `BinaryDecimalFormatter` | `NativeDecimalFormatter`
+| `BinaryGuidFormatter` | `NativeGuidFormatter`
+| `FourDimentionalArrayFormatter` | `FourDimensionalArrayFormatter`
+| `OldSpecBinaryFormatter` | Use `MessagePackSerializerOptions.OldSpec` or `MessagePackWriter.OldSpec` instead.
+| `OldSpecStringFormatter` | Use `MessagePackSerializerOptions.OldSpec` or `MessagePackWriter.OldSpec` instead.
+| `QeueueFormatter` | `QueueFormatter`
+| `TaskUnitFormatter` | Store values instead of promises
+| `TaskValueFormatter` | Store values instead of promises
+| `ThreeDimentionalArrayFormatter` | `ThreeDimensionalArrayFormatter`
+| `TwoDimentionalArrayFormatter` | `TwoDimensionalArrayFormatter`
+| `ValueTaskFormatter` | Store values instead of promises
+
+A few formatters that remain have changed to remove mutable properties where those formatters may be exposed
+as public static instances. This helps to avoid malfunctions when one MessagePack user changes a static setting
+to suit their need but in a way that conflicts with another MessagePack user within the same process.
+
+#### `TypelessFormatter` changes
+
+The `TypelessFormatter.BindToType` static property has been removed.
+If you were using this property, you can find equivalent functionality in the virtual `Type MessagePackSerializerOptions.LoadType(string typeName)` method. The `TypelessFormatter` will call this method on
+the `MessagePackSerializerOptions` instance passed to it during deserialization.
+
+For example, you can override this virtual method in your own derived type:
+
+```cs
+class LoadTypeCustomizedOptions : MessagePackSerializerOptions
+{
+ internal LoadTypeCustomizedOptions(MessagePackSerializerOptions copyFrom)
+ : base(copyFrom)
+ {
+ }
+
+ internal LoadTypeCustomizedOptions(IFormatterResolver resolver)
+ : base(resolver)
+ {
+ }
+
+ public override Type LoadType(string typeName)
+ {
+ Type type = base.LoadType(typeName);
+ if (type == null)
+ {
+ // custom logic here
+ }
+
+ return type;
+ }
+}
+```
+
+You can then instantiate this options type and pass it to your deserializer:
+
+```cs
+var options = new LoadTypeCustomizedOptions(MessagePackSerializerOptions.Standard);
+T value = MessagePackSerializer.Deserialize(sequence, options);
+```
+
+### Custom formatters
+
+If you have written a custom `IMessagePackFormatter` implementation you will have to adapt to the interface changes and APIs used to implement such a class.
+
+The interface has been changed as described here:
+
+```diff
+ public interface IMessagePackFormatter : IMessagePackFormatter
+ {
+- int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver formatterResolver);
++ void Serialize(ref MessagePackWriter writer, T value, MessagePackSerializerOptions options);
+- T Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize);
++ T Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options);
+ }
+```
+
+Notice the simpler method signature for each method.
+You no longer have to deal with raw arrays and offsets.
+The `MessagePackBinary` static class from v1.x that a formatter used to write msgpack codes is replaced with `MessagePackWriter` and `MessagePackReader`.
+These two structs include the APIs to write and read msgpack, and they manage the underlying buffers so you no longer need to.
+
+Consider the following v1.x formatter for the `Int16` type:
+
+```cs
+class NullableInt16Formatter : IMessagePackFormatter
+{
+ public int Serialize(ref byte[] bytes, int offset, Int16? value, IFormatterResolver formatterResolver)
+ {
+ if (value == null)
+ {
+ return MessagePackBinary.WriteNil(ref bytes, offset);
+ }
+ else
+ {
+ return MessagePackBinary.WriteInt16(ref bytes, offset, value.Value);
+ }
+ }
+
+ public Int16? Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize)
+ {
+ if (MessagePackBinary.IsNil(bytes, offset))
+ {
+ readSize = 1;
+ return null;
+ }
+ else
+ {
+ return MessagePackBinary.ReadInt16(bytes, offset, out readSize);
+ }
+ }
+}
+```
+
+After migration for v2.x, it looks like this:
+
+```cs
+class NullableInt16Formatter : IMessagePackFormatter
+{
+ public void Serialize(ref MessagePackWriter writer, Int16? value, MessagePackSerializerOptions options)
+ {
+ if (value == null)
+ {
+ writer.WriteNil();
+ }
+ else
+ {
+ writer.Write(value.Value);
+ }
+ }
+
+ public Int16? Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
+ {
+ if (reader.TryReadNil())
+ {
+ return default;
+ }
+ else
+ {
+ return reader.ReadInt16();
+ }
+ }
+}
+```
+
+Notice the structure is very similar, but arrays and offsets are no longer necessary.
+The underlying msgpack format is unchanged, allowing code to be upgraded to v2.x while maintaining
+compatibility with a file or network party that uses MessagePack v1.x.
+
+#### Subtle change in method naming
+
+When writing integers, the method name pattern has changed such that although your v1.x->v2.0 code will compile
+it may produce slightly different (and less efficient) msgpack binary than before. Here is the translation table:
+
+|v1.x|v2.x|
+|--|--|
+|`MessagePackBinary.WriteMapHeaderForceMap32Block`|(removed)
+|`MessagePackBinary.WriteArrayHeaderForceArray32Block`|(removed)
+|`MessagePackBinary.WriteByteForceByteBlock`|`MessagePackWriter.WriteUInt8(byte)`
+|`MessagePackBinary.WriteSByteForceSByteBlock`|`MessagePackWriter.WriteInt8(sbyte)`
+|`MessagePackBinary.WriteInt16ForceInt16Block`|`MessagePackWriter.WriteInt16(short)`
+|`MessagePackBinary.WriteInt64ForceInt64Block`|`MessagePackWriter.WriteInt64(long)`
+|`MessagePackBinary.MessagePackBinary.WriteInt32ForceInt32Block`|`MessagePackWriter.WriteInt32(int)`
+|`MessagePackBinary.WriteUInt16ForceUInt16Block`|`MessagePackWriter.WriteUInt16(ushort)`
+|`MessagePackBinary.WriteUInt32ForceUInt32Block`|`MessagePackWriter.WriteUInt32(uint)`
+|`MessagePackBinary.WriteUInt64ForceUInt64Block`|`MessagePackWriter.WriteUInt64(ulong)`
+|`MessagePackBinary.WriteStringForceStr32Block`|(removed)
+|`MessagePackBinary.WriteExtensionFormatHeaderForceExt32Block`|(removed)
+|`MessagePackBinary.WriteMapHeader`|`MessagePackWriter.WriteMapHeader`
+|`MessagePackBinary.WriteArrayHeader`|`MessagePackWriter.WriteArrayHeader`
+|`MessagePackBinary.WriteByte`|`MessagePackWriter.Write(byte)`
+|`MessagePackBinary.WriteBytes`|`MessagePackWriter.Write(byte[])`
+|`MessagePackBinary.WriteSByte`|`MessagePackWriter.Write(sbyte)`
+|`MessagePackBinary.WriteSingle`|`MessagePackWriter.Write(float)`
+|`MessagePackBinary.WriteDouble`|`MessagePackWriter.Write(double)`
+|`MessagePackBinary.WriteInt16`|`MessagePackWriter.Write(short)`
+|`MessagePackBinary.WriteInt32`|`MessagePackWriter.Write(int)`
+|`MessagePackBinary.WriteInt64`|`MessagePackWriter.Write(long)`
+|`MessagePackBinary.WriteUInt16`|`MessagePackWriter.Write(ushort)`
+|`MessagePackBinary.WriteUInt32`|`MessagePackWriter.Write(uint)`
+|`MessagePackBinary.WriteUInt64`|`MessagePackWriter.Write(ulong)`
+|`MessagePackBinary.WriteChar`|`MessagePackWriter.Write(char)`
+|`MessagePackBinary.WriteStringBytes`|`MessagePackWriter.WriteString(ReadOnlySpan)`
+|`MessagePackBinary.WriteString`|`MessagePackWriter.Write(string)`
+|`MessagePackBinary.WriteExtensionFormatHeader`|`MessagePackWriter.WriteExtensionFormatHeader`
+|`MessagePackBinary.WriteExtensionFormat`|`MessagePackWriter.WriteExtensionFormat`
+|`MessagePackBinary.WriteDateTime`|`MessagePackWriter.Write(DateTime)` ([notes](#DateTime))
+
+The essence here is that you can typically just call `MessagePackWriter.Write(*)`
+for primitive types and the most efficient msgpack binary will be written out.
+You only should call the explicit `WriteX(x)` methods if you need to force a particular
+(fixed length) format of a value to be written out.
+
+As for the integer *reading* methods, these are much more interchangeable than in v1.x.
+You can call *any* `ReadInt*` or `ReadUInt*` method and it will successfully read an integer
+value and fit it into the desired return type so long as the value doesn't overflow.
+So for example you can call `Write(byte)` and later read the value with `ReadInt32()`.
+You can even call `Write(long)` and later read it with `ReadByte()` and it will work
+so long as the actual value fits inside a `byte`.
+An `OverflowException` is thrown if the integer value exceeds the max or min value
+that can be stored by the required return type.
+
+## Behavioral changes
+
+### DateTime
+
+When writing out `DateTime` v1.x would *always* call `DateTime.ToUniversalTime()` before serializing the value.
+In v2.x [we only call this method if `DateTime.Kind == DateTimeKind.Local`](https://github.com/neuecc/MessagePack-CSharp/pull/520/files).
+The impact of this is that if you were writing `DateTimeKind.Unspecified` the serialized value will no longer be changed
+under some unjustified assumption that the underlying value was `Local`.
+Your should specify `DateTimeKind` explicitly for all your `DateTime` values.
+When upgrading to MessagePack v2.x this is a breaking change if your `Unspecified` values actually represented the `Local`
+time zone and needed the conversion.
diff --git a/doc/migrating_v2-v3.md b/doc/migrating_v2-v3.md
new file mode 100644
index 000000000..9d3569470
--- /dev/null
+++ b/doc/migrating_v2-v3.md
@@ -0,0 +1,34 @@
+# Migrating from MessagePack v2 to v3
+
+The most significant change in v3 is that AOT source generation of formatters is on by default.
+These new formatters are comparable to the dynamic formatters generated at runtime in prior versions, but they have some limitations not shared by their dynamically generated counterparts.
+These limitation and other migration requirements and considerations are enumerated below or are called out by analyzers.
+
+The `MessagePackAnalyzer` nuget package, which was optional in v2, is now a nuget dependency, which means diagnostics may appear in your compilation after upgrading to v3 that you have not seen before.
+v3 adds many new diagnostic providers to the set of analyzers as well, with general help and specific help for handling the new source generated formatters.
+
+## Breaking Changes
+
+- `MessagePackAnalyzer.json` is no longer used to configure the analyzer.
+ Use `GeneratedMessagePackResolverAttribute`, `MessagePackKnownFormatterAttribute` and `MessagePackAssumedFormattableAttribute` instead.
+- The `mpc` CLI tool is no longer used to generate ahead-of-time (AOT) formatters and resolver.
+ AOT code generation is "on by default" in v3 courtesy of our roslyn source generator.
+- Custom implementations of `IMessagePackFormatter` should be `internal` for automatic inclusion in our source generated resolver.
+- Types annotated with `[MessagePackObject]` should be declared as `partial` to grant the source generated formatter access to private/protected members, when applicable.
+- Unity users:
+ - Use NuGetForUnity to acquire the `MessagePack` nuget package instead of acquiring source code via the .zip file on our Releases page.
+ - Unity 2021.3 is no longer supported. The minimum required version is 2022.3.12f1.
+
+## Adapting to breaking changes
+
+### Migrate your `MessagePackAnalyzer.json` file
+
+1. Add `[assembly: MessagePackAssumedFormattable(typeof(MyType1))]` to your project for each type that appears inside your `MessagePackAnalyzer.json` file.
+1. Delete the `MessagePackAnalyzer.json` file.
+
+### Migrate from `mpc`
+
+1. Remove any scripts that invoked `mpc` from your build.
+1. Follow the instructions in [the AOT section of the README](../README.md#aot) to create a source generated resolver (with formatters).
+
+Be sure to build with .NET SDK 6.0 or later.
diff --git a/doc/migration.md b/doc/migration.md
index 30bd34e47..a815c74f1 100644
--- a/doc/migration.md
+++ b/doc/migration.md
@@ -1,393 +1,4 @@
-# Migrating from MessagePack v1.x to MessagePack v2.x
+# Migration instructions
-MessagePack 2.0 contains many breaking changes since the 1.x versions.
-These include both binary and source breaking changes, meaning you may need to update your source code as well as recompile against the 2.x version.
-
-The v1.x version will still be serviced for security fixes, but new features will tend to only be offered in the 2.x versions.
-
-Update your package references from the 1.x version you use to the 2.x version. If your project compiles, you may be done.
-Otherwise work through each compiler error. Some common ones you may face are listed below with suggested fixes.
-
-If you own an application that has a mix of MessagePack consumers and not all of them can be upgraded to v2.x at once, you can offer both MessagePack v1.x and v2.x assemblies with your application so that each user can find the one it needs. [Here is a sample](https://github.com/AArnott/MessagePackDualVersions).
-
-## API changes
-
-### MessagePackSerializerOptions
-
-A new `MessagePackSerializerOptions` class becomes a first class citizen in this library.
-It encapsulates the `IFormatterResolver` that used to be passed around by itself.
-It also includes several other settings that may influence how `MessagePackSerializerOptions` or some of the
-formatters may operate.
-
-Because this new class tends to get saved to public static properties, it is immutable to ensure it can be shared safely.
-Each property `Foo` on the class includes a `WithFoo` method which clones the instance and returns the new instance with just that one property changed.
-
-To support this new options class and avoid unnecessary allocations from the copy-and-mutate methods, many of the popular resolvers now expose a public static `Options` property with the resolver preset to itself. So for example, you may use:
-
-```cs
-var msgpack = MessagePackSerializer.Serialize(objectGraph, StandardResolverAllowPrivate.Options);
-var deserializedGraph = MessagePackSerializer.Deserialize(msgpack, StandardResolverAllowPrivate.Options);
-```
-
-If you want to combine a particular resolver with other options changes (e.g. enabling LZ4 compression), you may do that too:
-
-```cs
-var options = StandardResolverAllowPrivate.Options.WithCompression(MessagePackCompression.Lz4BlockArray);
-var msgpack = MessagePackSerializer.Serialize(objectGraph, options);
-var deserializedGraph = MessagePackSerializer.Deserialize(msgpack, options);
-```
-
-An equivalent options instance can be created manually:
-
-```cs
-var options = MessagePackSerializerOptions.Standard
- .WithCompression(MessagePackCompression.Lz4BlockArray)
- .WithResolver(StandardResolverAllowPrivate.Instance);
-```
-
-### MessagePackSerializer class
-
-#### Serialization
-
-Serializing object graphs to msgpack is now based on `IBufferWriter` instead of `ref byte[]`.
-This allows for serializing very large object graphs without repeatedly allocating ever-larger arrays and copying the previously serialized msgpack bytes from the smaller buffer to the larger one.
-`IBufferWriter` can direct the written msgpack bytes directly to a pipe, a file, or anywhere else you choose, allowing you to avoid a buffer copy within your own code as well.
-
-An `IBufferWriter` is always wrapped by the new `MessagePackWriter` struct.
-
-Many overloads of the `Serialize` method exist which ultimately all call the overload that accepts a `MessagePackWriter`.
-
-#### Deserialization
-
-Deserializing msgpack sequences is now much more flexible.
-Instead of deserializing from `byte[]` or `ArraySegment` only, you can deserialize from any `ReadOnlyMemory` or `ReadOnlySequence` instance.
-
-`ReadOnlyMemory` is like `ArraySegment` but more friendly and can refer to contiguous memory anywhere including native pointers. You can pass a `byte[]` or `ArraySegment` in anywhere that `ReadOnlyMemory` is expected and C# will implicitly cast for you (without any buffer copying).
-
-`ReadOnlySequence` allows for deserialization from non-continguously allocated memory, enabling you to deserialize very large msgpack sequences without risking an `OutOfMemoryException` due simply to the inability to find large amounts of free contiguous memory.
-
-Many overloads of the `Deserialize` method exists which ultimately all call the overload that accepts a `MessagePackReader`.
-
-#### Deserializing from a Stream
-
-Deserializing from a `Stream` has changed from v1.x to v2.0. The `readStrict` parameter has been removed and in v2.x
-the `MessagePackSerializer.Deserialize{Async}(Stream)` methods act as if `readStrict: false` in v1.x.
-This works great and is the preferred API to use when the entire `Stream` is expected to contain exactly one
-top-level messagepack structure that you want to deserialize.
-
-For performance reasons, the entire `Stream` is read into memory before deserialization begins.
-If there is more data on the `Stream` than the messagepack structure to be deserialized,
-the deserialization will ignore the excess data, but the excess data wouldn't be on the `Stream`
-any more to be read later.
-
-If the `Stream` is seekable (that is, its `CanSeek` property returns `true`) then after deserialization
-is complete the `Stream` will be repositioned to the first byte after the messagepack data structure
-that was deserialized. This means you'll get the `Stream` back as you might expect it, but only after
-you paid a perf cost of "reading" more data than was necessary to deserialize.
-
-If the `Stream` is *not* seekable (e.g. a network stream) or contains multiple top-level messagepack
-data structures consecutively, MessagePack 2.0 adds a new, more performant way to read each
-messagepack structure. It's analogous to v1.x's `readStrict: true` mode, but is much more performant.
-It comes in the form of the new `MessagePackStreamReader` class, and can be easily used as follows:
-
-```cs
-static async Task> DeserializeListFromStreamAsync(Stream stream, CancellationToken cancellationToken)
-{
- var dataStructures = new List();
- using (var streamReader = new MessagePackStreamReader(stream))
- {
- while (await streamReader.ReadAsync(cancellationToken) is ReadOnlySequence msgpack)
- {
- dataStructures.Add(MessagePackSerializer.Deserialize(msgpack, cancellationToken: cancellationToken));
- }
- }
-
- return dataStructures;
-}
-```
-
-#### Default behavior
-
-The `DefaultResolver` static property has been replaced with the `DefaultOptions` static property.
-Just as with v1.x, in v2.x this static property influences how serialization occurs
-when the value is not explicitly specified when invoking one of the `MessagePackSerializer` methods.
-
-**WARNING**: When developing a simple application where you control all MessagePack-related code it may be safe to rely on this mutable static to control behavior.
-For all other libraries or multi-purpose applications that use `MessagePackSerializer` you should explicitly specify the `MessagePackSerializerOptions` to use with each method invocation to guarantee your code behaves as you expect even when sharing an `AppDomain` or process with other MessagePack users that may change this static property.
-
-#### Non-generic methods
-
-In v1.x non-generic methods for serialization/deserialization were exposed on the nested `MessagePackSerializer.NonGeneric` class.
-In v2.x these overloads are moved to the `MessagePackSerializer` class itself.
-
-The `MessagePackSerializer.Typeless` nested class in v1.x remains in v2.x, but with a modified set of overloads.
-
-#### JSON converting methods
-
-In v1.x the `MessagePackSerializer` class exposed methods both to serialize an object graph to JSON,
-as well as converting between msgpack and JSON. These two translations were very different but were mere overloads of each other.
-In v2.x these methods have been renamed for clarity.
-The methods `ConvertFromJson` and `ConvertToJson` translates between JSON and msgpack binary.
-The method `SerializeToJson` translates an object graph to JSON.
-
-#### LZ4MessagePackSerializer
-
-The `LZ4MessagePackSerializer` class has been removed.
-Instead, use `MessagePackSerializer` and pass in a `MessagePackSerializerOptions` with `WithCompression` set to `MessagePackCompression.Lz4Block` or `MessagePackCompression.Lz4BlockArray`.
-
-For example, make this change:
-
-```diff
--byte[] buffer = LZ4MessagePackSerializer.Serialize("hi");
-+static readonly lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray);
-+byte[] buffer = MessagePackSerializer.Serialize("hi", lz4Options);
-```
-
-`Lz4Block` is same as v1 LZ4MessagePackSerializer. `Lz4BlockArray` is new compression mode of v2. Regardless of which Lz4 option is set at the deserialization, both data can be deserialized. For example, when the option is `Lz4BlockArray`, binary data of both `Lz4Block` and `Lz4BlockArray` can be deserialized.
-
-### Thrown exceptions
-
-In v1.x any exception thrown during serialization or deserialization was uncaught and propagated to the application.
-In v2.x all exceptions are caught by the `MessagePackSerializer` and rethrown as an inner exception of `MessagePackSerializationException`.
-This makes it easier to write code to catch exceptions during serialization since you can now catch just one specific type of exception.
-
-### Built-in resolvers
-
-The following resolvers have been *removed*:
-
-| Removed v1.x formatter | v2.x alternative |
-|--|--|
-| `UnsafeBinaryResolver` | `NativeDecimalResolver`, `NativeGuidResolver`
-
-#### CompositeResolver
-
-In v1.x the `CompositeResolver` type could only be used once and mutated a static property.
-In v2.x the `CompositeResolver` type no longer mutates any statics and thus can be used safely by many callers that simply want to aggregate many formatters and/or resolvers into one resolver. This often removes the need for you to define your own `IFormatterResolver`.
-
-For example if you have written a custom formatter and want to use that in addition to what the `StandardResolver` offers, you can easily compose an aggregate resolver like this:
-
-```cs
-var resolver = CompositeResolver.Create(
- new IMessagePackFormatter[] { MyCustomFormatter.Instance },
- new IFormatterResolver[] { StandardResolver.Instance }
-);
-var options = MessagePackSerializerOptions.Standard.WithResolver(resolver);
-var msgpack = MessagePackSerializer.Serialize(objectGraph, options);
-var deserializedGraph = MessagePackSerializer.Deserialize(msgpack, options);
-```
-
-### Built-in formatters
-
-The following formatters have been *removed*:
-
-| Removed v1.x formatter | v2.x alternative |
-|--|--|
-| `BinaryDecimalFormatter` | `NativeDecimalFormatter`
-| `BinaryGuidFormatter` | `NativeGuidFormatter`
-| `FourDimentionalArrayFormatter` | `FourDimensionalArrayFormatter`
-| `OldSpecBinaryFormatter` | Use `MessagePackSerializerOptions.OldSpec` or `MessagePackWriter.OldSpec` instead.
-| `OldSpecStringFormatter` | Use `MessagePackSerializerOptions.OldSpec` or `MessagePackWriter.OldSpec` instead.
-| `QeueueFormatter` | `QueueFormatter`
-| `TaskUnitFormatter` | Store values instead of promises
-| `TaskValueFormatter` | Store values instead of promises
-| `ThreeDimentionalArrayFormatter` | `ThreeDimensionalArrayFormatter`
-| `TwoDimentionalArrayFormatter` | `TwoDimensionalArrayFormatter`
-| `ValueTaskFormatter` | Store values instead of promises
-
-A few formatters that remain have changed to remove mutable properties where those formatters may be exposed
-as public static instances. This helps to avoid malfunctions when one MessagePack user changes a static setting
-to suit their need but in a way that conflicts with another MessagePack user within the same process.
-
-#### `TypelessFormatter` changes
-
-The `TypelessFormatter.BindToType` static property has been removed.
-If you were using this property, you can find equivalent functionality in the virtual `Type MessagePackSerializerOptions.LoadType(string typeName)` method. The `TypelessFormatter` will call this method on
-the `MessagePackSerializerOptions` instance passed to it during deserialization.
-
-For example, you can override this virtual method in your own derived type:
-
-```cs
-class LoadTypeCustomizedOptions : MessagePackSerializerOptions
-{
- internal LoadTypeCustomizedOptions(MessagePackSerializerOptions copyFrom)
- : base(copyFrom)
- {
- }
-
- internal LoadTypeCustomizedOptions(IFormatterResolver resolver)
- : base(resolver)
- {
- }
-
- public override Type LoadType(string typeName)
- {
- Type type = base.LoadType(typeName);
- if (type == null)
- {
- // custom logic here
- }
-
- return type;
- }
-}
-```
-
-You can then instantiate this options type and pass it to your deserializer:
-
-```cs
-var options = new LoadTypeCustomizedOptions(MessagePackSerializerOptions.Standard);
-T value = MessagePackSerializer.Deserialize(sequence, options);
-```
-
-### Custom formatters
-
-If you have written a custom `IMessagePackFormatter` implementation you will have to adapt to the interface changes and APIs used to implement such a class.
-
-The interface has been changed as described here:
-
-```diff
- public interface IMessagePackFormatter : IMessagePackFormatter
- {
-- int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver formatterResolver);
-+ void Serialize(ref MessagePackWriter writer, T value, MessagePackSerializerOptions options);
-- T Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize);
-+ T Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options);
- }
-```
-
-Notice the simpler method signature for each method.
-You no longer have to deal with raw arrays and offsets.
-The `MessagePackBinary` static class from v1.x that a formatter used to write msgpack codes is replaced with `MessagePackWriter` and `MessagePackReader`.
-These two structs include the APIs to write and read msgpack, and they manage the underlying buffers so you no longer need to.
-
-Consider the following v1.x formatter for the `Int16` type:
-
-```cs
-class NullableInt16Formatter : IMessagePackFormatter
-{
- public int Serialize(ref byte[] bytes, int offset, Int16? value, IFormatterResolver formatterResolver)
- {
- if (value == null)
- {
- return MessagePackBinary.WriteNil(ref bytes, offset);
- }
- else
- {
- return MessagePackBinary.WriteInt16(ref bytes, offset, value.Value);
- }
- }
-
- public Int16? Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize)
- {
- if (MessagePackBinary.IsNil(bytes, offset))
- {
- readSize = 1;
- return null;
- }
- else
- {
- return MessagePackBinary.ReadInt16(bytes, offset, out readSize);
- }
- }
-}
-```
-
-After migration for v2.x, it looks like this:
-
-```cs
-class NullableInt16Formatter : IMessagePackFormatter
-{
- public void Serialize(ref MessagePackWriter writer, Int16? value, MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- }
- else
- {
- writer.Write(value.Value);
- }
- }
-
- public Int16? Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return default;
- }
- else
- {
- return reader.ReadInt16();
- }
- }
-}
-```
-
-Notice the structure is very similar, but arrays and offsets are no longer necessary.
-The underlying msgpack format is unchanged, allowing code to be upgraded to v2.x while maintaining
-compatibility with a file or network party that uses MessagePack v1.x.
-
-#### Subtle change in method naming
-
-When writing integers, the method name pattern has changed such that although your v1.x->v2.0 code will compile
-it may produce slightly different (and less efficient) msgpack binary than before. Here is the translation table:
-
-|v1.x|v2.x|
-|--|--|
-|`MessagePackBinary.WriteMapHeaderForceMap32Block`|(removed)
-|`MessagePackBinary.WriteArrayHeaderForceArray32Block`|(removed)
-|`MessagePackBinary.WriteByteForceByteBlock`|`MessagePackWriter.WriteUInt8(byte)`
-|`MessagePackBinary.WriteSByteForceSByteBlock`|`MessagePackWriter.WriteInt8(sbyte)`
-|`MessagePackBinary.WriteInt16ForceInt16Block`|`MessagePackWriter.WriteInt16(short)`
-|`MessagePackBinary.WriteInt64ForceInt64Block`|`MessagePackWriter.WriteInt64(long)`
-|`MessagePackBinary.MessagePackBinary.WriteInt32ForceInt32Block`|`MessagePackWriter.WriteInt32(int)`
-|`MessagePackBinary.WriteUInt16ForceUInt16Block`|`MessagePackWriter.WriteUInt16(ushort)`
-|`MessagePackBinary.WriteUInt32ForceUInt32Block`|`MessagePackWriter.WriteUInt32(uint)`
-|`MessagePackBinary.WriteUInt64ForceUInt64Block`|`MessagePackWriter.WriteUInt64(ulong)`
-|`MessagePackBinary.WriteStringForceStr32Block`|(removed)
-|`MessagePackBinary.WriteExtensionFormatHeaderForceExt32Block`|(removed)
-|`MessagePackBinary.WriteMapHeader`|`MessagePackWriter.WriteMapHeader`
-|`MessagePackBinary.WriteArrayHeader`|`MessagePackWriter.WriteArrayHeader`
-|`MessagePackBinary.WriteByte`|`MessagePackWriter.Write(byte)`
-|`MessagePackBinary.WriteBytes`|`MessagePackWriter.Write(byte[])`
-|`MessagePackBinary.WriteSByte`|`MessagePackWriter.Write(sbyte)`
-|`MessagePackBinary.WriteSingle`|`MessagePackWriter.Write(float)`
-|`MessagePackBinary.WriteDouble`|`MessagePackWriter.Write(double)`
-|`MessagePackBinary.WriteInt16`|`MessagePackWriter.Write(short)`
-|`MessagePackBinary.WriteInt32`|`MessagePackWriter.Write(int)`
-|`MessagePackBinary.WriteInt64`|`MessagePackWriter.Write(long)`
-|`MessagePackBinary.WriteUInt16`|`MessagePackWriter.Write(ushort)`
-|`MessagePackBinary.WriteUInt32`|`MessagePackWriter.Write(uint)`
-|`MessagePackBinary.WriteUInt64`|`MessagePackWriter.Write(ulong)`
-|`MessagePackBinary.WriteChar`|`MessagePackWriter.Write(char)`
-|`MessagePackBinary.WriteStringBytes`|`MessagePackWriter.WriteString(ReadOnlySpan)`
-|`MessagePackBinary.WriteString`|`MessagePackWriter.Write(string)`
-|`MessagePackBinary.WriteExtensionFormatHeader`|`MessagePackWriter.WriteExtensionFormatHeader`
-|`MessagePackBinary.WriteExtensionFormat`|`MessagePackWriter.WriteExtensionFormat`
-|`MessagePackBinary.WriteDateTime`|`MessagePackWriter.Write(DateTime)` ([notes](#DateTime))
-
-The essence here is that you can typically just call `MessagePackWriter.Write(*)`
-for primitive types and the most efficient msgpack binary will be written out.
-You only should call the explicit `WriteX(x)` methods if you need to force a particular
-(fixed length) format of a value to be written out.
-
-As for the integer *reading* methods, these are much more interchangeable than in v1.x.
-You can call *any* `ReadInt*` or `ReadUInt*` method and it will successfully read an integer
-value and fit it into the desired return type so long as the value doesn't overflow.
-So for example you can call `Write(byte)` and later read the value with `ReadInt32()`.
-You can even call `Write(long)` and later read it with `ReadByte()` and it will work
-so long as the actual value fits inside a `byte`.
-An `OverflowException` is thrown if the integer value exceeds the max or min value
-that can be stored by the required return type.
-
-## Behavioral changes
-
-### DateTime
-
-When writing out `DateTime` v1.x would *always* call `DateTime.ToUniversalTime()` before serializing the value.
-In v2.x [we only call this method if `DateTime.Kind == DateTimeKind.Local`](https://github.com/neuecc/MessagePack-CSharp/pull/520/files).
-The impact of this is that if you were writing `DateTimeKind.Unspecified` the serialized value will no longer be changed
-under some unjustified assumption that the underlying value was `Local`.
-Your should specify `DateTimeKind` explicitly for all your `DateTime` values.
-When upgrading to MessagePack v2.x this is a breaking change if your `Unspecified` values actually represented the `Local`
-time zone and needed the conversion.
+- [Migrating from MessagePack v1 to v2](migrating_v1-v2.md)
+- [Migrating from MessagePack v2 to v3](migrating_v2-v3.md)
diff --git a/doc/msbuildtask.md b/doc/msbuildtask.md
deleted file mode 100644
index 5b9d75c86..000000000
--- a/doc/msbuildtask.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# MessagePack Compiler via MSBuild Task
-
-Cold startup performance and AOT environments can benefit by pre-compiling the specialized code
-for serializing and deserializing your custom types.
-
-Install the `MessagePack.MSBuild.Tasks` NuGet package in your project:
- [](https://www.nuget.org/packages/MessagePack.MSBuild.Tasks)
-
-This package automatically gets the MessagePack Compiler (mpc) to run during the build to produce a source file in the intermediate directory and adds it to the compilation, consumable in the normal way:
-
-```cs
-using System;
-using MessagePack;
-using MessagePack.Resolvers;
-
-class Program
-{
- static void Main(string[] args)
- {
- var o = new SomeObject { SomeMember = "hi" };
-
- var options = MessagePackSerializerOptions.Standard.WithResolver(
- CompositeResolver.Create(
- GeneratedResolver.Instance,
- StandardResolver.Instance
- ));
- byte[] b = MessagePackSerializer.Serialize(o, options);
- var o2 = MessagePackSerializer.Deserialize(b, options);
- Console.WriteLine(o2.SomeMember);
- }
-}
-
-[MessagePackObject]
-public class SomeObject
-{
- [Key(0)]
- public string SomeMember { get; set; }
-}
-```
-
-## Customizations
-
-A few MSBuild properties can be set in your project to customize mpc:
-
-Property | Purpose | Default value
---|--|--
-`MessagePackGeneratedResolverNamespace` | The prefix for the namespace under which code will be generated. `.Formatters` is always appended to this value. | `MessagePack`
-`MessagePackGeneratedResolverName` | The name of the generated type. | `GeneratedResolver`
-`MessagePackGeneratedUsesMapMode` | A boolean value that indicates whether all formatters should use property maps instead of more compact arrays. | `false`
-
-For example you could add this xml to your project file to set each of the above properties (in this example, to their default values):
-
-```xml
-
- MessagePack
- GeneratedResolver
- false
-
-```
diff --git a/global.json b/global.json
index c83e939e8..088f23e11 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "8.0.300",
+ "version": "9.0.100",
"rollForward": "patch",
"allowPrerelease": false
}
diff --git a/init.ps1 b/init.ps1
index ad3b4145c..d5909d736 100755
--- a/init.ps1
+++ b/init.ps1
@@ -28,6 +28,8 @@
No effect if -NoPrerequisites is specified.
.PARAMETER NoRestore
Skips the package restore step.
+.PARAMETER NoToolRestore
+ Skips the dotnet tool restore step.
.PARAMETER AccessToken
An optional access token for authenticating to Azure Artifacts authenticated feeds.
.PARAMETER Interactive
@@ -46,6 +48,8 @@ Param (
[Parameter()]
[switch]$NoRestore,
[Parameter()]
+ [switch]$NoToolRestore,
+ [Parameter()]
[string]$AccessToken,
[Parameter()]
[switch]$Interactive
@@ -63,12 +67,6 @@ if (!$NoPrerequisites) {
if ($LASTEXITCODE -eq 3010) {
Exit 3010
}
-
- # The procdump tool and env var is required for dotnet test to collect hang/crash dumps of tests.
- # But it only works on Windows.
- if ($env:OS -eq 'Windows_NT') {
- $EnvVars['PROCDUMP_PATH'] = & "$PSScriptRoot\azure-pipelines\Get-ProcDump.ps1"
- }
}
# Workaround nuget credential provider bug that causes very unreliable package restores on Azure Pipelines
@@ -79,13 +77,12 @@ Push-Location $PSScriptRoot
try {
$HeaderColor = 'Green'
- if (!$NoRestore -and $PSCmdlet.ShouldProcess("NuGet packages", "Restore")) {
- $RestoreArguments = @()
- if ($Interactive)
- {
- $RestoreArguments += '--interactive'
- }
+ $RestoreArguments = @()
+ if ($Interactive) {
+ $RestoreArguments += '--interactive'
+ }
+ if (!$NoRestore -and $PSCmdlet.ShouldProcess("NuGet packages", "Restore")) {
Write-Host "Restoring NuGet packages" -ForegroundColor $HeaderColor
dotnet restore @RestoreArguments
if ($lastexitcode -ne 0) {
@@ -93,6 +90,13 @@ try {
}
}
+ if (!$NoToolRestore -and $PSCmdlet.ShouldProcess("dotnet tool", "restore")) {
+ dotnet tool restore @RestoreArguments
+ if ($lastexitcode -ne 0) {
+ throw "Failure while restoring dotnet CLI tools."
+ }
+ }
+
& "$PSScriptRoot/tools/Set-EnvVars.ps1" -Variables $EnvVars -PrependPath $PrependPath | Out-Null
}
catch {
diff --git a/nuget.config b/nuget.config
index 2ed04eeb6..ba780d4f6 100644
--- a/nuget.config
+++ b/nuget.config
@@ -7,9 +7,20 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prepare_release.ps1 b/prepare_release.ps1
deleted file mode 100644
index d5dc21d6f..000000000
--- a/prepare_release.ps1
+++ /dev/null
@@ -1,14 +0,0 @@
-# Calculate the NPM package version, assuming the version change is in a new commit.
-git commit --allow-empty -m "Dummy commit" -q
-$NpmPackageVersion = (nbgv get-version -f json | ConvertFrom-Json).NpmPackageVersion
-git reset --mixed HEAD~ -q
-
-# Stamp the version into the package.json file and commit.
-pushd $PSScriptRoot/src/MessagePack.UnityClient/Assets/Scripts/MessagePack
-npm version $NpmPackageVersion --no-git-tag-version --allow-same-version
-git add package.json
-popd
-git commit -m "Stamp unity package version as $NpmPackageVersion"
-
-# Tag the release
-nbgv tag
diff --git a/sandbox/.editorconfig b/sandbox/.editorconfig
new file mode 100644
index 000000000..c7bcd1010
--- /dev/null
+++ b/sandbox/.editorconfig
@@ -0,0 +1,4 @@
+[*.cs]
+
+# CA1062: Validate arguments of public methods
+dotnet_diagnostic.CA1062.severity = silent
diff --git a/sandbox/Directory.Build.props b/sandbox/Directory.Build.props
index 68555510b..6bbc1b411 100644
--- a/sandbox/Directory.Build.props
+++ b/sandbox/Directory.Build.props
@@ -1,6 +1,7 @@
-
+ true
false
+
diff --git a/sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj b/sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj
index 8d1a7c7e2..4b3e91d14 100644
--- a/sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj
+++ b/sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj
@@ -7,150 +7,172 @@
$(DefineConstants);DYNAMICCODEDUMPER
-
+
Code\Attributes.cs
-
+
+ Code\AnalyzerAttributes.cs
+
+
Code\BufferWriter.cs
-
+
Code\IMessagePackFormatter`1.cs
-
+
Code\NullableFormatter.cs
-
+
Code\DateTimeFormatters.cs
-
+
Code\IFormatterResolver.cs
-
+
Code\IMessagePackSerializationCallbackReceiver.cs
-
+
Code\AutomataDictionary.cs
-
+
+ Code\AutomataKeyGen.cs
+
+
Code\ThreadsafeTypeKeyHashTable.cs
-
+
Code\ByteArrayStringHashTable.cs
-
+
Code\CodeGenHelpers.cs
-
+
Code\RuntimeTypeHandleEqualityComparer.cs
-
+
Code\DynamicAssembly.cs
-
+
+ Code\DynamicAssemblyFactory.cs
+
+
Code\ExpressionUtility.cs
-
+
Code\FarmHash.cs
-
+
Code\ILGeneratorExtensions.cs
-
+
Code\ReflectionExtensions.cs
-
+
Code\UnsafeMemory.cs
-
+
Code\UnsafeMemory.Low.cs
-
+
Code\ExtensionHeader.cs
-
+
Code\ExtensionResult.cs
-
+
Code\MessagePackEventSource.cs
-
+
Code\MessagePackSerializerOptions.cs
-
+
Code\MessagePackSecurity.cs
-
- Code\SipHash.cs
-
-
+
Code\MonoProtection.cs
-
+
Code\HashCode.cs
-
+
Code\BitOperations.cs
-
+
Code\MessagePackCompression.cs
-
+
Code\MessagePackReader.cs
-
+
Code\MessagePackReader.Integers.cs
-
+
Code\MessagePackWriter.cs
-
+
+ Code\MessagePackPrimitives.Writers.cs
+
+
+ Code\MessagePackPrimitives.Readers.cs
+
+
+ Code\MessagePackPrimitives.Readers.Integers.cs
+
+
+ Code\SkipClrVisibilityChecks.cs
+
+
Code\SequencePool.cs
-
+
Code\SequenceReader.cs
-
+
Code\SequenceReaderExtensions.cs
-
+
Code\SafeBitConverter.cs
-
+
+ Code\SipHash.cs
+
+
Code\MessagePackCode.cs
-
+
Code\MessagePackSerializationException.cs
-
+
Code\Internal\DateTimeConstants.cs
-
+
Code\Nil.cs
-
+
Code\Utilities.cs
-
+
Code\DynamicEnumResolver.cs
-
+
Code\DynamicObjectResolver.cs
-
+
Code\DynamicUnionResolver.cs
-
+
Code\ResolverUtilities.cs
-
+
Code\StringEncoding.cs
-
+
Class1.cs
+
diff --git a/sandbox/DynamicCodeDumper/Program.cs b/sandbox/DynamicCodeDumper/Program.cs
index d9ec30cb4..1d24bcc16 100644
--- a/sandbox/DynamicCodeDumper/Program.cs
+++ b/sandbox/DynamicCodeDumper/Program.cs
@@ -80,10 +80,10 @@ private static void Main(string[] args)
}
finally
{
- AssemblyBuilder a1 = DynamicObjectResolver.Instance.Save();
- AssemblyBuilder a2 = DynamicUnionResolver.Instance.Save();
- AssemblyBuilder a3 = DynamicEnumResolver.Instance.Save();
- AssemblyBuilder a4 = DynamicContractlessObjectResolver.Instance.Save();
+ AssemblyBuilder? a1 = DynamicObjectResolver.Instance.Save();
+ AssemblyBuilder? a2 = DynamicUnionResolver.Instance.Save();
+ AssemblyBuilder? a3 = DynamicEnumResolver.Instance.Save();
+ AssemblyBuilder? a4 = DynamicContractlessObjectResolver.Instance.Save();
////var a5 = AutomataKeyGen.Save();
////Verify(a5);
@@ -467,3 +467,13 @@ public EntityBase()
//// }
////}
}
+
+
+#pragma warning disable
+
+namespace MessagePack.Internal
+{
+ internal sealed class PreserveAttribute : System.Attribute
+ {
+ }
+}
diff --git a/sandbox/MessagePack.Internal/MessagePack.Internal.csproj b/sandbox/MessagePack.Internal/MessagePack.Internal.csproj
index bc7d5d8d4..6aaf526a6 100644
--- a/sandbox/MessagePack.Internal/MessagePack.Internal.csproj
+++ b/sandbox/MessagePack.Internal/MessagePack.Internal.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0
enable
$(DefineConstants);SPAN_BUILTIN;MESSAGEPACK_INTERNAL
true
@@ -16,23 +16,27 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sandbox/PerfBenchmarkDotNet/DeserializeBenchmark.cs b/sandbox/PerfBenchmarkDotNet/DeserializeBenchmark.cs
index 68af163a9..15127517e 100644
--- a/sandbox/PerfBenchmarkDotNet/DeserializeBenchmark.cs
+++ b/sandbox/PerfBenchmarkDotNet/DeserializeBenchmark.cs
@@ -96,6 +96,7 @@ public StringKeySerializerTarget Typeless_StringKey()
return (StringKeySerializerTarget)newmsgpack.MessagePack.MessagePackSerializer.Typeless.Deserialize(typelessWithStringKeyObj);
}
+#if MsgPackCli
[Benchmark]
public IntKeySerializerTarget MsgPackCliMap()
{
@@ -107,7 +108,9 @@ public IntKeySerializerTarget MsgPackCliArray()
{
return arrayContext.GetSerializer().UnpackSingleObject(arrayObj);
}
+#endif
+#if Protobuf
[Benchmark]
public IntKeySerializerTarget ProtobufNet()
{
@@ -116,7 +119,9 @@ public IntKeySerializerTarget ProtobufNet()
return ProtoBuf.Serializer.Deserialize(ms);
}
}
+#endif
+#if Hyperion
[Benchmark]
public IntKeySerializerTarget Hyperion()
{
@@ -125,7 +130,9 @@ public IntKeySerializerTarget Hyperion()
return hyperionSerializer.Deserialize(ms);
}
}
+#endif
+#if NewtonsoftJson
[Benchmark]
public IntKeySerializerTarget JsonNetString()
{
@@ -142,7 +149,9 @@ public IntKeySerializerTarget JsonNetStreamReader()
return jsonSerialzier.Deserialize(jr);
}
}
+#endif
+#if Jil
[Benchmark]
public IntKeySerializerTarget JilString()
{
@@ -158,9 +167,6 @@ public IntKeySerializerTarget JilStreamReader()
return Jil.JSON.Deserialize(sr);
}
}
+#endif
}
}
-
-#pragma warning restore SA1200 // Using directives should be placed correctly
-#pragma warning restore SA1403 // File may only contain a single namespace
-
diff --git a/sandbox/PerfBenchmarkDotNet/Lz4Benchmark.cs b/sandbox/PerfBenchmarkDotNet/Lz4Benchmark.cs
index 8ac52e8ec..2d476656e 100644
--- a/sandbox/PerfBenchmarkDotNet/Lz4Benchmark.cs
+++ b/sandbox/PerfBenchmarkDotNet/Lz4Benchmark.cs
@@ -53,7 +53,3 @@ public void Setup()
public StringKeySerializerTarget2[] DeserializeLz4BlockArray() => MessagePackSerializer.Deserialize(binLz4ContiguousBlock, lz4ContiguousBlockOptions);
}
}
-
-#pragma warning restore SA1200 // Using directives should be placed correctly
-#pragma warning restore SA1403 // File may only contain a single namespace
-
diff --git a/sandbox/PerfBenchmarkDotNet/Lz4PrimitiveBenchmark.cs b/sandbox/PerfBenchmarkDotNet/Lz4PrimitiveBenchmark.cs
index f2d8c47b7..c00cf7f0b 100644
--- a/sandbox/PerfBenchmarkDotNet/Lz4PrimitiveBenchmark.cs
+++ b/sandbox/PerfBenchmarkDotNet/Lz4PrimitiveBenchmark.cs
@@ -50,7 +50,3 @@ public void Setup()
public int DeserializeLz4BlockArray() => MessagePackSerializer.Deserialize(binLz4ContiguousBlock, lz4ContiguousBlockOptions);
}
}
-
-#pragma warning restore SA1200 // Using directives should be placed correctly
-#pragma warning restore SA1403 // File may only contain a single namespace
-
diff --git a/sandbox/PerfBenchmarkDotNet/MessagePackReaderBenchmark.cs b/sandbox/PerfBenchmarkDotNet/MessagePackReaderBenchmark.cs
index b41e6258d..2ecceaffb 100644
--- a/sandbox/PerfBenchmarkDotNet/MessagePackReaderBenchmark.cs
+++ b/sandbox/PerfBenchmarkDotNet/MessagePackReaderBenchmark.cs
@@ -7,7 +7,6 @@
using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
-using Nerdbank.Streams;
namespace PerfBenchmarkDotNet
{
@@ -29,6 +28,19 @@ public void GlobalSetup()
[Benchmark(OperationsPerInvoke = BufferLength)]
[BenchmarkCategory("2.0")]
+ public void ReadBytePrimitiveInt32()
+ {
+ int offset = 0;
+ ReadOnlySpan buffer = this.buffer;
+ for (int i = 0; i < this.buffer.Length; i++)
+ {
+ newmsgpack::MessagePack.MessagePackPrimitives.TryReadInt32(buffer.Slice(offset), out int value, out var readSize);
+ offset += readSize;
+ }
+ }
+
+ [Benchmark(OperationsPerInvoke = BufferLength, Baseline = true)]
+ [BenchmarkCategory("2.0")]
public void ReadByte20()
{
var reader = new newmsgpack::MessagePack.MessagePackReader(this.buffer);
diff --git a/sandbox/PerfBenchmarkDotNet/PerfBenchmarkDotNet.csproj b/sandbox/PerfBenchmarkDotNet/PerfBenchmarkDotNet.csproj
index 4dbab7b25..26d20cfa3 100644
--- a/sandbox/PerfBenchmarkDotNet/PerfBenchmarkDotNet.csproj
+++ b/sandbox/PerfBenchmarkDotNet/PerfBenchmarkDotNet.csproj
@@ -1,10 +1,26 @@
Exe
- net472;net7.0
+ net472;net8.0
true
true
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+
+ $(DefineConstants);Jil
+ $(DefineConstants);MsgPackCli
+ $(DefineConstants);Protobuf
+ $(DefineConstants);ZeroFormatter
+ $(DefineConstants);NewtonsoftJson
+ $(DefineConstants);Hyperion
+
False
@@ -17,13 +33,11 @@
-
-
diff --git a/sandbox/PerfBenchmarkDotNet/SerializeBenchmark.cs b/sandbox/PerfBenchmarkDotNet/SerializeBenchmark.cs
index fc9a3a06d..b3301150a 100644
--- a/sandbox/PerfBenchmarkDotNet/SerializeBenchmark.cs
+++ b/sandbox/PerfBenchmarkDotNet/SerializeBenchmark.cs
@@ -22,7 +22,7 @@ public class SerializeBenchmark
{
private static MsgPack.Serialization.SerializationContext mapContext = new MsgPack.Serialization.SerializationContext { SerializationMethod = SerializationMethod.Map };
private static MsgPack.Serialization.SerializationContext arrayContext = new MsgPack.Serialization.SerializationContext { SerializationMethod = SerializationMethod.Array };
- private static JsonSerializer jsonSerialzier = new JsonSerializer();
+ private static JsonSerializer jsonSerializer = new JsonSerializer();
private static Hyperion.Serializer hyperionSerializer = new Hyperion.Serializer();
private static newmsgpack::MessagePack.IFormatterResolver mpcGenFormatterResolver = new Resolver(new StringKeySerializerTargetFormatter_MpcGeneratedAutomata());
private static newmsgpack::MessagePack.IFormatterResolver mpcGenDictFormatterResolver = new Resolver(new StringKeySerializerTargetFormatter_MpcGeneratedDictionary());
@@ -59,6 +59,7 @@ public byte[] Typeless_StringKey()
return newmsgpack.MessagePack.MessagePackSerializer.Typeless.Serialize(stringData);
}
+#if MsgPackCli
[Benchmark]
public byte[] MsgPackCliMap()
{
@@ -70,7 +71,9 @@ public byte[] MsgPackCliArray()
{
return arrayContext.GetSerializer().PackSingleObject(intData);
}
+#endif
+#if Protobuf
[Benchmark]
public byte[] ProtobufNet()
{
@@ -80,7 +83,9 @@ public byte[] ProtobufNet()
return ms.ToArray();
}
}
+#endif
+#if Hyperion
[Benchmark]
public byte[] Hyperion()
{
@@ -90,13 +95,17 @@ public byte[] Hyperion()
return ms.ToArray();
}
}
+#endif
+#if ZeroFormatter
[Benchmark]
public byte[] ZeroFormatter()
{
return ZeroFormatterSerializer.Serialize(intData);
}
+#endif
+#if NewtonsoftJson
[Benchmark]
public byte[] JsonNetString()
{
@@ -111,13 +120,15 @@ public byte[] JsonNetStreamWriter()
using (var sr = new StreamWriter(ms, Encoding.UTF8))
using (var jr = new JsonTextWriter(sr))
{
- jsonSerialzier.Serialize(jr, intData);
+ jsonSerializer.Serialize(jr, intData);
}
return ms.ToArray();
}
}
+#endif
+#if Jil
[Benchmark]
public byte[] JilString()
{
@@ -137,6 +148,7 @@ public byte[] JilStreamWriter()
return ms.ToArray();
}
}
+#endif
}
}
diff --git a/sandbox/PerfBenchmarkDotNet/TypelessDeserializeBenchmark.cs b/sandbox/PerfBenchmarkDotNet/TypelessDeserializeBenchmark.cs
index 8f6b23bd2..b6dfa5f50 100644
--- a/sandbox/PerfBenchmarkDotNet/TypelessDeserializeBenchmark.cs
+++ b/sandbox/PerfBenchmarkDotNet/TypelessDeserializeBenchmark.cs
@@ -73,7 +73,3 @@ public TypelessPrimitiveType MessagePackSerializer_Deserialize_TypelessContractl
}
}
}
-
-#pragma warning restore SA1200 // Using directives should be placed correctly
-#pragma warning restore SA1403 // File may only contain a single namespace
-
diff --git a/sandbox/PerfNetFramework/PerfNetFramework.csproj b/sandbox/PerfNetFramework/PerfNetFramework.csproj
index e97936e7e..321dced72 100644
--- a/sandbox/PerfNetFramework/PerfNetFramework.csproj
+++ b/sandbox/PerfNetFramework/PerfNetFramework.csproj
@@ -1,7 +1,7 @@
Exe
- net472;net7.0
+ net472;net8.0
true
diff --git a/sandbox/PerfNetFramework/README.md b/sandbox/PerfNetFramework/README.md
index f91fa842c..8c791a766 100644
--- a/sandbox/PerfNetFramework/README.md
+++ b/sandbox/PerfNetFramework/README.md
@@ -10,7 +10,7 @@ When collecting ETL traces, use these settings in the Collect->Run dialog:
| Setting | Value |
|-------------|-------|
-| Command | `dotnet run -c release -p .\sandbox\PerfNetFramework\ -f net472 --no-build`
+| Command | `dotnet run -c release --project .\sandbox\PerfNetFramework\ -f net472 --no-build`
| Current Dir | `d:\git\messagepack-csharp` (or wherever your enlistment is)
| Additional Providers | `*MessagePack-Benchmark`
| No V3.X NGen | Checked
diff --git a/sandbox/Sandbox/Generated.cs b/sandbox/Sandbox/Generated.cs
deleted file mode 100644
index 696478189..000000000
--- a/sandbox/Sandbox/Generated.cs
+++ /dev/null
@@ -1,4481 +0,0 @@
-//
-// THIS (.cs) FILE IS GENERATED BY MPC(MessagePack-CSharp). DO NOT CHANGE IT.
-//
-
-#pragma warning disable 618
-#pragma warning disable 612
-#pragma warning disable 414
-#pragma warning disable 168
-#pragma warning disable CS1591 // document public APIs
-
-#pragma warning disable SA1312 // Variable names should begin with lower-case letter
-#pragma warning disable SA1649 // File name should match first type name
-
-namespace MessagePack.Resolvers
-{
- public class GeneratedResolver : global::MessagePack.IFormatterResolver
- {
- public static readonly global::MessagePack.IFormatterResolver Instance = new GeneratedResolver();
-
- private GeneratedResolver()
- {
- }
-
- public global::MessagePack.Formatters.IMessagePackFormatter GetFormatter()
- {
- return FormatterCache.Formatter;
- }
-
- private static class FormatterCache
- {
- internal static readonly global::MessagePack.Formatters.IMessagePackFormatter Formatter;
-
- static FormatterCache()
- {
- var f = GeneratedResolverGetFormatterHelper.GetFormatter(typeof(T));
- if (f != null)
- {
- Formatter = (global::MessagePack.Formatters.IMessagePackFormatter)f;
- }
- }
- }
- }
-
- internal static class GeneratedResolverGetFormatterHelper
- {
- private static readonly global::System.Collections.Generic.Dictionary lookup;
-
- static GeneratedResolverGetFormatterHelper()
- {
- lookup = new global::System.Collections.Generic.Dictionary(72)
- {
- { typeof(global::GlobalMyEnum[,]), 0 },
- { typeof(global::GlobalMyEnum[]), 1 },
- { typeof(global::QuestMessageBody[]), 2 },
- { typeof(global::System.Collections.Generic.IDictionary), 3 },
- { typeof(global::System.Collections.Generic.IList), 4 },
- { typeof(int[,,,]), 5 },
- { typeof(int[,,]), 6 },
- { typeof(int[,]), 7 },
- { typeof(global::GlobalMyEnum), 8 },
- { typeof(global::SharedData.ByteEnum), 9 },
- { typeof(global::IMessageBody), 10 },
- { typeof(global::SharedData.IIVersioningUnion), 11 },
- { typeof(global::SharedData.IUnionChecker), 12 },
- { typeof(global::SharedData.IUnionChecker2), 13 },
- { typeof(global::SharedData.IUnionSample), 14 },
- { typeof(global::SharedData.RootUnionType), 15 },
- { typeof(global::Abcdefg.Efcdigjl.Ateatatea.Hgfagfafgad.TnonodsfarnoiuAtatqaga), 16 },
- { typeof(global::ArrayTestTest), 17 },
- { typeof(global::ComplexModel), 18 },
- { typeof(global::GlobalMan), 19 },
- { typeof(global::Message), 20 },
- { typeof(global::MessagePackFormatterFieldUser), 21 },
- { typeof(global::PerfBenchmarkDotNet.StringKeySerializerTarget), 22 },
- { typeof(global::QuestMessageBody), 23 },
- { typeof(global::SharedData.ArrayOptimizeClass), 24 },
- { typeof(global::SharedData.BarClass), 25 },
- { typeof(global::SharedData.Callback1), 26 },
- { typeof(global::SharedData.Callback1_2), 27 },
- { typeof(global::SharedData.Callback2), 28 },
- { typeof(global::SharedData.Callback2_2), 29 },
- { typeof(global::SharedData.DefaultValueIntKeyClassWithExplicitConstructor), 30 },
- { typeof(global::SharedData.DefaultValueIntKeyClassWithoutExplicitConstructor), 31 },
- { typeof(global::SharedData.DefaultValueIntKeyStructWithExplicitConstructor), 32 },
- { typeof(global::SharedData.DefaultValueStringKeyClassWithExplicitConstructor), 33 },
- { typeof(global::SharedData.DefaultValueStringKeyClassWithoutExplicitConstructor), 34 },
- { typeof(global::SharedData.DefaultValueStringKeyStructWithExplicitConstructor), 35 },
- { typeof(global::SharedData.Empty1), 36 },
- { typeof(global::SharedData.Empty2), 37 },
- { typeof(global::SharedData.EmptyClass), 38 },
- { typeof(global::SharedData.EmptyStruct), 39 },
- { typeof(global::SharedData.FirstSimpleData), 40 },
- { typeof(global::SharedData.FooClass), 41 },
- { typeof(global::SharedData.HolderV0), 42 },
- { typeof(global::SharedData.HolderV1), 43 },
- { typeof(global::SharedData.HolderV2), 44 },
- { typeof(global::SharedData.MyClass), 45 },
- { typeof(global::SharedData.MySubUnion1), 46 },
- { typeof(global::SharedData.MySubUnion2), 47 },
- { typeof(global::SharedData.MySubUnion3), 48 },
- { typeof(global::SharedData.MySubUnion4), 49 },
- { typeof(global::SharedData.NestParent.NestContract), 50 },
- { typeof(global::SharedData.NonEmpty1), 51 },
- { typeof(global::SharedData.NonEmpty2), 52 },
- { typeof(global::SharedData.SimpleIntKeyData), 53 },
- { typeof(global::SharedData.SimpleStringKeyData), 54 },
- { typeof(global::SharedData.SimpleStructIntKeyData), 55 },
- { typeof(global::SharedData.SimpleStructStringKeyData), 56 },
- { typeof(global::SharedData.SubUnionType1), 57 },
- { typeof(global::SharedData.SubUnionType2), 58 },
- { typeof(global::SharedData.UnVersionBlockTest), 59 },
- { typeof(global::SharedData.Vector2), 60 },
- { typeof(global::SharedData.Vector3Like), 61 },
- { typeof(global::SharedData.VectorLike2), 62 },
- { typeof(global::SharedData.Version0), 63 },
- { typeof(global::SharedData.Version1), 64 },
- { typeof(global::SharedData.Version2), 65 },
- { typeof(global::SharedData.VersionBlockTest), 66 },
- { typeof(global::SharedData.VersioningUnion), 67 },
- { typeof(global::SharedData.WithIndexer), 68 },
- { typeof(global::SimpleModel), 69 },
- { typeof(global::StampMessageBody), 70 },
- { typeof(global::TextMessageBody), 71 },
- };
- }
-
- internal static object GetFormatter(global::System.Type t)
- {
- int key;
- if (!lookup.TryGetValue(t, out key))
- {
- return null;
- }
-
- switch (key)
- {
- case 0: return new global::MessagePack.Formatters.TwoDimensionalArrayFormatter();
- case 1: return new global::MessagePack.Formatters.ArrayFormatter();
- case 2: return new global::MessagePack.Formatters.ArrayFormatter();
- case 3: return new global::MessagePack.Formatters.InterfaceDictionaryFormatter();
- case 4: return new global::MessagePack.Formatters.InterfaceListFormatter2();
- case 5: return new global::MessagePack.Formatters.FourDimensionalArrayFormatter();
- case 6: return new global::MessagePack.Formatters.ThreeDimensionalArrayFormatter();
- case 7: return new global::MessagePack.Formatters.TwoDimensionalArrayFormatter();
- case 8: return new MessagePack.Formatters.GlobalMyEnumFormatter();
- case 9: return new MessagePack.Formatters.SharedData.ByteEnumFormatter();
- case 10: return new MessagePack.Formatters.IMessageBodyFormatter();
- case 11: return new MessagePack.Formatters.SharedData.IIVersioningUnionFormatter();
- case 12: return new MessagePack.Formatters.SharedData.IUnionCheckerFormatter();
- case 13: return new MessagePack.Formatters.SharedData.IUnionChecker2Formatter();
- case 14: return new MessagePack.Formatters.SharedData.IUnionSampleFormatter();
- case 15: return new MessagePack.Formatters.SharedData.RootUnionTypeFormatter();
- case 16: return new MessagePack.Formatters.Abcdefg.Efcdigjl.Ateatatea.Hgfagfafgad.TnonodsfarnoiuAtatqagaFormatter();
- case 17: return new MessagePack.Formatters.ArrayTestTestFormatter();
- case 18: return new MessagePack.Formatters.ComplexModelFormatter();
- case 19: return new MessagePack.Formatters.GlobalManFormatter();
- case 20: return new MessagePack.Formatters.MessageFormatter();
- case 21: return new MessagePack.Formatters.MessagePackFormatterFieldUserFormatter();
- case 22: return new MessagePack.Formatters.PerfBenchmarkDotNet.StringKeySerializerTargetFormatter();
- case 23: return new MessagePack.Formatters.QuestMessageBodyFormatter();
- case 24: return new MessagePack.Formatters.SharedData.ArrayOptimizeClassFormatter();
- case 25: return new MessagePack.Formatters.SharedData.BarClassFormatter();
- case 26: return new MessagePack.Formatters.SharedData.Callback1Formatter();
- case 27: return new MessagePack.Formatters.SharedData.Callback1_2Formatter();
- case 28: return new MessagePack.Formatters.SharedData.Callback2Formatter();
- case 29: return new MessagePack.Formatters.SharedData.Callback2_2Formatter();
- case 30: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyClassWithExplicitConstructorFormatter();
- case 31: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyClassWithoutExplicitConstructorFormatter();
- case 32: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyStructWithExplicitConstructorFormatter();
- case 33: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyClassWithExplicitConstructorFormatter();
- case 34: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyClassWithoutExplicitConstructorFormatter();
- case 35: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyStructWithExplicitConstructorFormatter();
- case 36: return new MessagePack.Formatters.SharedData.Empty1Formatter();
- case 37: return new MessagePack.Formatters.SharedData.Empty2Formatter();
- case 38: return new MessagePack.Formatters.SharedData.EmptyClassFormatter();
- case 39: return new MessagePack.Formatters.SharedData.EmptyStructFormatter();
- case 40: return new MessagePack.Formatters.SharedData.FirstSimpleDataFormatter();
- case 41: return new MessagePack.Formatters.SharedData.FooClassFormatter();
- case 42: return new MessagePack.Formatters.SharedData.HolderV0Formatter();
- case 43: return new MessagePack.Formatters.SharedData.HolderV1Formatter();
- case 44: return new MessagePack.Formatters.SharedData.HolderV2Formatter();
- case 45: return new MessagePack.Formatters.SharedData.MyClassFormatter();
- case 46: return new MessagePack.Formatters.SharedData.MySubUnion1Formatter();
- case 47: return new MessagePack.Formatters.SharedData.MySubUnion2Formatter();
- case 48: return new MessagePack.Formatters.SharedData.MySubUnion3Formatter();
- case 49: return new MessagePack.Formatters.SharedData.MySubUnion4Formatter();
- case 50: return new MessagePack.Formatters.SharedData.NestParent_NestContractFormatter();
- case 51: return new MessagePack.Formatters.SharedData.NonEmpty1Formatter();
- case 52: return new MessagePack.Formatters.SharedData.NonEmpty2Formatter();
- case 53: return new MessagePack.Formatters.SharedData.SimpleIntKeyDataFormatter();
- case 54: return new MessagePack.Formatters.SharedData.SimpleStringKeyDataFormatter();
- case 55: return new MessagePack.Formatters.SharedData.SimpleStructIntKeyDataFormatter();
- case 56: return new MessagePack.Formatters.SharedData.SimpleStructStringKeyDataFormatter();
- case 57: return new MessagePack.Formatters.SharedData.SubUnionType1Formatter();
- case 58: return new MessagePack.Formatters.SharedData.SubUnionType2Formatter();
- case 59: return new MessagePack.Formatters.SharedData.UnVersionBlockTestFormatter();
- case 60: return new MessagePack.Formatters.SharedData.Vector2Formatter();
- case 61: return new MessagePack.Formatters.SharedData.Vector3LikeFormatter();
- case 62: return new MessagePack.Formatters.SharedData.VectorLike2Formatter();
- case 63: return new MessagePack.Formatters.SharedData.Version0Formatter();
- case 64: return new MessagePack.Formatters.SharedData.Version1Formatter();
- case 65: return new MessagePack.Formatters.SharedData.Version2Formatter();
- case 66: return new MessagePack.Formatters.SharedData.VersionBlockTestFormatter();
- case 67: return new MessagePack.Formatters.SharedData.VersioningUnionFormatter();
- case 68: return new MessagePack.Formatters.SharedData.WithIndexerFormatter();
- case 69: return new MessagePack.Formatters.SimpleModelFormatter();
- case 70: return new MessagePack.Formatters.StampMessageBodyFormatter();
- case 71: return new MessagePack.Formatters.TextMessageBodyFormatter();
- default: return null;
- }
- }
- }
-}
-
-#pragma warning restore 168
-#pragma warning restore 414
-#pragma warning restore 618
-#pragma warning restore 612
-
-#pragma warning restore SA1312 // Variable names should begin with lower-case letter
-#pragma warning restore SA1649 // File name should match first type name
-
-
-//
-// THIS (.cs) FILE IS GENERATED BY MPC(MessagePack-CSharp). DO NOT CHANGE IT.
-//
-
-#pragma warning disable 618
-#pragma warning disable 612
-#pragma warning disable 414
-#pragma warning disable 168
-#pragma warning disable CS1591 // document public APIs
-
-#pragma warning disable SA1403 // File may only contain a single namespace
-#pragma warning disable SA1649 // File name should match first type name
-
-namespace MessagePack.Formatters
-{
-
- public sealed class GlobalMyEnumFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::GlobalMyEnum value, global::MessagePack.MessagePackSerializerOptions options)
- {
- writer.Write((global::System.Int32)value);
- }
-
- public global::GlobalMyEnum Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- return (global::GlobalMyEnum)reader.ReadInt32();
- }
- }
-}
-
-#pragma warning restore 168
-#pragma warning restore 414
-#pragma warning restore 618
-#pragma warning restore 612
-
-#pragma warning restore SA1403 // File may only contain a single namespace
-#pragma warning restore SA1649 // File name should match first type name
-
-//
-// THIS (.cs) FILE IS GENERATED BY MPC(MessagePack-CSharp). DO NOT CHANGE IT.
-//
-
-#pragma warning disable 618
-#pragma warning disable 612
-#pragma warning disable 414
-#pragma warning disable 168
-#pragma warning disable CS1591 // document public APIs
-
-#pragma warning disable SA1403 // File may only contain a single namespace
-#pragma warning disable SA1649 // File name should match first type name
-
-namespace MessagePack.Formatters.SharedData
-{
-
- public sealed class ByteEnumFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SharedData.ByteEnum value, global::MessagePack.MessagePackSerializerOptions options)
- {
- writer.Write((global::System.Byte)value);
- }
-
- public global::SharedData.ByteEnum Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- return (global::SharedData.ByteEnum)reader.ReadByte();
- }
- }
-}
-
-#pragma warning restore 168
-#pragma warning restore 414
-#pragma warning restore 618
-#pragma warning restore 612
-
-#pragma warning restore SA1403 // File may only contain a single namespace
-#pragma warning restore SA1649 // File name should match first type name
-
-
-//
-// THIS (.cs) FILE IS GENERATED BY MPC(MessagePack-CSharp). DO NOT CHANGE IT.
-//
-
-#pragma warning disable 618
-#pragma warning disable 612
-#pragma warning disable 414
-#pragma warning disable 168
-#pragma warning disable CS1591 // document public APIs
-
-#pragma warning disable SA1403 // File may only contain a single namespace
-#pragma warning disable SA1649 // File name should match first type name
-
-namespace MessagePack.Formatters
-{
- public sealed class IMessageBodyFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
- private readonly global::System.Collections.Generic.Dictionary> typeToKeyAndJumpMap;
- private readonly global::System.Collections.Generic.Dictionary keyToJumpMap;
-
- public IMessageBodyFormatter()
- {
- this.typeToKeyAndJumpMap = new global::System.Collections.Generic.Dictionary>(3, global::MessagePack.Internal.RuntimeTypeHandleEqualityComparer.Default)
- {
- { typeof(global::TextMessageBody).TypeHandle, new global::System.Collections.Generic.KeyValuePair(10, 0) },
- { typeof(global::StampMessageBody).TypeHandle, new global::System.Collections.Generic.KeyValuePair(14, 1) },
- { typeof(global::QuestMessageBody).TypeHandle, new global::System.Collections.Generic.KeyValuePair(25, 2) },
- };
- this.keyToJumpMap = new global::System.Collections.Generic.Dictionary(3)
- {
- { 10, 0 },
- { 14, 1 },
- { 25, 2 },
- };
- }
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::IMessageBody value, global::MessagePack.MessagePackSerializerOptions options)
- {
- global::System.Collections.Generic.KeyValuePair keyValuePair;
- if (value != null && this.typeToKeyAndJumpMap.TryGetValue(value.GetType().TypeHandle, out keyValuePair))
- {
- writer.WriteArrayHeader(2);
- writer.WriteInt32(keyValuePair.Key);
- switch (keyValuePair.Value)
- {
- case 0:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::TextMessageBody)value, options);
- break;
- case 1:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::StampMessageBody)value, options);
- break;
- case 2:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::QuestMessageBody)value, options);
- break;
- default:
- break;
- }
-
- return;
- }
-
- writer.WriteNil();
- }
-
- public global::IMessageBody Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- if (reader.ReadArrayHeader() != 2)
- {
- throw new global::System.InvalidOperationException("Invalid Union data was detected. Type:global::IMessageBody");
- }
-
- options.Security.DepthStep(ref reader);
- var key = reader.ReadInt32();
-
- if (!this.keyToJumpMap.TryGetValue(key, out key))
- {
- key = -1;
- }
-
- global::IMessageBody result = null;
- switch (key)
- {
- case 0:
- result = (global::IMessageBody)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- case 1:
- result = (global::IMessageBody)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- case 2:
- result = (global::IMessageBody)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- default:
- reader.Skip();
- break;
- }
-
- reader.Depth--;
- return result;
- }
- }
-
-
-}
-
-#pragma warning restore 168
-#pragma warning restore 414
-#pragma warning restore 618
-#pragma warning restore 612
-
-#pragma warning restore SA1403 // File may only contain a single namespace
-#pragma warning restore SA1649 // File name should match first type name
-
-//
-// THIS (.cs) FILE IS GENERATED BY MPC(MessagePack-CSharp). DO NOT CHANGE IT.
-//
-
-#pragma warning disable 618
-#pragma warning disable 612
-#pragma warning disable 414
-#pragma warning disable 168
-#pragma warning disable CS1591 // document public APIs
-
-#pragma warning disable SA1403 // File may only contain a single namespace
-#pragma warning disable SA1649 // File name should match first type name
-
-namespace MessagePack.Formatters.SharedData
-{
- public sealed class IIVersioningUnionFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
- private readonly global::System.Collections.Generic.Dictionary> typeToKeyAndJumpMap;
- private readonly global::System.Collections.Generic.Dictionary keyToJumpMap;
-
- public IIVersioningUnionFormatter()
- {
- this.typeToKeyAndJumpMap = new global::System.Collections.Generic.Dictionary>(1, global::MessagePack.Internal.RuntimeTypeHandleEqualityComparer.Default)
- {
- { typeof(global::SharedData.MySubUnion1).TypeHandle, new global::System.Collections.Generic.KeyValuePair(0, 0) },
- };
- this.keyToJumpMap = new global::System.Collections.Generic.Dictionary(1)
- {
- { 0, 0 },
- };
- }
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SharedData.IIVersioningUnion value, global::MessagePack.MessagePackSerializerOptions options)
- {
- global::System.Collections.Generic.KeyValuePair keyValuePair;
- if (value != null && this.typeToKeyAndJumpMap.TryGetValue(value.GetType().TypeHandle, out keyValuePair))
- {
- writer.WriteArrayHeader(2);
- writer.WriteInt32(keyValuePair.Key);
- switch (keyValuePair.Value)
- {
- case 0:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::SharedData.MySubUnion1)value, options);
- break;
- default:
- break;
- }
-
- return;
- }
-
- writer.WriteNil();
- }
-
- public global::SharedData.IIVersioningUnion Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- if (reader.ReadArrayHeader() != 2)
- {
- throw new global::System.InvalidOperationException("Invalid Union data was detected. Type:global::SharedData.IIVersioningUnion");
- }
-
- options.Security.DepthStep(ref reader);
- var key = reader.ReadInt32();
-
- if (!this.keyToJumpMap.TryGetValue(key, out key))
- {
- key = -1;
- }
-
- global::SharedData.IIVersioningUnion result = null;
- switch (key)
- {
- case 0:
- result = (global::SharedData.IIVersioningUnion)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- default:
- reader.Skip();
- break;
- }
-
- reader.Depth--;
- return result;
- }
- }
-
- public sealed class IUnionCheckerFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
- private readonly global::System.Collections.Generic.Dictionary> typeToKeyAndJumpMap;
- private readonly global::System.Collections.Generic.Dictionary keyToJumpMap;
-
- public IUnionCheckerFormatter()
- {
- this.typeToKeyAndJumpMap = new global::System.Collections.Generic.Dictionary>(4, global::MessagePack.Internal.RuntimeTypeHandleEqualityComparer.Default)
- {
- { typeof(global::SharedData.MySubUnion1).TypeHandle, new global::System.Collections.Generic.KeyValuePair(0, 0) },
- { typeof(global::SharedData.MySubUnion2).TypeHandle, new global::System.Collections.Generic.KeyValuePair(1, 1) },
- { typeof(global::SharedData.MySubUnion3).TypeHandle, new global::System.Collections.Generic.KeyValuePair(2, 2) },
- { typeof(global::SharedData.MySubUnion4).TypeHandle, new global::System.Collections.Generic.KeyValuePair(3, 3) },
- };
- this.keyToJumpMap = new global::System.Collections.Generic.Dictionary(4)
- {
- { 0, 0 },
- { 1, 1 },
- { 2, 2 },
- { 3, 3 },
- };
- }
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SharedData.IUnionChecker value, global::MessagePack.MessagePackSerializerOptions options)
- {
- global::System.Collections.Generic.KeyValuePair keyValuePair;
- if (value != null && this.typeToKeyAndJumpMap.TryGetValue(value.GetType().TypeHandle, out keyValuePair))
- {
- writer.WriteArrayHeader(2);
- writer.WriteInt32(keyValuePair.Key);
- switch (keyValuePair.Value)
- {
- case 0:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::SharedData.MySubUnion1)value, options);
- break;
- case 1:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::SharedData.MySubUnion2)value, options);
- break;
- case 2:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::SharedData.MySubUnion3)value, options);
- break;
- case 3:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::SharedData.MySubUnion4)value, options);
- break;
- default:
- break;
- }
-
- return;
- }
-
- writer.WriteNil();
- }
-
- public global::SharedData.IUnionChecker Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- if (reader.ReadArrayHeader() != 2)
- {
- throw new global::System.InvalidOperationException("Invalid Union data was detected. Type:global::SharedData.IUnionChecker");
- }
-
- options.Security.DepthStep(ref reader);
- var key = reader.ReadInt32();
-
- if (!this.keyToJumpMap.TryGetValue(key, out key))
- {
- key = -1;
- }
-
- global::SharedData.IUnionChecker result = null;
- switch (key)
- {
- case 0:
- result = (global::SharedData.IUnionChecker)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- case 1:
- result = (global::SharedData.IUnionChecker)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- case 2:
- result = (global::SharedData.IUnionChecker)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- case 3:
- result = (global::SharedData.IUnionChecker)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- default:
- reader.Skip();
- break;
- }
-
- reader.Depth--;
- return result;
- }
- }
-
- public sealed class IUnionChecker2Formatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
- private readonly global::System.Collections.Generic.Dictionary> typeToKeyAndJumpMap;
- private readonly global::System.Collections.Generic.Dictionary keyToJumpMap;
-
- public IUnionChecker2Formatter()
- {
- this.typeToKeyAndJumpMap = new global::System.Collections.Generic.Dictionary>(4, global::MessagePack.Internal.RuntimeTypeHandleEqualityComparer.Default)
- {
- { typeof(global::SharedData.MySubUnion2).TypeHandle, new global::System.Collections.Generic.KeyValuePair(31, 0) },
- { typeof(global::SharedData.MySubUnion3).TypeHandle, new global::System.Collections.Generic.KeyValuePair(42, 1) },
- { typeof(global::SharedData.MySubUnion4).TypeHandle, new global::System.Collections.Generic.KeyValuePair(63, 2) },
- { typeof(global::SharedData.MySubUnion1).TypeHandle, new global::System.Collections.Generic.KeyValuePair(120, 3) },
- };
- this.keyToJumpMap = new global::System.Collections.Generic.Dictionary(4)
- {
- { 31, 0 },
- { 42, 1 },
- { 63, 2 },
- { 120, 3 },
- };
- }
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SharedData.IUnionChecker2 value, global::MessagePack.MessagePackSerializerOptions options)
- {
- global::System.Collections.Generic.KeyValuePair keyValuePair;
- if (value != null && this.typeToKeyAndJumpMap.TryGetValue(value.GetType().TypeHandle, out keyValuePair))
- {
- writer.WriteArrayHeader(2);
- writer.WriteInt32(keyValuePair.Key);
- switch (keyValuePair.Value)
- {
- case 0:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::SharedData.MySubUnion2)value, options);
- break;
- case 1:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::SharedData.MySubUnion3)value, options);
- break;
- case 2:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::SharedData.MySubUnion4)value, options);
- break;
- case 3:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::SharedData.MySubUnion1)value, options);
- break;
- default:
- break;
- }
-
- return;
- }
-
- writer.WriteNil();
- }
-
- public global::SharedData.IUnionChecker2 Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- if (reader.ReadArrayHeader() != 2)
- {
- throw new global::System.InvalidOperationException("Invalid Union data was detected. Type:global::SharedData.IUnionChecker2");
- }
-
- options.Security.DepthStep(ref reader);
- var key = reader.ReadInt32();
-
- if (!this.keyToJumpMap.TryGetValue(key, out key))
- {
- key = -1;
- }
-
- global::SharedData.IUnionChecker2 result = null;
- switch (key)
- {
- case 0:
- result = (global::SharedData.IUnionChecker2)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- case 1:
- result = (global::SharedData.IUnionChecker2)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- case 2:
- result = (global::SharedData.IUnionChecker2)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- case 3:
- result = (global::SharedData.IUnionChecker2)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- default:
- reader.Skip();
- break;
- }
-
- reader.Depth--;
- return result;
- }
- }
-
- public sealed class IUnionSampleFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
- private readonly global::System.Collections.Generic.Dictionary> typeToKeyAndJumpMap;
- private readonly global::System.Collections.Generic.Dictionary keyToJumpMap;
-
- public IUnionSampleFormatter()
- {
- this.typeToKeyAndJumpMap = new global::System.Collections.Generic.Dictionary>(2, global::MessagePack.Internal.RuntimeTypeHandleEqualityComparer.Default)
- {
- { typeof(global::SharedData.FooClass).TypeHandle, new global::System.Collections.Generic.KeyValuePair(0, 0) },
- { typeof(global::SharedData.BarClass).TypeHandle, new global::System.Collections.Generic.KeyValuePair(100, 1) },
- };
- this.keyToJumpMap = new global::System.Collections.Generic.Dictionary(2)
- {
- { 0, 0 },
- { 100, 1 },
- };
- }
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SharedData.IUnionSample value, global::MessagePack.MessagePackSerializerOptions options)
- {
- global::System.Collections.Generic.KeyValuePair keyValuePair;
- if (value != null && this.typeToKeyAndJumpMap.TryGetValue(value.GetType().TypeHandle, out keyValuePair))
- {
- writer.WriteArrayHeader(2);
- writer.WriteInt32(keyValuePair.Key);
- switch (keyValuePair.Value)
- {
- case 0:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::SharedData.FooClass)value, options);
- break;
- case 1:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::SharedData.BarClass)value, options);
- break;
- default:
- break;
- }
-
- return;
- }
-
- writer.WriteNil();
- }
-
- public global::SharedData.IUnionSample Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- if (reader.ReadArrayHeader() != 2)
- {
- throw new global::System.InvalidOperationException("Invalid Union data was detected. Type:global::SharedData.IUnionSample");
- }
-
- options.Security.DepthStep(ref reader);
- var key = reader.ReadInt32();
-
- if (!this.keyToJumpMap.TryGetValue(key, out key))
- {
- key = -1;
- }
-
- global::SharedData.IUnionSample result = null;
- switch (key)
- {
- case 0:
- result = (global::SharedData.IUnionSample)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- case 1:
- result = (global::SharedData.IUnionSample)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- default:
- reader.Skip();
- break;
- }
-
- reader.Depth--;
- return result;
- }
- }
-
- public sealed class RootUnionTypeFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
- private readonly global::System.Collections.Generic.Dictionary> typeToKeyAndJumpMap;
- private readonly global::System.Collections.Generic.Dictionary keyToJumpMap;
-
- public RootUnionTypeFormatter()
- {
- this.typeToKeyAndJumpMap = new global::System.Collections.Generic.Dictionary>(2, global::MessagePack.Internal.RuntimeTypeHandleEqualityComparer.Default)
- {
- { typeof(global::SharedData.SubUnionType1).TypeHandle, new global::System.Collections.Generic.KeyValuePair(0, 0) },
- { typeof(global::SharedData.SubUnionType2).TypeHandle, new global::System.Collections.Generic.KeyValuePair(1, 1) },
- };
- this.keyToJumpMap = new global::System.Collections.Generic.Dictionary(2)
- {
- { 0, 0 },
- { 1, 1 },
- };
- }
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SharedData.RootUnionType value, global::MessagePack.MessagePackSerializerOptions options)
- {
- global::System.Collections.Generic.KeyValuePair keyValuePair;
- if (value != null && this.typeToKeyAndJumpMap.TryGetValue(value.GetType().TypeHandle, out keyValuePair))
- {
- writer.WriteArrayHeader(2);
- writer.WriteInt32(keyValuePair.Key);
- switch (keyValuePair.Value)
- {
- case 0:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::SharedData.SubUnionType1)value, options);
- break;
- case 1:
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Serialize(ref writer, (global::SharedData.SubUnionType2)value, options);
- break;
- default:
- break;
- }
-
- return;
- }
-
- writer.WriteNil();
- }
-
- public global::SharedData.RootUnionType Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- if (reader.ReadArrayHeader() != 2)
- {
- throw new global::System.InvalidOperationException("Invalid Union data was detected. Type:global::SharedData.RootUnionType");
- }
-
- options.Security.DepthStep(ref reader);
- var key = reader.ReadInt32();
-
- if (!this.keyToJumpMap.TryGetValue(key, out key))
- {
- key = -1;
- }
-
- global::SharedData.RootUnionType result = null;
- switch (key)
- {
- case 0:
- result = (global::SharedData.RootUnionType)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- case 1:
- result = (global::SharedData.RootUnionType)global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(options.Resolver).Deserialize(ref reader, options);
- break;
- default:
- reader.Skip();
- break;
- }
-
- reader.Depth--;
- return result;
- }
- }
-
-
-}
-
-#pragma warning restore 168
-#pragma warning restore 414
-#pragma warning restore 618
-#pragma warning restore 612
-
-#pragma warning restore SA1403 // File may only contain a single namespace
-#pragma warning restore SA1649 // File name should match first type name
-
-
-//
-// THIS (.cs) FILE IS GENERATED BY MPC(MessagePack-CSharp). DO NOT CHANGE IT.
-//
-
-#pragma warning disable 618
-#pragma warning disable 612
-#pragma warning disable 414
-#pragma warning disable 168
-#pragma warning disable CS1591 // document public APIs
-
-#pragma warning disable SA1129 // Do not use default value type constructor
-#pragma warning disable SA1309 // Field names should not begin with underscore
-#pragma warning disable SA1312 // Variable names should begin with lower-case letter
-#pragma warning disable SA1403 // File may only contain a single namespace
-#pragma warning disable SA1649 // File name should match first type name
-
-namespace MessagePack.Formatters.Abcdefg.Efcdigjl.Ateatatea.Hgfagfafgad
-{
- public sealed class TnonodsfarnoiuAtatqagaFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::Abcdefg.Efcdigjl.Ateatatea.Hgfagfafgad.TnonodsfarnoiuAtatqaga value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- writer.WriteArrayHeader(1);
- writer.Write(value.MyProperty);
- }
-
- public global::Abcdefg.Efcdigjl.Ateatatea.Hgfagfafgad.TnonodsfarnoiuAtatqaga Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- var length = reader.ReadArrayHeader();
- var ____result = new global::Abcdefg.Efcdigjl.Ateatatea.Hgfagfafgad.TnonodsfarnoiuAtatqaga();
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- ____result.MyProperty = reader.ReadInt32();
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
-}
-
-#pragma warning restore 168
-#pragma warning restore 414
-#pragma warning restore 618
-#pragma warning restore 612
-
-#pragma warning restore SA1129 // Do not use default value type constructor
-#pragma warning restore SA1309 // Field names should not begin with underscore
-#pragma warning restore SA1312 // Variable names should begin with lower-case letter
-#pragma warning restore SA1403 // File may only contain a single namespace
-#pragma warning restore SA1649 // File name should match first type name
-
-//
-// THIS (.cs) FILE IS GENERATED BY MPC(MessagePack-CSharp). DO NOT CHANGE IT.
-//
-
-#pragma warning disable 618
-#pragma warning disable 612
-#pragma warning disable 414
-#pragma warning disable 168
-#pragma warning disable CS1591 // document public APIs
-
-#pragma warning disable SA1129 // Do not use default value type constructor
-#pragma warning disable SA1309 // Field names should not begin with underscore
-#pragma warning disable SA1312 // Variable names should begin with lower-case letter
-#pragma warning disable SA1403 // File may only contain a single namespace
-#pragma warning disable SA1649 // File name should match first type name
-
-namespace MessagePack.Formatters
-{
- public sealed class ArrayTestTestFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::ArrayTestTest value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- global::MessagePack.IFormatterResolver formatterResolver = options.Resolver;
- writer.WriteArrayHeader(7);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.MyProperty0, options);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.MyProperty1, options);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.MyProperty2, options);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.MyProperty3, options);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.MyProperty4, options);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.MyProperty5, options);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.MyProperty6, options);
- }
-
- public global::ArrayTestTest Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- global::MessagePack.IFormatterResolver formatterResolver = options.Resolver;
- var length = reader.ReadArrayHeader();
- var ____result = new global::ArrayTestTest();
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- ____result.MyProperty0 = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- case 1:
- ____result.MyProperty1 = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- case 2:
- ____result.MyProperty2 = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- case 3:
- ____result.MyProperty3 = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- case 4:
- ____result.MyProperty4 = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- case 5:
- ____result.MyProperty5 = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- case 6:
- ____result.MyProperty6 = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class GlobalManFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::GlobalMan value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- writer.WriteArrayHeader(1);
- writer.Write(value.MyProperty);
- }
-
- public global::GlobalMan Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- var length = reader.ReadArrayHeader();
- var ____result = new global::GlobalMan();
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- ____result.MyProperty = reader.ReadInt32();
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class MessageFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::Message value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- global::MessagePack.IFormatterResolver formatterResolver = options.Resolver;
- writer.WriteArrayHeader(4);
- writer.Write(value.UserId);
- writer.Write(value.RoomId);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.PostTime, options);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.Body, options);
- }
-
- public global::Message Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- global::MessagePack.IFormatterResolver formatterResolver = options.Resolver;
- var length = reader.ReadArrayHeader();
- var ____result = new global::Message();
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- ____result.UserId = reader.ReadInt32();
- break;
- case 1:
- ____result.RoomId = reader.ReadInt32();
- break;
- case 2:
- ____result.PostTime = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- case 3:
- ____result.Body = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class MessagePackFormatterFieldUserFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
- private readonly global::MessagePack.Formatters.NativeDateTimeFormatter __TimestampCustomFormatter__ = new global::MessagePack.Formatters.NativeDateTimeFormatter();
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::MessagePackFormatterFieldUser value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- writer.WriteArrayHeader(1);
- this.__TimestampCustomFormatter__.Serialize(ref writer, value.Timestamp, options);
- }
-
- public global::MessagePackFormatterFieldUser Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- var length = reader.ReadArrayHeader();
- var ____result = new global::MessagePackFormatterFieldUser();
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- ____result.Timestamp = this.__TimestampCustomFormatter__.Deserialize(ref reader, options);
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class QuestMessageBodyFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::QuestMessageBody value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- global::MessagePack.IFormatterResolver formatterResolver = options.Resolver;
- writer.WriteArrayHeader(2);
- writer.Write(value.QuestId);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.Text, options);
- }
-
- public global::QuestMessageBody Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- global::MessagePack.IFormatterResolver formatterResolver = options.Resolver;
- var length = reader.ReadArrayHeader();
- var ____result = new global::QuestMessageBody();
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- ____result.QuestId = reader.ReadInt32();
- break;
- case 1:
- ____result.Text = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class StampMessageBodyFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::StampMessageBody value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- writer.WriteArrayHeader(1);
- writer.Write(value.StampId);
- }
-
- public global::StampMessageBody Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- var length = reader.ReadArrayHeader();
- var ____result = new global::StampMessageBody();
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- ____result.StampId = reader.ReadInt32();
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class TextMessageBodyFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::TextMessageBody value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- global::MessagePack.IFormatterResolver formatterResolver = options.Resolver;
- writer.WriteArrayHeader(1);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.Text, options);
- }
-
- public global::TextMessageBody Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- global::MessagePack.IFormatterResolver formatterResolver = options.Resolver;
- var length = reader.ReadArrayHeader();
- var ____result = new global::TextMessageBody();
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- ____result.Text = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
-}
-
-#pragma warning restore 168
-#pragma warning restore 414
-#pragma warning restore 618
-#pragma warning restore 612
-
-#pragma warning restore SA1129 // Do not use default value type constructor
-#pragma warning restore SA1309 // Field names should not begin with underscore
-#pragma warning restore SA1312 // Variable names should begin with lower-case letter
-#pragma warning restore SA1403 // File may only contain a single namespace
-#pragma warning restore SA1649 // File name should match first type name
-
-//
-// THIS (.cs) FILE IS GENERATED BY MPC(MessagePack-CSharp). DO NOT CHANGE IT.
-//
-
-#pragma warning disable 618
-#pragma warning disable 612
-#pragma warning disable 414
-#pragma warning disable 168
-#pragma warning disable CS1591 // document public APIs
-
-#pragma warning disable SA1129 // Do not use default value type constructor
-#pragma warning disable SA1309 // Field names should not begin with underscore
-#pragma warning disable SA1312 // Variable names should begin with lower-case letter
-#pragma warning disable SA1403 // File may only contain a single namespace
-#pragma warning disable SA1649 // File name should match first type name
-
-namespace MessagePack.Formatters
-{
- public sealed class ComplexModelFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
- // AdditionalProperty
- private static global::System.ReadOnlySpan GetSpan_AdditionalProperty() => new byte[1 + 18] { 178, 65, 100, 100, 105, 116, 105, 111, 110, 97, 108, 80, 114, 111, 112, 101, 114, 116, 121 };
- // CreatedOn
- private static global::System.ReadOnlySpan GetSpan_CreatedOn() => new byte[1 + 9] { 169, 67, 114, 101, 97, 116, 101, 100, 79, 110 };
- // Id
- private static global::System.ReadOnlySpan GetSpan_Id() => new byte[1 + 2] { 162, 73, 100 };
- // Name
- private static global::System.ReadOnlySpan GetSpan_Name() => new byte[1 + 4] { 164, 78, 97, 109, 101 };
- // UpdatedOn
- private static global::System.ReadOnlySpan GetSpan_UpdatedOn() => new byte[1 + 9] { 169, 85, 112, 100, 97, 116, 101, 100, 79, 110 };
- // SimpleModels
- private static global::System.ReadOnlySpan GetSpan_SimpleModels() => new byte[1 + 12] { 172, 83, 105, 109, 112, 108, 101, 77, 111, 100, 101, 108, 115 };
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::ComplexModel value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value is null)
- {
- writer.WriteNil();
- return;
- }
-
- var formatterResolver = options.Resolver;
- writer.WriteMapHeader(6);
- writer.WriteRaw(GetSpan_AdditionalProperty());
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify>(formatterResolver).Serialize(ref writer, value.AdditionalProperty, options);
- writer.WriteRaw(GetSpan_CreatedOn());
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.CreatedOn, options);
- writer.WriteRaw(GetSpan_Id());
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.Id, options);
- writer.WriteRaw(GetSpan_Name());
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.Name, options);
- writer.WriteRaw(GetSpan_UpdatedOn());
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.UpdatedOn, options);
- writer.WriteRaw(GetSpan_SimpleModels());
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify>(formatterResolver).Serialize(ref writer, value.SimpleModels, options);
- }
-
- public global::ComplexModel Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- var formatterResolver = options.Resolver;
- var length = reader.ReadMapHeader();
- var ____result = new global::ComplexModel();
-
- for (int i = 0; i < length; i++)
- {
- var stringKey = global::MessagePack.Internal.CodeGenHelpers.ReadStringSpan(ref reader);
- switch (stringKey.Length)
- {
- default:
- FAIL:
- reader.Skip();
- continue;
- case 18:
- if (!global::System.MemoryExtensions.SequenceEqual(stringKey, GetSpan_AdditionalProperty().Slice(1))) { goto FAIL; }
-
- reader.Skip();
- continue;
- case 9:
- switch (global::MessagePack.Internal.AutomataKeyGen.GetKey(ref stringKey))
- {
- default: goto FAIL;
- case 5720808977192022595UL:
- if (stringKey[0] != 110) { goto FAIL; }
-
- ____result.CreatedOn = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- continue;
-
- case 5720808977191956565UL:
- if (stringKey[0] != 110) { goto FAIL; }
-
- ____result.UpdatedOn = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- continue;
-
- }
- case 2:
- if (global::MessagePack.Internal.AutomataKeyGen.GetKey(ref stringKey) != 25673UL) { goto FAIL; }
-
- ____result.Id = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- continue;
- case 4:
- if (global::MessagePack.Internal.AutomataKeyGen.GetKey(ref stringKey) != 1701667150UL) { goto FAIL; }
-
- ____result.Name = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- continue;
- case 12:
- if (!global::System.MemoryExtensions.SequenceEqual(stringKey, GetSpan_SimpleModels().Slice(1))) { goto FAIL; }
-
- reader.Skip();
- continue;
-
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class SimpleModelFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
- // Id
- private static global::System.ReadOnlySpan GetSpan_Id() => new byte[1 + 2] { 162, 73, 100 };
- // Name
- private static global::System.ReadOnlySpan GetSpan_Name() => new byte[1 + 4] { 164, 78, 97, 109, 101 };
- // CreatedOn
- private static global::System.ReadOnlySpan GetSpan_CreatedOn() => new byte[1 + 9] { 169, 67, 114, 101, 97, 116, 101, 100, 79, 110 };
- // Precision
- private static global::System.ReadOnlySpan GetSpan_Precision() => new byte[1 + 9] { 169, 80, 114, 101, 99, 105, 115, 105, 111, 110 };
- // Money
- private static global::System.ReadOnlySpan GetSpan_Money() => new byte[1 + 5] { 165, 77, 111, 110, 101, 121 };
- // Amount
- private static global::System.ReadOnlySpan GetSpan_Amount() => new byte[1 + 6] { 166, 65, 109, 111, 117, 110, 116 };
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SimpleModel value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value is null)
- {
- writer.WriteNil();
- return;
- }
-
- var formatterResolver = options.Resolver;
- writer.WriteMapHeader(6);
- writer.WriteRaw(GetSpan_Id());
- writer.Write(value.Id);
- writer.WriteRaw(GetSpan_Name());
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.Name, options);
- writer.WriteRaw(GetSpan_CreatedOn());
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.CreatedOn, options);
- writer.WriteRaw(GetSpan_Precision());
- writer.Write(value.Precision);
- writer.WriteRaw(GetSpan_Money());
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.Money, options);
- writer.WriteRaw(GetSpan_Amount());
- writer.Write(value.Amount);
- }
-
- public global::SimpleModel Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- var formatterResolver = options.Resolver;
- var length = reader.ReadMapHeader();
- var ____result = new global::SimpleModel();
-
- for (int i = 0; i < length; i++)
- {
- var stringKey = global::MessagePack.Internal.CodeGenHelpers.ReadStringSpan(ref reader);
- switch (stringKey.Length)
- {
- default:
- FAIL:
- reader.Skip();
- continue;
- case 2:
- if (global::MessagePack.Internal.AutomataKeyGen.GetKey(ref stringKey) != 25673UL) { goto FAIL; }
-
- ____result.Id = reader.ReadInt32();
- continue;
- case 4:
- if (global::MessagePack.Internal.AutomataKeyGen.GetKey(ref stringKey) != 1701667150UL) { goto FAIL; }
-
- ____result.Name = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- continue;
- case 9:
- switch (global::MessagePack.Internal.AutomataKeyGen.GetKey(ref stringKey))
- {
- default: goto FAIL;
- case 5720808977192022595UL:
- if (stringKey[0] != 110) { goto FAIL; }
-
- ____result.CreatedOn = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- continue;
-
- case 8028074707240972880UL:
- if (stringKey[0] != 110) { goto FAIL; }
-
- ____result.Precision = reader.ReadInt32();
- continue;
-
- }
- case 5:
- if (global::MessagePack.Internal.AutomataKeyGen.GetKey(ref stringKey) != 521392779085UL) { goto FAIL; }
-
- ____result.Money = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- continue;
- case 6:
- if (global::MessagePack.Internal.AutomataKeyGen.GetKey(ref stringKey) != 128017765461313UL) { goto FAIL; }
-
- reader.Skip();
- continue;
-
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
-}
-
-#pragma warning restore 168
-#pragma warning restore 414
-#pragma warning restore 618
-#pragma warning restore 612
-
-#pragma warning restore SA1129 // Do not use default value type constructor
-#pragma warning restore SA1309 // Field names should not begin with underscore
-#pragma warning restore SA1312 // Variable names should begin with lower-case letter
-#pragma warning restore SA1403 // File may only contain a single namespace
-#pragma warning restore SA1649 // File name should match first type name
-
-//
-// THIS (.cs) FILE IS GENERATED BY MPC(MessagePack-CSharp). DO NOT CHANGE IT.
-//
-
-#pragma warning disable 618
-#pragma warning disable 612
-#pragma warning disable 414
-#pragma warning disable 168
-#pragma warning disable CS1591 // document public APIs
-
-#pragma warning disable SA1129 // Do not use default value type constructor
-#pragma warning disable SA1309 // Field names should not begin with underscore
-#pragma warning disable SA1312 // Variable names should begin with lower-case letter
-#pragma warning disable SA1403 // File may only contain a single namespace
-#pragma warning disable SA1649 // File name should match first type name
-
-namespace MessagePack.Formatters.PerfBenchmarkDotNet
-{
- public sealed class StringKeySerializerTargetFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
- // MyProperty1
- private static global::System.ReadOnlySpan GetSpan_MyProperty1() => new byte[1 + 11] { 171, 77, 121, 80, 114, 111, 112, 101, 114, 116, 121, 49 };
- // MyProperty2
- private static global::System.ReadOnlySpan GetSpan_MyProperty2() => new byte[1 + 11] { 171, 77, 121, 80, 114, 111, 112, 101, 114, 116, 121, 50 };
- // MyProperty3
- private static global::System.ReadOnlySpan GetSpan_MyProperty3() => new byte[1 + 11] { 171, 77, 121, 80, 114, 111, 112, 101, 114, 116, 121, 51 };
- // MyProperty4
- private static global::System.ReadOnlySpan GetSpan_MyProperty4() => new byte[1 + 11] { 171, 77, 121, 80, 114, 111, 112, 101, 114, 116, 121, 52 };
- // MyProperty5
- private static global::System.ReadOnlySpan GetSpan_MyProperty5() => new byte[1 + 11] { 171, 77, 121, 80, 114, 111, 112, 101, 114, 116, 121, 53 };
- // MyProperty6
- private static global::System.ReadOnlySpan GetSpan_MyProperty6() => new byte[1 + 11] { 171, 77, 121, 80, 114, 111, 112, 101, 114, 116, 121, 54 };
- // MyProperty7
- private static global::System.ReadOnlySpan GetSpan_MyProperty7() => new byte[1 + 11] { 171, 77, 121, 80, 114, 111, 112, 101, 114, 116, 121, 55 };
- // MyProperty8
- private static global::System.ReadOnlySpan GetSpan_MyProperty8() => new byte[1 + 11] { 171, 77, 121, 80, 114, 111, 112, 101, 114, 116, 121, 56 };
- // MyProperty9
- private static global::System.ReadOnlySpan GetSpan_MyProperty9() => new byte[1 + 11] { 171, 77, 121, 80, 114, 111, 112, 101, 114, 116, 121, 57 };
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::PerfBenchmarkDotNet.StringKeySerializerTarget value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value is null)
- {
- writer.WriteNil();
- return;
- }
-
- writer.WriteMapHeader(9);
- writer.WriteRaw(GetSpan_MyProperty1());
- writer.Write(value.MyProperty1);
- writer.WriteRaw(GetSpan_MyProperty2());
- writer.Write(value.MyProperty2);
- writer.WriteRaw(GetSpan_MyProperty3());
- writer.Write(value.MyProperty3);
- writer.WriteRaw(GetSpan_MyProperty4());
- writer.Write(value.MyProperty4);
- writer.WriteRaw(GetSpan_MyProperty5());
- writer.Write(value.MyProperty5);
- writer.WriteRaw(GetSpan_MyProperty6());
- writer.Write(value.MyProperty6);
- writer.WriteRaw(GetSpan_MyProperty7());
- writer.Write(value.MyProperty7);
- writer.WriteRaw(GetSpan_MyProperty8());
- writer.Write(value.MyProperty8);
- writer.WriteRaw(GetSpan_MyProperty9());
- writer.Write(value.MyProperty9);
- }
-
- public global::PerfBenchmarkDotNet.StringKeySerializerTarget Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- var length = reader.ReadMapHeader();
- var ____result = new global::PerfBenchmarkDotNet.StringKeySerializerTarget();
-
- for (int i = 0; i < length; i++)
- {
- var stringKey = global::MessagePack.Internal.CodeGenHelpers.ReadStringSpan(ref reader);
- switch (stringKey.Length)
- {
- default:
- FAIL:
- reader.Skip();
- continue;
- case 11:
- switch (global::MessagePack.Internal.AutomataKeyGen.GetKey(ref stringKey))
- {
- default: goto FAIL;
- case 8243118316933118285UL:
- switch (global::MessagePack.Internal.AutomataKeyGen.GetKey(ref stringKey))
- {
- default: goto FAIL;
- case 3242356UL:
- ____result.MyProperty1 = reader.ReadInt32();
- continue;
- case 3307892UL:
- ____result.MyProperty2 = reader.ReadInt32();
- continue;
- case 3373428UL:
- ____result.MyProperty3 = reader.ReadInt32();
- continue;
- case 3438964UL:
- ____result.MyProperty4 = reader.ReadInt32();
- continue;
- case 3504500UL:
- ____result.MyProperty5 = reader.ReadInt32();
- continue;
- case 3570036UL:
- ____result.MyProperty6 = reader.ReadInt32();
- continue;
- case 3635572UL:
- ____result.MyProperty7 = reader.ReadInt32();
- continue;
- case 3701108UL:
- ____result.MyProperty8 = reader.ReadInt32();
- continue;
- case 3766644UL:
- ____result.MyProperty9 = reader.ReadInt32();
- continue;
- }
-
- }
-
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
-}
-
-#pragma warning restore 168
-#pragma warning restore 414
-#pragma warning restore 618
-#pragma warning restore 612
-
-#pragma warning restore SA1129 // Do not use default value type constructor
-#pragma warning restore SA1309 // Field names should not begin with underscore
-#pragma warning restore SA1312 // Variable names should begin with lower-case letter
-#pragma warning restore SA1403 // File may only contain a single namespace
-#pragma warning restore SA1649 // File name should match first type name
-
-//
-// THIS (.cs) FILE IS GENERATED BY MPC(MessagePack-CSharp). DO NOT CHANGE IT.
-//
-
-#pragma warning disable 618
-#pragma warning disable 612
-#pragma warning disable 414
-#pragma warning disable 168
-#pragma warning disable CS1591 // document public APIs
-
-#pragma warning disable SA1129 // Do not use default value type constructor
-#pragma warning disable SA1309 // Field names should not begin with underscore
-#pragma warning disable SA1312 // Variable names should begin with lower-case letter
-#pragma warning disable SA1403 // File may only contain a single namespace
-#pragma warning disable SA1649 // File name should match first type name
-
-namespace MessagePack.Formatters.SharedData
-{
- public sealed class ArrayOptimizeClassFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SharedData.ArrayOptimizeClass value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- writer.WriteArrayHeader(16);
- writer.Write(value.MyProperty0);
- writer.Write(value.MyProperty1);
- writer.Write(value.MyProperty2);
- writer.Write(value.MyProperty3);
- writer.Write(value.MyProperty4);
- writer.Write(value.MyProperty5);
- writer.Write(value.MyProperty6);
- writer.Write(value.MyProperty7);
- writer.Write(value.MyProperty8);
- writer.Write(value.MyProvperty9);
- writer.Write(value.MyProperty10);
- writer.Write(value.MyProperty11);
- writer.Write(value.MyPropverty12);
- writer.Write(value.MyPropevrty13);
- writer.Write(value.MyProperty14);
- writer.Write(value.MyProperty15);
- }
-
- public global::SharedData.ArrayOptimizeClass Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- var length = reader.ReadArrayHeader();
- var ____result = new global::SharedData.ArrayOptimizeClass();
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- ____result.MyProperty0 = reader.ReadInt32();
- break;
- case 1:
- ____result.MyProperty1 = reader.ReadInt32();
- break;
- case 2:
- ____result.MyProperty2 = reader.ReadInt32();
- break;
- case 3:
- ____result.MyProperty3 = reader.ReadInt32();
- break;
- case 4:
- ____result.MyProperty4 = reader.ReadInt32();
- break;
- case 5:
- ____result.MyProperty5 = reader.ReadInt32();
- break;
- case 6:
- ____result.MyProperty6 = reader.ReadInt32();
- break;
- case 7:
- ____result.MyProperty7 = reader.ReadInt32();
- break;
- case 8:
- ____result.MyProperty8 = reader.ReadInt32();
- break;
- case 9:
- ____result.MyProvperty9 = reader.ReadInt32();
- break;
- case 10:
- ____result.MyProperty10 = reader.ReadInt32();
- break;
- case 11:
- ____result.MyProperty11 = reader.ReadInt32();
- break;
- case 12:
- ____result.MyPropverty12 = reader.ReadInt32();
- break;
- case 13:
- ____result.MyPropevrty13 = reader.ReadInt32();
- break;
- case 14:
- ____result.MyProperty14 = reader.ReadInt32();
- break;
- case 15:
- ____result.MyProperty15 = reader.ReadInt32();
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class BarClassFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SharedData.BarClass value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- global::MessagePack.IFormatterResolver formatterResolver = options.Resolver;
- writer.WriteArrayHeader(1);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.OPQ, options);
- }
-
- public global::SharedData.BarClass Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- global::MessagePack.IFormatterResolver formatterResolver = options.Resolver;
- var length = reader.ReadArrayHeader();
- var ____result = new global::SharedData.BarClass();
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- ____result.OPQ = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class Callback1Formatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SharedData.Callback1 value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- value.OnBeforeSerialize();
- writer.WriteArrayHeader(1);
- writer.Write(value.X);
- }
-
- public global::SharedData.Callback1 Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- var length = reader.ReadArrayHeader();
- var __X__ = default(int);
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- __X__ = reader.ReadInt32();
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- var ____result = new global::SharedData.Callback1(__X__);
- ____result.OnAfterDeserialize();
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class Callback1_2Formatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SharedData.Callback1_2 value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- ((global::MessagePack.IMessagePackSerializationCallbackReceiver)value).OnBeforeSerialize();
- writer.WriteArrayHeader(1);
- writer.Write(value.X);
- }
-
- public global::SharedData.Callback1_2 Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- var length = reader.ReadArrayHeader();
- var __X__ = default(int);
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- __X__ = reader.ReadInt32();
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- var ____result = new global::SharedData.Callback1_2(__X__);
- ((global::MessagePack.IMessagePackSerializationCallbackReceiver)____result).OnAfterDeserialize();
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class DefaultValueIntKeyClassWithExplicitConstructorFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SharedData.DefaultValueIntKeyClassWithExplicitConstructor value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- global::MessagePack.IFormatterResolver formatterResolver = options.Resolver;
- writer.WriteArrayHeader(4);
- writer.Write(value.Prop1);
- writer.Write(value.Prop2);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.Prop3, options);
- global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Serialize(ref writer, value.Prop4, options);
- }
-
- public global::SharedData.DefaultValueIntKeyClassWithExplicitConstructor Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- global::MessagePack.IFormatterResolver formatterResolver = options.Resolver;
- var length = reader.ReadArrayHeader();
- var __Prop1__ = default(int);
- var __Prop2__ = default(int);
- var __Prop3__ = default(string);
- var __Prop4__ = default(string);
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- __Prop1__ = reader.ReadInt32();
- break;
- case 1:
- __Prop2__ = reader.ReadInt32();
- break;
- case 2:
- __Prop3__ = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- case 3:
- __Prop4__ = global::MessagePack.FormatterResolverExtensions.GetFormatterWithVerify(formatterResolver).Deserialize(ref reader, options);
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- var ____result = new global::SharedData.DefaultValueIntKeyClassWithExplicitConstructor(__Prop1__);
- if (length <= 1)
- {
- goto MEMBER_ASSIGNMENT_END;
- }
-
- ____result.Prop2 = __Prop2__;
- if (length <= 2)
- {
- goto MEMBER_ASSIGNMENT_END;
- }
-
- ____result.Prop3 = __Prop3__;
- if (length <= 3)
- {
- goto MEMBER_ASSIGNMENT_END;
- }
-
- ____result.Prop4 = __Prop4__;
-
- MEMBER_ASSIGNMENT_END:
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class DefaultValueIntKeyClassWithoutExplicitConstructorFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SharedData.DefaultValueIntKeyClassWithoutExplicitConstructor value, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (value == null)
- {
- writer.WriteNil();
- return;
- }
-
- writer.WriteArrayHeader(2);
- writer.Write(value.Prop1);
- writer.Write(value.Prop2);
- }
-
- public global::SharedData.DefaultValueIntKeyClassWithoutExplicitConstructor Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- return null;
- }
-
- options.Security.DepthStep(ref reader);
- var length = reader.ReadArrayHeader();
- var ____result = new global::SharedData.DefaultValueIntKeyClassWithoutExplicitConstructor();
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- ____result.Prop1 = reader.ReadInt32();
- break;
- case 1:
- ____result.Prop2 = reader.ReadInt32();
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class DefaultValueIntKeyStructWithExplicitConstructorFormatter : global::MessagePack.Formatters.IMessagePackFormatter
- {
-
- public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::SharedData.DefaultValueIntKeyStructWithExplicitConstructor value, global::MessagePack.MessagePackSerializerOptions options)
- {
- writer.WriteArrayHeader(2);
- writer.Write(value.Prop1);
- writer.Write(value.Prop2);
- }
-
- public global::SharedData.DefaultValueIntKeyStructWithExplicitConstructor Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
- {
- if (reader.TryReadNil())
- {
- throw new global::System.InvalidOperationException("typecode is null, struct not supported");
- }
-
- options.Security.DepthStep(ref reader);
- var length = reader.ReadArrayHeader();
- var __Prop1__ = default(int);
- var __Prop2__ = default(int);
-
- for (int i = 0; i < length; i++)
- {
- switch (i)
- {
- case 0:
- __Prop1__ = reader.ReadInt32();
- break;
- case 1:
- __Prop2__ = reader.ReadInt32();
- break;
- default:
- reader.Skip();
- break;
- }
- }
-
- var ____result = new global::SharedData.DefaultValueIntKeyStructWithExplicitConstructor(__Prop1__);
- if (length <= 1)
- {
- goto MEMBER_ASSIGNMENT_END;
- }
-
- ____result.Prop2 = __Prop2__;
-
- MEMBER_ASSIGNMENT_END:
- reader.Depth--;
- return ____result;
- }
- }
-
- public sealed class DynamicArgumentTupleFormatter : global::MessagePack.Formatters.IMessagePackFormatter