mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-01-18 02:39:30 +00:00
Merge pull request #184 from ceph/devel
Sync downstream devel with upstream devel branch
This commit is contained in:
commit
113d8c69c2
28
.github/dependabot.yml
vendored
28
.github/dependabot.yml
vendored
@ -1,5 +1,6 @@
|
||||
---
|
||||
version: 2
|
||||
enable-beta-ecosystems: true
|
||||
updates:
|
||||
- package-ecosystem: "gomod"
|
||||
# ODF only: disable PR creation, synced from upstream
|
||||
@ -8,6 +9,20 @@ updates:
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
rebase-strategy: "disabled"
|
||||
groups:
|
||||
golang-dependencies:
|
||||
patterns:
|
||||
- "github.com/golang*"
|
||||
k8s-dependencies:
|
||||
patterns:
|
||||
- "k8s.io*"
|
||||
- "sigs.k8s.io*"
|
||||
github-dependencies:
|
||||
patterns:
|
||||
- "github.com*"
|
||||
exclude-patterns:
|
||||
- "github.com/golang*"
|
||||
- "github.com/container-storage-interface/spec"
|
||||
labels:
|
||||
- rebase
|
||||
commit-message:
|
||||
@ -59,6 +74,19 @@ updates:
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
rebase-strategy: "disabled"
|
||||
groups:
|
||||
golang-dependencies:
|
||||
patterns:
|
||||
- "github.com/golang*"
|
||||
k8s-dependencies:
|
||||
patterns:
|
||||
- "k8s.io*"
|
||||
- "sigs.k8s.io*"
|
||||
github-dependencies:
|
||||
patterns:
|
||||
- "github.com*"
|
||||
exclude-patterns:
|
||||
- "github.com/golang*"
|
||||
labels:
|
||||
- rebase
|
||||
- ci/skip/e2e
|
||||
|
112
.github/workflows/pull-request-commentor.yaml
vendored
112
.github/workflows/pull-request-commentor.yaml
vendored
@ -8,87 +8,74 @@ on:
|
||||
- "release-v*"
|
||||
types:
|
||||
- labeled
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
add-comment:
|
||||
branch-k8s-selection:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
branch: [release-v3.8, release-v3.9, devel]
|
||||
k8s: ["1.25", "1.26", "1.27", "1.28"]
|
||||
exclude:
|
||||
# the next Ceph-CSI version will not be tested with old Kubernetes
|
||||
- k8s: "1.25"
|
||||
branch: "devel"
|
||||
|
||||
# Ceph-CSI <= 3.9 was released before Kubernetes 1.28
|
||||
- k8s: "1.28"
|
||||
branch: "release-v3.8"
|
||||
- k8s: "1.28"
|
||||
branch: "release-v3.9"
|
||||
|
||||
# watch out, matrix.branch can not be used in this if-statement :-/
|
||||
if: >
|
||||
(github.event.label.name == 'ok-to-test' &&
|
||||
github.event.pull_request.merged != true)
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Add comment to trigger external storage tests for Kubernetes 1.25
|
||||
- name: >
|
||||
Add comment to trigger external storage tests for Kubernetes
|
||||
${{ matrix.k8s }}
|
||||
if: ${{ github.base_ref == matrix.branch }}
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.CEPH_CSI_BOT_TOKEN }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
/test ci/centos/k8s-e2e-external-storage/1.25
|
||||
/test ci/centos/k8s-e2e-external-storage/${{ matrix.k8s }}
|
||||
|
||||
- name: Add comment to trigger external storage tests for Kubernetes 1.26
|
||||
- name: >
|
||||
Add comment to trigger helm E2E tests for Kubernetes
|
||||
${{ matrix.k8s }}
|
||||
if: ${{ github.base_ref == matrix.branch }}
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.CEPH_CSI_BOT_TOKEN }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
/test ci/centos/k8s-e2e-external-storage/1.26
|
||||
/test ci/centos/mini-e2e-helm/k8s-${{ matrix.k8s }}
|
||||
|
||||
- name: Add comment to trigger external storage tests for Kubernetes 1.27
|
||||
- name: Add comment to trigger E2E tests for Kubernetes ${{ matrix.k8s }}
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
if: ${{ github.base_ref == matrix.branch }}
|
||||
with:
|
||||
token: ${{ secrets.CEPH_CSI_BOT_TOKEN }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
/test ci/centos/k8s-e2e-external-storage/1.27
|
||||
/test ci/centos/mini-e2e/k8s-${{ matrix.k8s }}
|
||||
|
||||
- name: Add comment to trigger helm E2E tests for Kubernetes 1.25
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.CEPH_CSI_BOT_TOKEN }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
/test ci/centos/mini-e2e-helm/k8s-1.25
|
||||
any-branch-k8s-version:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
- name: Add comment to trigger helm E2E tests for Kubernetes 1.26
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.CEPH_CSI_BOT_TOKEN }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
/test ci/centos/mini-e2e-helm/k8s-1.26
|
||||
|
||||
- name: Add comment to trigger helm E2E tests for Kubernetes 1.27
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.CEPH_CSI_BOT_TOKEN }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
/test ci/centos/mini-e2e-helm/k8s-1.27
|
||||
|
||||
- name: Add comment to trigger E2E tests for Kubernetes 1.25
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.CEPH_CSI_BOT_TOKEN }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
/test ci/centos/mini-e2e/k8s-1.25
|
||||
|
||||
- name: Add comment to trigger E2E tests for Kubernetes 1.26
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.CEPH_CSI_BOT_TOKEN }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
/test ci/centos/mini-e2e/k8s-1.26
|
||||
|
||||
- name: Add comment to trigger E2E tests for Kubernetes 1.27
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.CEPH_CSI_BOT_TOKEN }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body: |
|
||||
/test ci/centos/mini-e2e/k8s-1.27
|
||||
if: >
|
||||
(github.event.label.name == 'ok-to-test' &&
|
||||
github.event.pull_request.merged != true)
|
||||
|
||||
steps:
|
||||
- name: Add comment to trigger cephfs upgrade tests
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
@ -105,6 +92,19 @@ jobs:
|
||||
body: |
|
||||
/test ci/centos/upgrade-tests-rbd
|
||||
|
||||
remove-label:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# run after the other jobs
|
||||
needs:
|
||||
- branch-k8s-selection
|
||||
- any-branch-k8s-version
|
||||
|
||||
if: >
|
||||
(github.event.label.name == 'ok-to-test' &&
|
||||
github.event.pull_request.merged != true)
|
||||
|
||||
steps:
|
||||
- name: remove ok-to-test-label after commenting
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
|
252
.mergify.yml
252
.mergify.yml
@ -22,7 +22,7 @@ queue_rules:
|
||||
# Conditions to get out of the queue (= merged)
|
||||
- or:
|
||||
- and:
|
||||
- base~=^(devel)|(release-.+)$
|
||||
- base=release-v*
|
||||
- "status-success=codespell"
|
||||
- "status-success=multi-arch-build"
|
||||
- "status-success=go-test"
|
||||
@ -40,6 +40,25 @@ queue_rules:
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.27"
|
||||
- "status-success=ci/centos/upgrade-tests-cephfs"
|
||||
- "status-success=ci/centos/upgrade-tests-rbd"
|
||||
- and:
|
||||
- base=devel
|
||||
- "status-success=codespell"
|
||||
- "status-success=multi-arch-build"
|
||||
- "status-success=go-test"
|
||||
- "status-success=golangci-lint"
|
||||
- "status-success=mod-check"
|
||||
- "status-success=lint-extras"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.26"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.27"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.28"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.28"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.28"
|
||||
- "status-success=ci/centos/upgrade-tests-cephfs"
|
||||
- "status-success=ci/centos/upgrade-tests-rbd"
|
||||
- and:
|
||||
- base=ci/centos
|
||||
- "status-success=ci/centos/job-validation"
|
||||
@ -82,31 +101,59 @@ pull_request_rules:
|
||||
|
||||
- name: update dependencies by dependabot (skip commitlint)
|
||||
conditions:
|
||||
- author=dependabot[bot]
|
||||
- label!=DNM
|
||||
- base~=^(devel)|(release-.+)$
|
||||
- "#approved-reviews-by>=2"
|
||||
- "#changes-requested-reviews-by=0"
|
||||
- "approved-reviews-by=@ceph/ceph-csi-contributors"
|
||||
- "approved-reviews-by=@ceph/ceph-csi-maintainers"
|
||||
- "status-success=codespell"
|
||||
- "status-success=multi-arch-build"
|
||||
- "status-success=go-test"
|
||||
- "status-success=golangci-lint"
|
||||
- "status-success=mod-check"
|
||||
- "status-success=lint-extras"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.25"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.26"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.27"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.25"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.25"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.27"
|
||||
- "status-success=ci/centos/upgrade-tests-cephfs"
|
||||
- "status-success=ci/centos/upgrade-tests-rbd"
|
||||
- "status-success=DCO"
|
||||
- or:
|
||||
- and:
|
||||
- author=dependabot[bot]
|
||||
- label!=DNM
|
||||
- base=release-v*
|
||||
- "#approved-reviews-by>=2"
|
||||
- "#changes-requested-reviews-by=0"
|
||||
- "approved-reviews-by=@ceph/ceph-csi-contributors"
|
||||
- "approved-reviews-by=@ceph/ceph-csi-maintainers"
|
||||
- "status-success=codespell"
|
||||
- "status-success=multi-arch-build"
|
||||
- "status-success=go-test"
|
||||
- "status-success=golangci-lint"
|
||||
- "status-success=mod-check"
|
||||
- "status-success=lint-extras"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.25"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.26"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.27"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.25"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.25"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.27"
|
||||
- "status-success=ci/centos/upgrade-tests-cephfs"
|
||||
- "status-success=ci/centos/upgrade-tests-rbd"
|
||||
- "status-success=DCO"
|
||||
- and:
|
||||
- author=dependabot[bot]
|
||||
- label!=DNM
|
||||
- base=devel
|
||||
- "#approved-reviews-by>=2"
|
||||
- "#changes-requested-reviews-by=0"
|
||||
- "approved-reviews-by=@ceph/ceph-csi-contributors"
|
||||
- "approved-reviews-by=@ceph/ceph-csi-maintainers"
|
||||
- "status-success=codespell"
|
||||
- "status-success=multi-arch-build"
|
||||
- "status-success=go-test"
|
||||
- "status-success=golangci-lint"
|
||||
- "status-success=mod-check"
|
||||
- "status-success=lint-extras"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.26"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.27"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.28"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.28"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.28"
|
||||
- "status-success=ci/centos/upgrade-tests-cephfs"
|
||||
- "status-success=ci/centos/upgrade-tests-rbd"
|
||||
- "status-success=DCO"
|
||||
actions:
|
||||
queue:
|
||||
name: default
|
||||
@ -121,31 +168,59 @@ pull_request_rules:
|
||||
|
||||
- name: automatic merge
|
||||
conditions:
|
||||
- label!=DNM
|
||||
- base~=^(devel)|(release-.+)$
|
||||
- "#approved-reviews-by>=2"
|
||||
- "#changes-requested-reviews-by=0"
|
||||
- "approved-reviews-by=@ceph/ceph-csi-contributors"
|
||||
- "approved-reviews-by=@ceph/ceph-csi-maintainers"
|
||||
- "status-success=codespell"
|
||||
- "status-success=multi-arch-build"
|
||||
- "status-success=go-test"
|
||||
- "status-success=golangci-lint"
|
||||
- "status-success=commitlint"
|
||||
- "status-success=mod-check"
|
||||
- "status-success=lint-extras"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.25"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.26"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.27"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.25"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.25"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.27"
|
||||
- "status-success=ci/centos/upgrade-tests-cephfs"
|
||||
- "status-success=ci/centos/upgrade-tests-rbd"
|
||||
- "status-success=DCO"
|
||||
- or:
|
||||
- and:
|
||||
- label!=DNM
|
||||
- base=release-v*
|
||||
- "#approved-reviews-by>=2"
|
||||
- "#changes-requested-reviews-by=0"
|
||||
- "approved-reviews-by=@ceph/ceph-csi-contributors"
|
||||
- "approved-reviews-by=@ceph/ceph-csi-maintainers"
|
||||
- "status-success=codespell"
|
||||
- "status-success=multi-arch-build"
|
||||
- "status-success=go-test"
|
||||
- "status-success=golangci-lint"
|
||||
- "status-success=commitlint"
|
||||
- "status-success=mod-check"
|
||||
- "status-success=lint-extras"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.25"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.26"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.27"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.25"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.25"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.27"
|
||||
- "status-success=ci/centos/upgrade-tests-cephfs"
|
||||
- "status-success=ci/centos/upgrade-tests-rbd"
|
||||
- "status-success=DCO"
|
||||
- and:
|
||||
- label!=DNM
|
||||
- base=devel
|
||||
- "#approved-reviews-by>=2"
|
||||
- "#changes-requested-reviews-by=0"
|
||||
- "approved-reviews-by=@ceph/ceph-csi-contributors"
|
||||
- "approved-reviews-by=@ceph/ceph-csi-maintainers"
|
||||
- "status-success=codespell"
|
||||
- "status-success=multi-arch-build"
|
||||
- "status-success=go-test"
|
||||
- "status-success=golangci-lint"
|
||||
- "status-success=commitlint"
|
||||
- "status-success=mod-check"
|
||||
- "status-success=lint-extras"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.26"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.27"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.28"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.28"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.28"
|
||||
- "status-success=ci/centos/upgrade-tests-cephfs"
|
||||
- "status-success=ci/centos/upgrade-tests-rbd"
|
||||
- "status-success=DCO"
|
||||
actions:
|
||||
queue:
|
||||
name: default
|
||||
@ -153,30 +228,57 @@ pull_request_rules:
|
||||
|
||||
- name: automatic merge PR having ready-to-merge label
|
||||
conditions:
|
||||
- label!=DNM
|
||||
- label=ready-to-merge
|
||||
- base~=^(devel)|(release-.+)$
|
||||
- "approved-reviews-by=@ceph/ceph-csi-maintainers"
|
||||
- "status-success=codespell"
|
||||
- "status-success=multi-arch-build"
|
||||
- "status-success=go-test"
|
||||
- "status-success=golangci-lint"
|
||||
- "status-success=commitlint"
|
||||
- "status-success=mod-check"
|
||||
- "status-success=lint-extras"
|
||||
- "#changes-requested-reviews-by=0"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.25"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.26"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.27"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.25"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.25"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.27"
|
||||
- "status-success=ci/centos/upgrade-tests-cephfs"
|
||||
- "status-success=ci/centos/upgrade-tests-rbd"
|
||||
- "status-success=DCO"
|
||||
- or:
|
||||
- and:
|
||||
- base=release-v*
|
||||
- label!=DNM
|
||||
- label=ready-to-merge
|
||||
- "approved-reviews-by=@ceph/ceph-csi-maintainers"
|
||||
- "status-success=codespell"
|
||||
- "status-success=multi-arch-build"
|
||||
- "status-success=go-test"
|
||||
- "status-success=golangci-lint"
|
||||
- "status-success=commitlint"
|
||||
- "status-success=mod-check"
|
||||
- "status-success=lint-extras"
|
||||
- "#changes-requested-reviews-by=0"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.25"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.26"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.27"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.25"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.25"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.27"
|
||||
- "status-success=ci/centos/upgrade-tests-cephfs"
|
||||
- "status-success=ci/centos/upgrade-tests-rbd"
|
||||
- "status-success=DCO"
|
||||
- and:
|
||||
- base=devel
|
||||
- label!=DNM
|
||||
- label=ready-to-merge
|
||||
- "approved-reviews-by=@ceph/ceph-csi-maintainers"
|
||||
- "status-success=codespell"
|
||||
- "status-success=multi-arch-build"
|
||||
- "status-success=go-test"
|
||||
- "status-success=golangci-lint"
|
||||
- "status-success=commitlint"
|
||||
- "status-success=mod-check"
|
||||
- "status-success=lint-extras"
|
||||
- "#changes-requested-reviews-by=0"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.26"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.27"
|
||||
- "status-success=ci/centos/k8s-e2e-external-storage/1.28"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e-helm/k8s-1.28"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.26"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.27"
|
||||
- "status-success=ci/centos/mini-e2e/k8s-1.28"
|
||||
- "status-success=ci/centos/upgrade-tests-cephfs"
|
||||
- "status-success=ci/centos/upgrade-tests-rbd"
|
||||
- "status-success=DCO"
|
||||
actions:
|
||||
queue:
|
||||
name: default
|
||||
|
@ -4,13 +4,13 @@ go 1.18
|
||||
|
||||
require (
|
||||
github.com/google/go-github v17.0.0+incompatible
|
||||
golang.org/x/oauth2 v0.10.0
|
||||
golang.org/x/oauth2 v0.11.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
golang.org/x/net v0.12.0 // indirect
|
||||
golang.org/x/net v0.14.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
)
|
||||
|
@ -11,10 +11,10 @@ github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
||||
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
|
||||
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
|
||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
|
||||
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
|
1
actions/retest/vendor/golang.org/x/oauth2/internal/client_appengine.go
generated
vendored
1
actions/retest/vendor/golang.org/x/oauth2/internal/client_appengine.go
generated
vendored
@ -3,7 +3,6 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build appengine
|
||||
// +build appengine
|
||||
|
||||
package internal
|
||||
|
||||
|
6
actions/retest/vendor/modules.txt
vendored
6
actions/retest/vendor/modules.txt
vendored
@ -7,11 +7,11 @@ github.com/google/go-github/github
|
||||
# github.com/google/go-querystring v1.1.0
|
||||
## explicit; go 1.10
|
||||
github.com/google/go-querystring/query
|
||||
# golang.org/x/net v0.12.0
|
||||
# golang.org/x/net v0.14.0
|
||||
## explicit; go 1.17
|
||||
golang.org/x/net/context
|
||||
# golang.org/x/oauth2 v0.10.0
|
||||
## explicit; go 1.17
|
||||
# golang.org/x/oauth2 v0.11.0
|
||||
## explicit; go 1.18
|
||||
golang.org/x/oauth2
|
||||
golang.org/x/oauth2/internal
|
||||
# google.golang.org/appengine v1.6.7
|
||||
|
14
api/go.mod
14
api/go.mod
@ -6,26 +6,26 @@ require (
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/openshift/api v0.0.0-20230320192226-1fc631efd341
|
||||
github.com/stretchr/testify v1.8.4
|
||||
k8s.io/api v0.27.4
|
||||
k8s.io/api v0.28.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
golang.org/x/net v0.13.0 // indirect
|
||||
golang.org/x/text v0.11.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apimachinery v0.27.4 // indirect
|
||||
k8s.io/klog/v2 v2.90.1 // indirect
|
||||
k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect
|
||||
k8s.io/apimachinery v0.28.1 // indirect
|
||||
k8s.io/klog/v2 v2.100.1 // indirect
|
||||
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
)
|
||||
|
32
api/go.sum
32
api/go.sum
@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
@ -16,7 +16,7 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
@ -27,7 +27,7 @@ github.com/openshift/api v0.0.0-20230320192226-1fc631efd341 h1:PhLdiIlVqgN4frwrG
|
||||
github.com/openshift/api v0.0.0-20230320192226-1fc631efd341/go.mod h1:ctXNyWanKEjGj8sss1KjjHQ3ENKFm33FFnS5BKaIPh4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
@ -44,8 +44,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY=
|
||||
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -54,8 +54,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
|
||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
@ -73,14 +73,14 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.27.4 h1:0pCo/AN9hONazBKlNUdhQymmnfLRbSZjd5H5H3f0bSs=
|
||||
k8s.io/api v0.27.4/go.mod h1:O3smaaX15NfxjzILfiln1D8Z3+gEYpjEpiNA/1EVK1Y=
|
||||
k8s.io/apimachinery v0.27.4 h1:CdxflD4AF61yewuid0fLl6bM4a3q04jWel0IlP+aYjs=
|
||||
k8s.io/apimachinery v0.27.4/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
|
||||
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
|
||||
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY=
|
||||
k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
k8s.io/api v0.28.1 h1:i+0O8k2NPBCPYaMB+uCkseEbawEt/eFaiRqUx8aB108=
|
||||
k8s.io/api v0.28.1/go.mod h1:uBYwID+66wiL28Kn2tBjBYQdEU0Xk0z5qF8bIBqk/Dg=
|
||||
k8s.io/apimachinery v0.28.1 h1:EJD40og3GizBSV3mkIoXQBsws32okPOy+MkRyzh6nPY=
|
||||
k8s.io/apimachinery v0.28.1/go.mod h1:X0xh/chESs2hP9koe+SdIAcXWcQ+RM5hy0ZynB+yEvw=
|
||||
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
|
||||
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk=
|
||||
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
||||
|
10
build.env
10
build.env
@ -15,8 +15,8 @@ CSI_IMAGE_VERSION=canary
|
||||
CSI_UPGRADE_VERSION=v3.9.0
|
||||
|
||||
# Ceph version to use
|
||||
BASE_IMAGE=quay.io/ceph/ceph:v17
|
||||
CEPH_VERSION=quincy
|
||||
BASE_IMAGE=quay.io/ceph/ceph:v18
|
||||
CEPH_VERSION=reef
|
||||
|
||||
# standard Golang options
|
||||
GOLANG_VERSION=1.20.4
|
||||
@ -44,14 +44,14 @@ HELM_SCRIPT=https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
|
||||
HELM_VERSION=v3.10.1
|
||||
|
||||
# minikube settings
|
||||
MINIKUBE_VERSION=v1.31.0
|
||||
MINIKUBE_VERSION=v1.31.2
|
||||
VM_DRIVER=none
|
||||
CHANGE_MINIKUBE_NONE_USER=true
|
||||
|
||||
# Rook options
|
||||
ROOK_VERSION=v1.10.9
|
||||
ROOK_VERSION=v1.12.1
|
||||
# Provide ceph image path
|
||||
ROOK_CEPH_CLUSTER_IMAGE=quay.io/ceph/ceph:v17
|
||||
ROOK_CEPH_CLUSTER_IMAGE=quay.io/ceph/ceph:v18
|
||||
|
||||
# CSI sidecar version
|
||||
CSI_ATTACHER_VERSION=v4.3.0
|
||||
|
@ -47,7 +47,7 @@ To install the Chart into your Kubernetes cluster
|
||||
After installation succeeds, you can get a status of Chart
|
||||
|
||||
```bash
|
||||
helm status "ceph-csi-cephfs"
|
||||
helm status --namespace "ceph-csi-cephfs" "ceph-csi-cephfs"
|
||||
```
|
||||
|
||||
### Upgrade Chart
|
||||
|
@ -198,8 +198,8 @@ provisioner:
|
||||
name: resizer
|
||||
enabled: true
|
||||
image:
|
||||
repository: registry.k8s.io/sig-storage/csi-resizer
|
||||
tag: v1.8.0
|
||||
repository: gcr.io/k8s-staging-sig-storage/csi-resizer
|
||||
tag: canary
|
||||
pullPolicy: IfNotPresent
|
||||
resources: {}
|
||||
## For further options, check
|
||||
|
@ -47,7 +47,7 @@ To install the Chart into your Kubernetes cluster
|
||||
After installation succeeds, you can get a status of Chart
|
||||
|
||||
```bash
|
||||
helm status "ceph-csi-rbd"
|
||||
helm status --namespace "ceph-csi-rbd" "ceph-csi-rbd"
|
||||
```
|
||||
|
||||
### Upgrade Chart
|
||||
|
@ -243,8 +243,8 @@ provisioner:
|
||||
name: resizer
|
||||
enabled: true
|
||||
image:
|
||||
repository: registry.k8s.io/sig-storage/csi-resizer
|
||||
tag: v1.8.0
|
||||
repository: gcr.io/k8s-staging-sig-storage/csi-resizer
|
||||
tag: canary
|
||||
pullPolicy: IfNotPresent
|
||||
resources: {}
|
||||
## For further options, check
|
||||
|
@ -4,12 +4,13 @@ ARG BASE_IMAGE
|
||||
|
||||
FROM ${BASE_IMAGE} as updated_base
|
||||
|
||||
# TODO: remove the following cmd, when issue
|
||||
# https://github.com/ceph/ceph-container/issues/2034 is fixed.
|
||||
# TODO: remove the following cmd, when issues
|
||||
# https://github.com/ceph/ceph-container/issues/2034
|
||||
# https://github.com/ceph/ceph-container/issues/2141 are fixed.
|
||||
RUN dnf config-manager --disable \
|
||||
tcmu-runner,tcmu-runner-source,tcmu-runner-noarch,ceph-iscsi || true
|
||||
tcmu-runner,tcmu-runner-source,tcmu-runner-noarch,ceph-iscsi,ganesha || true
|
||||
|
||||
RUN dnf -y update \
|
||||
RUN dnf -y update --nobest \
|
||||
&& dnf clean all \
|
||||
&& rm -rf /var/cache/yum
|
||||
|
||||
|
@ -62,7 +62,7 @@ spec:
|
||||
- name: socket-dir
|
||||
mountPath: /csi
|
||||
- name: csi-resizer
|
||||
image: registry.k8s.io/sig-storage/csi-resizer:v1.8.0
|
||||
image: gcr.io/k8s-staging-sig-storage/csi-resizer:canary
|
||||
args:
|
||||
- "--csi-address=$(ADDRESS)"
|
||||
- "--v=1"
|
||||
|
@ -57,7 +57,7 @@ spec:
|
||||
- name: socket-dir
|
||||
mountPath: /csi
|
||||
- name: csi-resizer
|
||||
image: registry.k8s.io/sig-storage/csi-resizer:v1.8.0
|
||||
image: gcr.io/k8s-staging-sig-storage/csi-resizer:canary
|
||||
args:
|
||||
- "--csi-address=$(ADDRESS)"
|
||||
- "--v=1"
|
||||
|
@ -99,7 +99,7 @@ spec:
|
||||
- name: socket-dir
|
||||
mountPath: /csi
|
||||
- name: csi-resizer
|
||||
image: registry.k8s.io/sig-storage/csi-resizer:v1.8.0
|
||||
image: gcr.io/k8s-staging-sig-storage/csi-resizer:canary
|
||||
args:
|
||||
- "--csi-address=$(ADDRESS)"
|
||||
- "--v=1"
|
||||
|
@ -44,6 +44,7 @@ var (
|
||||
cephFSExamplePath = examplePath + "cephfs/"
|
||||
subvolumegroup = "e2e"
|
||||
fileSystemName = "myfs"
|
||||
fileSystemPoolName = "myfs-replicated"
|
||||
)
|
||||
|
||||
func deployCephfsPlugin() {
|
||||
@ -394,11 +395,19 @@ var _ = Describe(cephfsType, func() {
|
||||
}
|
||||
validateSubvolumeCount(f, 1, fileSystemName, subvolumegroup)
|
||||
validateOmapCount(f, 1, cephfsType, metadataPool, volumesType)
|
||||
pvcName := app.Spec.Volumes[0].Name
|
||||
// delete pod
|
||||
err = deletePod(app.Name, app.Namespace, f.ClientSet, deployTimeout)
|
||||
if err != nil {
|
||||
framework.Failf("failed to delete application: %v", err)
|
||||
}
|
||||
|
||||
// wait for the associated PVC to be deleted
|
||||
err = waitForPVCToBeDeleted(f.ClientSet, app.Namespace, pvcName, deployTimeout)
|
||||
if err != nil {
|
||||
framework.Failf("failed to wait for PVC deletion: %v", err)
|
||||
}
|
||||
|
||||
validateSubvolumeCount(f, 0, fileSystemName, subvolumegroup)
|
||||
validateOmapCount(f, 0, cephfsType, metadataPool, volumesType)
|
||||
err = deleteResource(cephFSExamplePath + "storageclass.yaml")
|
||||
@ -1613,6 +1622,7 @@ var _ = Describe(cephfsType, func() {
|
||||
scOpts := map[string]string{
|
||||
"encrypted": "true",
|
||||
"encryptionKMSID": kmsID,
|
||||
"pool": fileSystemPoolName,
|
||||
}
|
||||
|
||||
err = createCephfsStorageClass(f.ClientSet, f, true, scOpts)
|
||||
|
@ -268,40 +268,6 @@ func (yrn *yamlResourceNamespaced) Do(action kubectlAction) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type rookNFSResource struct {
|
||||
f *framework.Framework
|
||||
modules []string
|
||||
orchBackend string
|
||||
}
|
||||
|
||||
func (rnr *rookNFSResource) Do(action kubectlAction) error {
|
||||
if action != kubectlCreate {
|
||||
// we won't disabled modules
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, module := range rnr.modules {
|
||||
cmd := fmt.Sprintf("ceph mgr module enable %s", module)
|
||||
_, _, err := execCommandInToolBoxPod(rnr.f, cmd, rookNamespace)
|
||||
if err != nil {
|
||||
// depending on the Ceph/Rook version, modules are
|
||||
// enabled by default
|
||||
framework.Logf("enabling module %q failed: %v", module, err)
|
||||
}
|
||||
}
|
||||
|
||||
if rnr.orchBackend != "" {
|
||||
// this is not required for all Rook versions, allow failing
|
||||
cmd := fmt.Sprintf("ceph orch set backend %s", rnr.orchBackend)
|
||||
_, _, err := execCommandInToolBoxPod(rnr.f, cmd, rookNamespace)
|
||||
if err != nil {
|
||||
framework.Logf("setting orch backend %q failed: %v", rnr.orchBackend, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func waitForDeploymentUpdateScale(
|
||||
c kubernetes.Interface,
|
||||
ns,
|
||||
|
13
e2e/nfs.go
13
e2e/nfs.go
@ -72,14 +72,14 @@ func deployNFSPlugin(f *framework.Framework) {
|
||||
framework.Failf("failed to create pool for NFS config %q: %v", nfsPoolName, err)
|
||||
}
|
||||
|
||||
createORDeleteNFSResources(f, kubectlCreate)
|
||||
createORDeleteNFSResources(kubectlCreate)
|
||||
}
|
||||
|
||||
func deleteNFSPlugin() {
|
||||
createORDeleteNFSResources(nil, kubectlDelete)
|
||||
createORDeleteNFSResources(kubectlDelete)
|
||||
}
|
||||
|
||||
func createORDeleteNFSResources(f *framework.Framework, action kubectlAction) {
|
||||
func createORDeleteNFSResources(action kubectlAction) {
|
||||
cephConfigFile := getConfigFile(cephConfconfigMap, deployPath, examplePath)
|
||||
resources := []ResourceDeployer{
|
||||
// shared resources
|
||||
@ -112,12 +112,7 @@ func createORDeleteNFSResources(f *framework.Framework, action kubectlAction) {
|
||||
filename: nfsDirPath + nfsNodePlugin,
|
||||
namespace: cephCSINamespace,
|
||||
},
|
||||
// NFS-export management by Rook
|
||||
&rookNFSResource{
|
||||
f: f,
|
||||
modules: []string{"rook", "nfs"},
|
||||
orchBackend: "rook",
|
||||
},
|
||||
// NFS server deployment
|
||||
&yamlResourceNamespaced{
|
||||
filename: nfsExamplePath + nfsRookCephNFS,
|
||||
namespace: rookNamespace,
|
||||
|
32
e2e/pvc.go
32
e2e/pvc.go
@ -430,3 +430,35 @@ func getMetricsForPVC(f *framework.Framework, pvc *v1.PersistentVolumeClaim, t i
|
||||
return false, nil
|
||||
})
|
||||
}
|
||||
|
||||
func waitForPVCToBeDeleted(c kubernetes.Interface, namespace, pvcName string, t int) error {
|
||||
timeout := time.Duration(t) * time.Minute
|
||||
ctx := context.TODO()
|
||||
start := time.Now()
|
||||
|
||||
return wait.PollUntilContextTimeout(ctx, poll, timeout, true, func(ctx context.Context) (bool, error) {
|
||||
pvc, err := c.CoreV1().PersistentVolumeClaims(namespace).Get(ctx, pvcName, metav1.GetOptions{})
|
||||
// Check that the PVC is really deleted.
|
||||
framework.Logf(
|
||||
"waiting for PVC %s in state %s to be deleted (%d seconds elapsed)",
|
||||
pvcName,
|
||||
pvc.Status.String(),
|
||||
int(time.Since(start).Seconds()))
|
||||
if err == nil {
|
||||
framework.Logf("PVC %s (status: %s) has not been deleted yet, rechecking...", pvcName, pvc.Status)
|
||||
|
||||
return false, nil
|
||||
}
|
||||
if isRetryableAPIError(err) {
|
||||
framework.Logf("failed to verify deletion of PVC %s (status: %s): %v", pvcName, pvc.Status, err)
|
||||
|
||||
return false, nil
|
||||
}
|
||||
if !apierrs.IsNotFound(err) {
|
||||
return false, fmt.Errorf("get on deleted PVC %v failed with error other than \"not found\": %w", pvcName, err)
|
||||
}
|
||||
|
||||
// PVC has been successfully deleted
|
||||
return true, nil
|
||||
})
|
||||
}
|
||||
|
@ -813,10 +813,18 @@ var _ = Describe("RBD", func() {
|
||||
// validate created backend rbd images
|
||||
validateRBDImageCount(f, 1, defaultRBDPool)
|
||||
validateOmapCount(f, 1, rbdType, defaultRBDPool, volumesType)
|
||||
pvcName := app.Spec.Volumes[0].Name
|
||||
err = deletePod(app.Name, app.Namespace, f.ClientSet, deployTimeout)
|
||||
if err != nil {
|
||||
framework.Failf("failed to delete application: %v", err)
|
||||
}
|
||||
|
||||
// wait for the associated PVC to be deleted
|
||||
err = waitForPVCToBeDeleted(f.ClientSet, app.Namespace, pvcName, deployTimeout)
|
||||
if err != nil {
|
||||
framework.Failf("failed to wait for PVC deletion: %v", err)
|
||||
}
|
||||
|
||||
// validate created backend rbd images
|
||||
validateRBDImageCount(f, 0, defaultRBDPool)
|
||||
validateOmapCount(f, 0, rbdType, defaultRBDPool, volumesType)
|
||||
|
@ -827,13 +827,13 @@ func createPool(f *framework.Framework, name string) error {
|
||||
pgCount = 128
|
||||
size = 1
|
||||
)
|
||||
// ceph osd pool create replicapool
|
||||
cmd := fmt.Sprintf("ceph osd pool create %s %d", name, pgCount)
|
||||
// ceph osd pool create name
|
||||
cmd := fmt.Sprintf("ceph osd pool create %s %d --yes-i-really-mean-it", name, pgCount)
|
||||
_, _, err := execCommandInToolBoxPod(f, cmd, rookNamespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// ceph osd pool set replicapool size 1
|
||||
// ceph osd pool set name size 1
|
||||
cmd = fmt.Sprintf("ceph osd pool set %s size %d --yes-i-really-mean-it", name, size)
|
||||
_, _, err = execCommandInToolBoxPod(f, cmd, rookNamespace)
|
||||
|
||||
|
@ -10,6 +10,9 @@ making configuring the Ceph cluster a minimal effort.
|
||||
Ceph does not enable the NFS-service by default. In order for Rook Ceph to be
|
||||
able to configure NFS-exports, the NFS-service needs to be configured first.
|
||||
|
||||
- Required for Ceph v16.2.7 and below
|
||||
- Optional for Ceph v16.2.8 and above
|
||||
|
||||
In the [Rook Toolbox][rook_toolbox], run the following commands:
|
||||
|
||||
```console
|
||||
|
148
go.mod
148
go.mod
@ -3,26 +3,26 @@ module github.com/ceph/ceph-csi
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/IBM/keyprotect-go-client v0.10.0
|
||||
github.com/aws/aws-sdk-go v1.44.313
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.21.0
|
||||
github.com/IBM/keyprotect-go-client v0.12.2
|
||||
github.com/aws/aws-sdk-go v1.44.333
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.21.5
|
||||
github.com/ceph/ceph-csi/api v0.0.0-00010101000000-000000000000
|
||||
// TODO: API for managing subvolume metadata and snapshot metadata requires `ceph_ci_untested` build-tag
|
||||
github.com/ceph/go-ceph v0.22.0
|
||||
github.com/ceph/go-ceph v0.23.0
|
||||
github.com/container-storage-interface/spec v1.8.0
|
||||
github.com/csi-addons/replication-lib-utils v0.2.0
|
||||
github.com/csi-addons/spec v0.2.1-0.20230606140122-d20966d2e444
|
||||
github.com/gemalto/kmip-go v0.0.9
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/google/fscrypt v0.3.4
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/google/uuid v1.3.1
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/hashicorp/vault/api v1.9.2
|
||||
github.com/kubernetes-csi/csi-lib-utils v0.14.0
|
||||
github.com/kubernetes-csi/external-snapshotter/client/v6 v6.2.0
|
||||
github.com/libopenstorage/secrets v0.0.0-20210908194121-a1d19aa9713a
|
||||
github.com/onsi/ginkgo/v2 v2.11.0
|
||||
github.com/onsi/ginkgo/v2 v2.12.0
|
||||
github.com/onsi/gomega v1.27.10
|
||||
github.com/pkg/xattr v0.4.9
|
||||
github.com/prometheus/client_golang v1.16.0
|
||||
@ -35,41 +35,41 @@ require (
|
||||
//
|
||||
// when updating k8s.io/kubernetes, make sure to update the replace section too
|
||||
//
|
||||
k8s.io/api v0.27.4
|
||||
k8s.io/apimachinery v0.27.4
|
||||
k8s.io/api v0.28.1
|
||||
k8s.io/apimachinery v0.28.1
|
||||
k8s.io/client-go v12.0.0+incompatible
|
||||
k8s.io/cloud-provider v0.27.4
|
||||
k8s.io/cloud-provider v0.28.0
|
||||
k8s.io/klog/v2 v2.100.1
|
||||
k8s.io/kubernetes v1.27.4
|
||||
k8s.io/mount-utils v0.27.4
|
||||
k8s.io/kubernetes v1.28.1
|
||||
k8s.io/mount-utils v0.28.0
|
||||
k8s.io/pod-security-admission v0.0.0
|
||||
k8s.io/utils v0.0.0-20230209194617-a36077c30491
|
||||
sigs.k8s.io/controller-runtime v0.15.1-0.20230524200249-30eae58f1b98
|
||||
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2
|
||||
sigs.k8s.io/controller-runtime v0.16.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/ansel1/merry v1.6.2 // indirect
|
||||
github.com/ansel1/merry/v2 v2.0.1 // indirect
|
||||
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
|
||||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
|
||||
github.com/armon/go-metrics v0.3.10 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.20.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.37 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.31 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.31 // indirect
|
||||
github.com/aws/smithy-go v1.14.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.21.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 // indirect
|
||||
github.com/aws/smithy-go v1.14.2 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.4.0 // indirect
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
||||
@ -81,14 +81,14 @@ require (
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.1 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/cel-go v0.12.6 // indirect
|
||||
github.com/google/gnostic v0.6.9 // indirect
|
||||
github.com/google/cel-go v0.16.0 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
|
||||
@ -108,7 +108,7 @@ require (
|
||||
github.com/hashicorp/vault v1.11.11 // indirect
|
||||
github.com/hashicorp/vault/sdk v0.7.0 // indirect
|
||||
github.com/imdario/mergo v0.3.13 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
@ -131,15 +131,15 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_model v0.4.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/common v0.44.0 // indirect
|
||||
github.com/prometheus/procfs v0.10.1 // indirect
|
||||
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||
github.com/spf13/cobra v1.6.0 // indirect
|
||||
github.com/spf13/cobra v1.7.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stoewer/go-strcase v1.2.0 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.7 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.7 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.9 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.9 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.1 // indirect
|
||||
go.opentelemetry.io/otel v1.10.0 // indirect
|
||||
@ -150,32 +150,31 @@ require (
|
||||
go.opentelemetry.io/otel/sdk v1.10.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.10.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/oauth2 v0.7.0 // indirect
|
||||
golang.org/x/sync v0.2.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.25.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 // indirect
|
||||
golang.org/x/oauth2 v0.8.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/term v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.9.3 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect
|
||||
google.golang.org/api v0.110.0 // indirect
|
||||
golang.org/x/tools v0.12.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.27.4 // indirect
|
||||
k8s.io/apiserver v0.27.4 // indirect
|
||||
k8s.io/component-base v0.27.4 // indirect
|
||||
k8s.io/component-helpers v0.27.4 // indirect
|
||||
k8s.io/controller-manager v0.27.4 // indirect
|
||||
k8s.io/kms v0.27.4 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
|
||||
k8s.io/apiextensions-apiserver v0.28.0 // indirect
|
||||
k8s.io/apiserver v0.28.0 // indirect
|
||||
k8s.io/component-base v0.28.0 // indirect
|
||||
k8s.io/component-helpers v0.28.0 // indirect
|
||||
k8s.io/controller-manager v0.28.0 // indirect
|
||||
k8s.io/kms v0.28.0 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
|
||||
k8s.io/kubectl v0.0.0 // indirect
|
||||
k8s.io/kubelet v0.0.0 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 // indirect
|
||||
@ -194,32 +193,33 @@ replace (
|
||||
//
|
||||
// k8s.io/kubernetes depends on these k8s.io packages, but unversioned
|
||||
//
|
||||
k8s.io/api => k8s.io/api v0.27.4
|
||||
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.27.4
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.27.4
|
||||
k8s.io/apiserver => k8s.io/apiserver v0.27.4
|
||||
k8s.io/cli-runtime => k8s.io/cli-runtime v0.27.4
|
||||
k8s.io/client-go => k8s.io/client-go v0.27.4
|
||||
k8s.io/cloud-provider => k8s.io/cloud-provider v0.27.4
|
||||
k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.27.4
|
||||
k8s.io/code-generator => k8s.io/code-generator v0.27.4
|
||||
k8s.io/component-base => k8s.io/component-base v0.27.4
|
||||
k8s.io/component-helpers => k8s.io/component-helpers v0.27.4
|
||||
k8s.io/controller-manager => k8s.io/controller-manager v0.27.4
|
||||
k8s.io/cri-api => k8s.io/cri-api v0.27.4
|
||||
k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.27.4
|
||||
k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.27.4
|
||||
k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.27.4
|
||||
k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.27.4
|
||||
k8s.io/kube-proxy => k8s.io/kube-proxy v0.27.4
|
||||
k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.27.4
|
||||
k8s.io/kubectl => k8s.io/kubectl v0.27.4
|
||||
k8s.io/kubelet => k8s.io/kubelet v0.27.4
|
||||
k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.27.4
|
||||
k8s.io/metrics => k8s.io/metrics v0.27.4
|
||||
k8s.io/mount-utils => k8s.io/mount-utils v0.27.4
|
||||
k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.27.4
|
||||
k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.27.4
|
||||
k8s.io/api => k8s.io/api v0.28.0
|
||||
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.28.0
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.28.0
|
||||
k8s.io/apiserver => k8s.io/apiserver v0.28.0
|
||||
k8s.io/cli-runtime => k8s.io/cli-runtime v0.28.0
|
||||
k8s.io/client-go => k8s.io/client-go v0.28.0
|
||||
k8s.io/cloud-provider => k8s.io/cloud-provider v0.28.0
|
||||
k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.28.0
|
||||
k8s.io/code-generator => k8s.io/code-generator v0.28.0
|
||||
k8s.io/component-base => k8s.io/component-base v0.28.0
|
||||
k8s.io/component-helpers => k8s.io/component-helpers v0.28.0
|
||||
k8s.io/controller-manager => k8s.io/controller-manager v0.28.0
|
||||
k8s.io/cri-api => k8s.io/cri-api v0.28.0
|
||||
k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.28.0
|
||||
k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.28.0
|
||||
k8s.io/endpointslice => k8s.io/endpointslice v0.28.0
|
||||
k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.28.0
|
||||
k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.28.0
|
||||
k8s.io/kube-proxy => k8s.io/kube-proxy v0.28.0
|
||||
k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.28.0
|
||||
k8s.io/kubectl => k8s.io/kubectl v0.28.0
|
||||
k8s.io/kubelet => k8s.io/kubelet v0.28.0
|
||||
k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.28.0
|
||||
k8s.io/metrics => k8s.io/metrics v0.28.0
|
||||
k8s.io/mount-utils => k8s.io/mount-utils v0.28.0
|
||||
k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.28.0
|
||||
k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.28.0
|
||||
// layeh.com seems to be misbehaving
|
||||
layeh.com/radius => github.com/layeh/radius v0.0.0-20190322222518-890bc1058917
|
||||
)
|
||||
|
@ -542,9 +542,10 @@ func (vo *VolumeOptions) populateVolumeOptionsFromBackingSnapshot(
|
||||
return fmtBackingSnapshotOptionMismatch("clusterID", vo.ClusterID, parentBackingSnapVolOpts.ClusterID)
|
||||
}
|
||||
|
||||
if vo.Pool != "" {
|
||||
return errors.New("cannot set pool for snapshot-backed volume")
|
||||
}
|
||||
// Pool parameter is optional and only used to set 'pool_layout' argument for
|
||||
// subvolume and subvolume clone create commands.
|
||||
// Setting this to empty since it is not used with Snapshot-backed volume.
|
||||
vo.Pool = ""
|
||||
|
||||
if vo.MetadataPool != parentBackingSnapVolOpts.MetadataPool {
|
||||
return fmtBackingSnapshotOptionMismatch("MetadataPool", vo.MetadataPool, parentBackingSnapVolOpts.MetadataPool)
|
||||
|
@ -24,7 +24,7 @@ import (
|
||||
|
||||
"github.com/container-storage-interface/spec/lib/go/csi"
|
||||
// google.golang.org/protobuf/encoding doesn't offer MessageV2().
|
||||
"github.com/golang/protobuf/proto" //nolint:staticcheck // See comment above.
|
||||
"github.com/golang/protobuf/proto" //nolint:all // See comment above.
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
)
|
||||
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
clientConfig "sigs.k8s.io/controller-runtime/pkg/client/config"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
|
||||
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
|
||||
)
|
||||
|
||||
// Manager is the interface that will wrap Add function.
|
||||
@ -62,7 +63,7 @@ func Start(config Config) error {
|
||||
opts := manager.Options{
|
||||
LeaderElection: true,
|
||||
// disable metrics
|
||||
MetricsBindAddress: "0",
|
||||
Metrics: metricsserver.Options{BindAddress: "0"},
|
||||
LeaderElectionNamespace: config.Namespace,
|
||||
LeaderElectionResourceLock: resourcelock.LeasesResourceLock,
|
||||
LeaderElectionID: electionID,
|
||||
|
@ -50,6 +50,11 @@ const (
|
||||
// imageMirrorModeJournal uses journaling to propagate RBD images between
|
||||
// ceph clusters.
|
||||
imageMirrorModeJournal imageMirroringMode = "journal"
|
||||
|
||||
// imageCreationTimeKey is the key to get/set the image creation timestamp
|
||||
// on the image metadata. The key is starting with `.rbd` so that it will
|
||||
// not get replicated to remote cluster.
|
||||
imageCreationTimeKey = ".rbd.image.creation_time"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -480,6 +485,14 @@ func (rs *ReplicationServer) DemoteVolume(ctx context.Context,
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
creationTime, err := rbdVol.GetImageCreationTime()
|
||||
if err != nil {
|
||||
log.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
mirroringInfo, err := rbdVol.GetImageMirroringInfo()
|
||||
if err != nil {
|
||||
log.ErrorLog(ctx, err.Error())
|
||||
@ -497,6 +510,17 @@ func (rs *ReplicationServer) DemoteVolume(ctx context.Context,
|
||||
|
||||
// demote image to secondary
|
||||
if mirroringInfo.Primary {
|
||||
// store the image creation time for resync
|
||||
_, err = rbdVol.GetMetadata(imageCreationTimeKey)
|
||||
if err != nil && errors.Is(err, librbd.ErrNotFound) {
|
||||
err = rbdVol.SetMetadata(imageCreationTimeKey, timestampToString(creationTime))
|
||||
}
|
||||
if err != nil {
|
||||
log.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
err = rbdVol.DemoteImage()
|
||||
if err != nil {
|
||||
log.ErrorLog(ctx, err.Error())
|
||||
@ -538,6 +562,8 @@ func checkRemoteSiteStatus(ctx context.Context, mirrorStatus *librbd.GlobalMirro
|
||||
// ResyncVolume extracts the RBD volume information from the volumeID, If the
|
||||
// image is present, mirroring is enabled and the image is in demoted state.
|
||||
// If yes it will resync the image to correct the split-brain.
|
||||
//
|
||||
//nolint:gocyclo,cyclop // TODO: reduce complexity
|
||||
func (rs *ReplicationServer) ResyncVolume(ctx context.Context,
|
||||
req *replication.ResyncVolumeRequest,
|
||||
) (*replication.ResyncVolumeResponse, error) {
|
||||
@ -578,7 +604,7 @@ func (rs *ReplicationServer) ResyncVolume(ctx context.Context,
|
||||
// it takes time for this operation.
|
||||
log.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Aborted, err.Error())
|
||||
return nil, status.Errorf(codes.Aborted, err.Error())
|
||||
}
|
||||
|
||||
if mirroringInfo.State != librbd.MirrorImageEnabled {
|
||||
@ -637,14 +663,40 @@ func (rs *ReplicationServer) ResyncVolume(ctx context.Context,
|
||||
ready = checkRemoteSiteStatus(ctx, mirrorStatus)
|
||||
}
|
||||
|
||||
err = rbdVol.ResyncVol(localStatus, req.Force)
|
||||
creationTime, err := rbdVol.GetImageCreationTime()
|
||||
if err != nil {
|
||||
return nil, getGRPCError(err)
|
||||
return nil, status.Errorf(codes.Internal, "failed to get image info for %s: %s", rbdVol, err.Error())
|
||||
}
|
||||
|
||||
err = checkVolumeResyncStatus(localStatus)
|
||||
// image creation time is stored in the image metadata. it looks like
|
||||
// `"seconds:1692879841 nanos:631526669"`
|
||||
savedImageTime, err := rbdVol.GetMetadata(imageCreationTimeKey)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
return nil, status.Errorf(codes.Internal,
|
||||
"failed to get %s key from image metadata for %s: %s",
|
||||
imageCreationTimeKey,
|
||||
rbdVol,
|
||||
err.Error())
|
||||
}
|
||||
|
||||
st, err := timestampFromString(savedImageTime)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to parse image creation time: %s", err.Error())
|
||||
}
|
||||
log.DebugLog(ctx, "image %s, savedImageTime=%v, currentImageTime=%v", rbdVol, st, creationTime.AsTime())
|
||||
|
||||
if req.Force && st.Equal(creationTime.AsTime()) {
|
||||
err = rbdVol.ResyncVol(localStatus)
|
||||
if err != nil {
|
||||
return nil, getGRPCError(err)
|
||||
}
|
||||
}
|
||||
|
||||
if !ready {
|
||||
err = checkVolumeResyncStatus(localStatus)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
err = rbdVol.RepairResyncedImageID(ctx, ready)
|
||||
@ -659,6 +711,40 @@ func (rs *ReplicationServer) ResyncVolume(ctx context.Context,
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// timestampToString converts the time.Time object to string.
|
||||
func timestampToString(st *timestamppb.Timestamp) string {
|
||||
return fmt.Sprintf("seconds:%d nanos:%d", st.Seconds, st.Nanos)
|
||||
}
|
||||
|
||||
// timestampFromString parses the timestamp string and returns the time.Time
|
||||
// object.
|
||||
func timestampFromString(timestamp string) (time.Time, error) {
|
||||
st := time.Time{}
|
||||
parts := strings.Fields(timestamp)
|
||||
if len(parts) != 2 {
|
||||
return st, fmt.Errorf("failed to parse image creation time: %s", timestamp)
|
||||
}
|
||||
if len(strings.Split(parts[0], ":")) != 2 || len(strings.Split(parts[1], ":")) != 2 {
|
||||
return st, fmt.Errorf("failed to parse image creation time: %s", timestamp)
|
||||
}
|
||||
secondsStr := strings.Split(parts[0], ":")[1]
|
||||
nanosStr := strings.Split(parts[1], ":")[1]
|
||||
|
||||
seconds, err := strconv.ParseInt(secondsStr, 10, 64)
|
||||
if err != nil {
|
||||
return st, fmt.Errorf("failed to parse image creation time seconds: %s", err.Error())
|
||||
}
|
||||
|
||||
nanos, err := strconv.ParseInt(nanosStr, 10, 32)
|
||||
if err != nil {
|
||||
return st, fmt.Errorf("failed to parse image creation time nenos: %s", err.Error())
|
||||
}
|
||||
|
||||
st = time.Unix(seconds, nanos)
|
||||
|
||||
return st, nil
|
||||
}
|
||||
|
||||
func getGRPCError(err error) error {
|
||||
if err == nil {
|
||||
return status.Error(codes.OK, codes.OK.String())
|
||||
@ -854,20 +940,17 @@ func getLastSyncInfo(description string) (*replication.GetVolumeReplicationInfoR
|
||||
}
|
||||
|
||||
func checkVolumeResyncStatus(localStatus librbd.SiteMirrorImageStatus) error {
|
||||
// we are considering 2 states to check resync started and resync completed
|
||||
// as below. all other states will be considered as an error state so that
|
||||
// cephCSI can return error message and volume replication operator can
|
||||
// mark the VolumeReplication status as not resyncing for the volume.
|
||||
|
||||
// If the state is Replaying means the resync is going on.
|
||||
// Once the volume on remote cluster is demoted and resync
|
||||
// is completed the image state will be moved to UNKNOWN.
|
||||
// RBD mirror daemon should be always running on the primary cluster.
|
||||
if !localStatus.Up || (localStatus.State != librbd.MirrorImageStatusStateReplaying &&
|
||||
localStatus.State != librbd.MirrorImageStatusStateUnknown) {
|
||||
return fmt.Errorf(
|
||||
"not resyncing. Local status: daemon up=%t image is in %q state",
|
||||
localStatus.Up, localStatus.State)
|
||||
// we are considering local snapshot timestamp to check if the resync is
|
||||
// started or not, if we dont see local_snapshot_timestamp in the
|
||||
// description of localStatus, we are returning error. if we see the local
|
||||
// snapshot timestamp in the description we return resyncing started.
|
||||
description := localStatus.Description
|
||||
resp, err := getLastSyncInfo(description)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get last sync info: %w", err)
|
||||
}
|
||||
if resp.LastSyncTime == nil {
|
||||
return errors.New("last sync time is nil")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -225,74 +225,26 @@ func TestCheckVolumeResyncStatus(t *testing.T) {
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "test when rbd mirror daemon is not running",
|
||||
name: "test when local_snapshot_timestamp is non zero",
|
||||
args: librbd.SiteMirrorImageStatus{
|
||||
State: librbd.MirrorImageStatusStateUnknown,
|
||||
Up: false,
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "test for unknown state",
|
||||
args: librbd.SiteMirrorImageStatus{
|
||||
State: librbd.MirrorImageStatusStateUnknown,
|
||||
Up: true,
|
||||
//nolint:lll // sample output cannot be split into multiple lines.
|
||||
Description: `replaying, {"bytes_per_second":0.0,"bytes_per_snapshot":81920.0,"last_snapshot_bytes":81920,"last_snapshot_sync_seconds":56743,"local_snapshot_timestamp":1684675261,"remote_snapshot_timestamp":1684675261,"replay_state":"idle"}`,
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "test for error state",
|
||||
name: "test when local_snapshot_timestamp is zero",
|
||||
//nolint:lll // sample output cannot be split into multiple lines.
|
||||
args: librbd.SiteMirrorImageStatus{
|
||||
State: librbd.MirrorImageStatusStateError,
|
||||
Up: true,
|
||||
Description: `replaying, {"bytes_per_second":0.0,"bytes_per_snapshot":81920.0,"last_snapshot_bytes":81920,"last_snapshot_sync_seconds":56743,"local_snapshot_timestamp":0,"remote_snapshot_timestamp":1684675261,"replay_state":"idle"}`,
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "test for syncing state",
|
||||
name: "test when local_snapshot_timestamp is not present",
|
||||
//nolint:lll // sample output cannot be split into multiple lines.
|
||||
args: librbd.SiteMirrorImageStatus{
|
||||
State: librbd.MirrorImageStatusStateSyncing,
|
||||
Up: true,
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "test for starting_replay state",
|
||||
args: librbd.SiteMirrorImageStatus{
|
||||
State: librbd.MirrorImageStatusStateStartingReplay,
|
||||
Up: true,
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "test for replaying state",
|
||||
args: librbd.SiteMirrorImageStatus{
|
||||
State: librbd.MirrorImageStatusStateReplaying,
|
||||
Up: true,
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "test for stopping_replay state",
|
||||
args: librbd.SiteMirrorImageStatus{
|
||||
State: librbd.MirrorImageStatusStateStoppingReplay,
|
||||
Up: true,
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "test for stopped state",
|
||||
args: librbd.SiteMirrorImageStatus{
|
||||
State: librbd.MirrorImageStatusStateStopped,
|
||||
Up: true,
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "test for invalid state",
|
||||
args: librbd.SiteMirrorImageStatus{
|
||||
State: librbd.MirrorImageStatusState(100),
|
||||
Up: true,
|
||||
Description: `replaying, {"bytes_per_second":0.0,"bytes_per_snapshot":81920.0,"last_snapshot_bytes":81920,"last_snapshot_sync_seconds":56743,"remote_snapshot_timestamp":1684675261,"replay_state":"idle"}`,
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
@ -644,3 +596,64 @@ func TestGetGRPCError(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_timestampFromString(t *testing.T) {
|
||||
tm := timestamppb.Now()
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
timestamp string
|
||||
want time.Time
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "valid timestamp",
|
||||
timestamp: timestampToString(tm),
|
||||
want: tm.AsTime().Local(),
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "invalid timestamp",
|
||||
timestamp: "invalid",
|
||||
want: time.Time{},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "empty timestamp",
|
||||
timestamp: "",
|
||||
want: time.Time{},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid format",
|
||||
timestamp: "seconds:%d nanos:%d",
|
||||
want: time.Time{},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "missing nanos",
|
||||
timestamp: "seconds:10",
|
||||
want: time.Time{},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "missing seconds",
|
||||
timestamp: "nanos:0",
|
||||
want: time.Time{},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got, err := timestampFromString(tt.timestamp)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("timestampFromString() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("timestampFromString() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1558,6 +1558,19 @@ func (rv *rbdVolume) setImageOptions(ctx context.Context, options *librbd.ImageO
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetImageCreationTime returns the creation time of the image. if the image
|
||||
// creation time is not set, it queries the image info and returns the creation time.
|
||||
func (ri *rbdImage) GetImageCreationTime() (*timestamppb.Timestamp, error) {
|
||||
if ri.CreatedAt != nil {
|
||||
return ri.CreatedAt, nil
|
||||
}
|
||||
if err := ri.getImageInfo(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ri.CreatedAt, nil
|
||||
}
|
||||
|
||||
// getImageInfo queries rbd about the given image and returns its metadata, and returns
|
||||
// ErrImageNotFound if provided image is not found.
|
||||
func (ri *rbdImage) getImageInfo() error {
|
||||
|
@ -19,31 +19,19 @@ package rbd
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
librbd "github.com/ceph/go-ceph/rbd"
|
||||
)
|
||||
|
||||
func (rv *rbdVolume) ResyncVol(localStatus librbd.SiteMirrorImageStatus, force bool) error {
|
||||
if resyncRequired(localStatus) {
|
||||
// If the force option is not set return the error message to retry
|
||||
// with Force option.
|
||||
if !force {
|
||||
return fmt.Errorf("%w: image is in %q state, description (%s). Force resync to recover volume",
|
||||
ErrFailedPrecondition, localStatus.State, localStatus.Description)
|
||||
}
|
||||
err := rv.resyncImage()
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: failed to resync image: %w", ErrResyncImageFailed, err)
|
||||
}
|
||||
|
||||
// If we issued a resync, return a non-final error as image needs to be recreated
|
||||
// locally. Caller retries till RBD syncs an initial version of the image to
|
||||
// report its status in the resync request.
|
||||
return fmt.Errorf("%w: awaiting initial resync due to split brain", ErrUnavailable)
|
||||
func (rv *rbdVolume) ResyncVol(localStatus librbd.SiteMirrorImageStatus) error {
|
||||
if err := rv.resyncImage(); err != nil {
|
||||
return fmt.Errorf("%w: failed to resync image: %w", ErrResyncImageFailed, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
// If we issued a resync, return a non-final error as image needs to be recreated
|
||||
// locally. Caller retries till RBD syncs an initial version of the image to
|
||||
// report its status in the resync request.
|
||||
return fmt.Errorf("%w: awaiting initial resync due to split brain", ErrUnavailable)
|
||||
}
|
||||
|
||||
// repairResyncedImageID updates the existing image ID with new one.
|
||||
@ -66,22 +54,6 @@ func (rv *rbdVolume) RepairResyncedImageID(ctx context.Context, ready bool) erro
|
||||
return rv.repairImageID(ctx, j, true)
|
||||
}
|
||||
|
||||
// resyncRequired returns true if local image is in split-brain state and image
|
||||
// needs resync.
|
||||
func resyncRequired(localStatus librbd.SiteMirrorImageStatus) bool {
|
||||
// resync is required if the image is in error state or the description
|
||||
// contains split-brain message.
|
||||
// In some corner cases like `re-player shutdown` the local image will not
|
||||
// be in an error state. It would be also worth considering the `description`
|
||||
// field to make sure about split-brain.
|
||||
if localStatus.State == librbd.MirrorImageStatusStateError ||
|
||||
strings.Contains(localStatus.Description, "split-brain") {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (rv *rbdVolume) DisableVolumeReplication(
|
||||
mirroringInfo *librbd.MirrorImageInfo,
|
||||
force bool,
|
||||
|
@ -268,7 +268,11 @@ up)
|
||||
fi
|
||||
# shellcheck disable=SC2086
|
||||
${minikube} start --force --memory="${MEMORY}" --cpus="${CPUS}" -b kubeadm --kubernetes-version="${KUBE_VERSION}" --driver="${VM_DRIVER}" --feature-gates="${K8S_FEATURE_GATES}" --cni="${CNI}" ${EXTRA_CONFIG} --wait-timeout="${MINIKUBE_WAIT_TIMEOUT}" --wait="${MINIKUBE_WAIT}" --delete-on-failure ${DISK_CONFIG}
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
${minikube} ssh "sudo sed -i 's/\(ExecStart=\/var.*\)/\1 --v=4/' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf"
|
||||
${minikube} ssh "sudo systemctl daemon-reload"
|
||||
${minikube} ssh "sudo systemctl restart kubelet"
|
||||
${minikube} ssh "ps -Af |grep kubelet"
|
||||
# create a link so the default dataDirHostPath will work for this
|
||||
# environment
|
||||
if [[ "${VM_DRIVER}" != "none" ]] && [[ "${VM_DRIVER}" != "podman" ]]; then
|
||||
|
2
vendor/github.com/IBM/keyprotect-go-client/README.md
generated
vendored
2
vendor/github.com/IBM/keyprotect-go-client/README.md
generated
vendored
@ -1,4 +1,4 @@
|
||||
# IBM Cloud Go SDK Version 0.9.2
|
||||
# IBM Cloud Go SDK
|
||||
|
||||
# keyprotect-go-client
|
||||
|
||||
|
19
vendor/github.com/IBM/keyprotect-go-client/key_rings.go
generated
vendored
19
vendor/github.com/IBM/keyprotect-go-client/key_rings.go
generated
vendored
@ -3,6 +3,8 @@ package kp
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -18,7 +20,7 @@ type KeyRing struct {
|
||||
|
||||
type KeyRings struct {
|
||||
Metadata KeysMetadata `json:"metadata"`
|
||||
KeyRings []KeyRing `json:"resources"`
|
||||
KeyRings []KeyRing `json:"resources"`
|
||||
}
|
||||
|
||||
// CreateRing method creates a key ring in the instance with the provided name
|
||||
@ -57,11 +59,24 @@ func (c *Client) GetKeyRings(ctx context.Context) (*KeyRings, error) {
|
||||
return &rings, nil
|
||||
}
|
||||
|
||||
type DeleteKeyRingQueryOption func(*http.Request)
|
||||
|
||||
func WithForce(force bool) DeleteKeyRingQueryOption {
|
||||
return func(req *http.Request) {
|
||||
query := req.URL.Query()
|
||||
query.Add("force", strconv.FormatBool(force))
|
||||
req.URL.RawQuery = query.Encode()
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteRing method deletes the key ring with the provided name in the instance
|
||||
// For information please refer to the link below:
|
||||
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-managing-key-rings#delete-key-ring-api
|
||||
func (c *Client) DeleteKeyRing(ctx context.Context, id string) error {
|
||||
func (c *Client) DeleteKeyRing(ctx context.Context, id string, opts ...DeleteKeyRingQueryOption) error {
|
||||
req, err := c.newRequest("DELETE", fmt.Sprintf(path+"/%s", id), nil)
|
||||
for _, opt := range opts {
|
||||
opt(req)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
246
vendor/github.com/IBM/keyprotect-go-client/keys.go
generated
vendored
246
vendor/github.com/IBM/keyprotect-go-client/keys.go
generated
vendored
@ -133,22 +133,118 @@ type KeyVersion struct {
|
||||
CreationDate *time.Time `json:"creationDate,omitempty"`
|
||||
}
|
||||
|
||||
// This function returns a string so we can pass extra info not in the key struct if needed
|
||||
type CreateKeyOption func(k *Key)
|
||||
|
||||
func WithExpiration(expiration *time.Time) CreateKeyOption {
|
||||
return func(key *Key) {
|
||||
key.Expiration = expiration
|
||||
}
|
||||
}
|
||||
|
||||
func WithDescription(description string) CreateKeyOption {
|
||||
return func(key *Key) {
|
||||
key.Description = description
|
||||
}
|
||||
}
|
||||
|
||||
func WithPayload(payload string, encryptedNonce, iv *string, sha1 bool) CreateKeyOption {
|
||||
return func(key *Key) {
|
||||
key.Payload = payload
|
||||
if !key.Extractable {
|
||||
hasNonce := encryptedNonce != nil && *encryptedNonce != ""
|
||||
hasIV := iv != nil && *iv != ""
|
||||
if hasNonce {
|
||||
key.EncryptedNonce = *encryptedNonce
|
||||
}
|
||||
if hasIV {
|
||||
key.IV = *iv
|
||||
}
|
||||
// Encryption algo field is only for secure import.
|
||||
// Only included it if either nonce or IV are specified.
|
||||
// API will error if only one of IV or nonce are specified but the other is empty.
|
||||
if hasNonce || hasIV {
|
||||
algorithm := AlgorithmRSAOAEP256
|
||||
if sha1 {
|
||||
algorithm = AlgorithmRSAOAEP1
|
||||
}
|
||||
key.EncryptionAlgorithm = algorithm
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func WithAliases(aliases []string) CreateKeyOption {
|
||||
return func(key *Key) {
|
||||
key.Aliases = aliases
|
||||
}
|
||||
}
|
||||
|
||||
func WithTags(tags []string) CreateKeyOption {
|
||||
return func(key *Key) {
|
||||
key.Tags = tags
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) CreateKeyWithOptions(ctx context.Context, name string, extractable bool, options ...CreateKeyOption) (*Key, error) {
|
||||
key := &Key{
|
||||
Name: name,
|
||||
Type: keyType,
|
||||
Extractable: extractable,
|
||||
}
|
||||
for _, opt := range options {
|
||||
opt(key)
|
||||
}
|
||||
return c.createKeyResource(ctx, *key, keysPath)
|
||||
}
|
||||
|
||||
func (c *Client) CreateKeyWithPolicyOverridesWithOptions(ctx context.Context, name string, extractable bool, policy Policy, options ...CreateKeyOption) (*Key, error) {
|
||||
key := &Key{
|
||||
Name: name,
|
||||
Type: keyType,
|
||||
Extractable: extractable,
|
||||
}
|
||||
for _, opt := range options {
|
||||
opt(key)
|
||||
}
|
||||
/*
|
||||
Setting the value of rotationInterval to -1 in case user passes 0 value
|
||||
as we want to retain the param `interval_month` after marshalling
|
||||
so that we can get correct error msg from REST API saying interval_month should be between 1 to 12
|
||||
Otherwise the param would not be sent to REST API in case of value 0
|
||||
and it would throw error saying interval_month is missing
|
||||
*/
|
||||
if policy.Rotation != nil && policy.Rotation.Interval == 0 {
|
||||
policy.Rotation.Interval = -1
|
||||
}
|
||||
key.Rotation = policy.Rotation
|
||||
key.DualAuthDelete = policy.DualAuth
|
||||
|
||||
return c.createKeyResource(ctx, *key, keysWithPolicyOverridesPath)
|
||||
}
|
||||
|
||||
// CreateKey creates a new KP key.
|
||||
func (c *Client) CreateKey(ctx context.Context, name string, expiration *time.Time, extractable bool) (*Key, error) {
|
||||
return c.CreateImportedKey(ctx, name, expiration, "", "", "", extractable)
|
||||
return c.CreateKeyWithOptions(ctx, name, extractable, WithExpiration(expiration))
|
||||
}
|
||||
|
||||
// CreateImportedKey creates a new KP key from the given key material.
|
||||
func (c *Client) CreateImportedKey(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string, extractable bool) (*Key, error) {
|
||||
key := c.createKeyTemplate(ctx, name, expiration, payload, encryptedNonce, iv, extractable, nil, AlgorithmRSAOAEP256, nil)
|
||||
return c.createKey(ctx, key)
|
||||
return c.CreateKeyWithOptions(ctx, name, extractable,
|
||||
WithExpiration(expiration),
|
||||
WithPayload(payload, &encryptedNonce, &iv, false),
|
||||
)
|
||||
}
|
||||
|
||||
// CreateImportedKeyWithSHA1 creates a new KP key from the given key material
|
||||
// using RSAES OAEP SHA 1 as encryption algorithm.
|
||||
func (c *Client) CreateImportedKeyWithSHA1(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string, extractable bool, aliases []string) (*Key, error) {
|
||||
key := c.createKeyTemplate(ctx, name, expiration, payload, encryptedNonce, iv, extractable, aliases, AlgorithmRSAOAEP1, nil)
|
||||
return c.createKey(ctx, key)
|
||||
func (c *Client) CreateImportedKeyWithSHA1(ctx context.Context, name string, expiration *time.Time,
|
||||
payload, encryptedNonce, iv string, extractable bool, aliases []string) (*Key, error) {
|
||||
return c.CreateKeyWithOptions(ctx, name, extractable,
|
||||
WithExpiration(expiration),
|
||||
WithPayload(payload, &encryptedNonce, &iv, true),
|
||||
WithAliases(aliases),
|
||||
)
|
||||
}
|
||||
|
||||
// CreateRootKey creates a new, non-extractable key resource without
|
||||
@ -189,47 +285,64 @@ func (c *Client) CreateKeyWithAliases(ctx context.Context, name string, expirati
|
||||
// For more information please refer to the links below:
|
||||
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-import-root-keys#import-root-key-api
|
||||
// https://cloud.ibm.com/docs/key-protect?topic=key-protect-import-standard-keys#import-standard-key-gui
|
||||
func (c *Client) CreateImportedKeyWithAliases(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string, extractable bool, aliases []string) (*Key, error) {
|
||||
key := c.createKeyTemplate(ctx, name, expiration, payload, encryptedNonce, iv, extractable, aliases, AlgorithmRSAOAEP256, nil)
|
||||
return c.createKey(ctx, key)
|
||||
func (c *Client) CreateImportedKeyWithAliases(ctx context.Context, name string, expiration *time.Time,
|
||||
payload, encryptedNonce, iv string, extractable bool, aliases []string) (*Key, error) {
|
||||
return c.CreateKeyWithOptions(ctx, name, extractable,
|
||||
WithExpiration(expiration),
|
||||
WithPayload(payload, &encryptedNonce, &iv, false),
|
||||
WithAliases(aliases),
|
||||
)
|
||||
}
|
||||
|
||||
func (c *Client) createKeyTemplate(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string, extractable bool, aliases []string, encryptionAlgorithm string, policy *Policy) Key {
|
||||
key := Key{
|
||||
Name: name,
|
||||
Type: keyType,
|
||||
Extractable: extractable,
|
||||
Payload: payload,
|
||||
}
|
||||
|
||||
if aliases != nil {
|
||||
key.Aliases = aliases
|
||||
}
|
||||
|
||||
if !extractable && payload != "" && encryptedNonce != "" && iv != "" {
|
||||
key.EncryptedNonce = encryptedNonce
|
||||
key.IV = iv
|
||||
key.EncryptionAlgorithm = encryptionAlgorithm
|
||||
}
|
||||
|
||||
if expiration != nil {
|
||||
key.Expiration = expiration
|
||||
}
|
||||
|
||||
if policy != nil {
|
||||
key.Rotation = policy.Rotation
|
||||
key.DualAuthDelete = policy.DualAuth
|
||||
}
|
||||
|
||||
return key
|
||||
// CreateImportedKeyWithPolicyOverridesWithSHA1 creates a new KP key with policy overrides from the given key material
|
||||
// and key policy details using RSAES OAEP SHA 1 as encryption algorithm.
|
||||
func (c *Client) CreateImportedKeyWithPolicyOverridesWithSHA1(ctx context.Context, name string, expiration *time.Time,
|
||||
payload, encryptedNonce, iv string, extractable bool, aliases []string, policy Policy) (*Key, error) {
|
||||
return c.CreateKeyWithPolicyOverridesWithOptions(ctx, name, extractable, policy,
|
||||
WithExpiration(expiration),
|
||||
WithPayload(payload, &encryptedNonce, &iv, true),
|
||||
WithAliases(aliases),
|
||||
)
|
||||
}
|
||||
|
||||
func (c *Client) createKey(ctx context.Context, key Key) (*Key, error) {
|
||||
return c.createKeyResource(ctx, key, keysPath)
|
||||
// CreateKeyWithPolicyOverrides creates a new KP key with given key policy details
|
||||
func (c *Client) CreateKeyWithPolicyOverrides(ctx context.Context, name string, expiration *time.Time, extractable bool, aliases []string, policy Policy) (*Key, error) {
|
||||
return c.CreateKeyWithPolicyOverridesWithOptions(ctx, name, extractable, policy,
|
||||
WithExpiration(expiration),
|
||||
WithAliases(aliases),
|
||||
)
|
||||
}
|
||||
|
||||
func (c *Client) createKeyWithPolicyOverrides(ctx context.Context, key Key) (*Key, error) {
|
||||
return c.createKeyResource(ctx, key, keysWithPolicyOverridesPath)
|
||||
// CreateImportedKeyWithPolicyOverrides creates a new Imported KP key from the given key material and with given key policy details
|
||||
func (c *Client) CreateImportedKeyWithPolicyOverrides(ctx context.Context, name string, expiration *time.Time,
|
||||
payload, encryptedNonce, iv string, extractable bool, aliases []string, policy Policy) (*Key, error) {
|
||||
return c.CreateKeyWithPolicyOverridesWithOptions(ctx, name, extractable, policy,
|
||||
WithExpiration(expiration),
|
||||
WithPayload(payload, &encryptedNonce, &iv, false),
|
||||
WithAliases(aliases),
|
||||
)
|
||||
}
|
||||
|
||||
// CreateRootKeyWithPolicyOverrides creates a new, non-extractable key resource without key material and with given key policy details
|
||||
func (c *Client) CreateRootKeyWithPolicyOverrides(ctx context.Context, name string, expiration *time.Time, aliases []string, policy Policy) (*Key, error) {
|
||||
return c.CreateKeyWithPolicyOverrides(ctx, name, expiration, false, aliases, policy)
|
||||
}
|
||||
|
||||
// CreateStandardKeyWithPolicyOverrides creates a new, extractable key resource without key material and with given key policy details
|
||||
func (c *Client) CreateStandardKeyWithPolicyOverrides(ctx context.Context, name string, expiration *time.Time, aliases []string, policy Policy) (*Key, error) {
|
||||
return c.CreateKeyWithPolicyOverrides(ctx, name, expiration, true, aliases, policy)
|
||||
}
|
||||
|
||||
// CreateImportedRootKeyWithPolicyOverrides creates a new, non-extractable key resource with the given key material and with given key policy details
|
||||
func (c *Client) CreateImportedRootKeyWithPolicyOverrides(ctx context.Context, name string, expiration *time.Time,
|
||||
payload, encryptedNonce, iv string, aliases []string, policy Policy) (*Key, error) {
|
||||
return c.CreateImportedKeyWithPolicyOverrides(ctx, name, expiration, payload, encryptedNonce, iv, false, aliases, policy)
|
||||
}
|
||||
|
||||
// CreateImportedStandardKeyWithPolicyOverrides creates a new, extractable key resource with the given key material and with given key policy details
|
||||
func (c *Client) CreateImportedStandardKeyWithPolicyOverrides(ctx context.Context, name string, expiration *time.Time,
|
||||
payload string, aliases []string, policy Policy) (*Key, error) {
|
||||
return c.CreateImportedKeyWithPolicyOverrides(ctx, name, expiration, payload, "", "", true, aliases, policy)
|
||||
}
|
||||
|
||||
func (c *Client) createKeyResource(ctx context.Context, key Key, path string) (*Key, error) {
|
||||
@ -283,57 +396,6 @@ func (c *Client) SetKeyRing(ctx context.Context, idOrAlias, newKeyRingID string)
|
||||
return &response.Keys[0], nil
|
||||
}
|
||||
|
||||
// CreateImportedKeyWithPolicyOverridesWithSHA1 creates a new KP key with policy overrides from the given key material
|
||||
// and key policy details using RSAES OAEP SHA 1 as encryption algorithm.
|
||||
func (c *Client) CreateImportedKeyWithPolicyOverridesWithSHA1(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string, extractable bool, aliases []string, policy Policy) (*Key, error) {
|
||||
/*
|
||||
Setting the value of rotationInterval to -1 in case user passes 0 value as we want to retain the param `interval_month` after marshalling so that we can get correct error msg from REST API saying interval_month should be between 1 to 12 Otherwise the param would not be sent to REST API in case of value 0 and it would throw error saying interval_month is missing
|
||||
*/
|
||||
if policy.Rotation != nil && policy.Rotation.Interval == 0 {
|
||||
policy.Rotation.Interval = -1
|
||||
}
|
||||
key := c.createKeyTemplate(ctx, name, expiration, payload, encryptedNonce, iv, extractable, aliases, AlgorithmRSAOAEP1, &policy)
|
||||
return c.createKeyWithPolicyOverrides(ctx, key)
|
||||
}
|
||||
|
||||
// CreateKeyWithPolicyOverrides creates a new KP key with given key policy details
|
||||
func (c *Client) CreateKeyWithPolicyOverrides(ctx context.Context, name string, expiration *time.Time, extractable bool, aliases []string, policy Policy) (*Key, error) {
|
||||
return c.CreateImportedKeyWithPolicyOverrides(ctx, name, expiration, "", "", "", extractable, aliases, policy)
|
||||
}
|
||||
|
||||
// CreateImportedKeyWithPolicyOverrides creates a new Imported KP key from the given key material and with given key policy details
|
||||
func (c *Client) CreateImportedKeyWithPolicyOverrides(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string, extractable bool, aliases []string, policy Policy) (*Key, error) {
|
||||
/*
|
||||
Setting the value of rotationInterval to -1 in case user passes 0 value as we want to retain the param `interval_month` after marshalling so that we can get correct error msg from REST API saying interval_month should be between 1 to 12 Otherwise the param would not be sent to REST API in case of value 0 and it would throw error saying interval_month is missing
|
||||
*/
|
||||
if policy.Rotation != nil && policy.Rotation.Interval == 0 {
|
||||
policy.Rotation.Interval = -1
|
||||
}
|
||||
key := c.createKeyTemplate(ctx, name, expiration, payload, encryptedNonce, iv, extractable, aliases, AlgorithmRSAOAEP256, &policy)
|
||||
|
||||
return c.createKeyWithPolicyOverrides(ctx, key)
|
||||
}
|
||||
|
||||
// CreateRootKeyWithPolicyOverrides creates a new, non-extractable key resource without key material and with given key policy details
|
||||
func (c *Client) CreateRootKeyWithPolicyOverrides(ctx context.Context, name string, expiration *time.Time, aliases []string, policy Policy) (*Key, error) {
|
||||
return c.CreateKeyWithPolicyOverrides(ctx, name, expiration, false, aliases, policy)
|
||||
}
|
||||
|
||||
// CreateStandardKeyWithPolicyOverrides creates a new, extractable key resource without key material and with given key policy details
|
||||
func (c *Client) CreateStandardKeyWithPolicyOverrides(ctx context.Context, name string, expiration *time.Time, aliases []string, policy Policy) (*Key, error) {
|
||||
return c.CreateKeyWithPolicyOverrides(ctx, name, expiration, true, aliases, policy)
|
||||
}
|
||||
|
||||
// CreateImportedRootKeyWithPolicyOverrides creates a new, non-extractable key resource with the given key material and with given key policy details
|
||||
func (c *Client) CreateImportedRootKeyWithPolicyOverrides(ctx context.Context, name string, expiration *time.Time, payload, encryptedNonce, iv string, aliases []string, policy Policy) (*Key, error) {
|
||||
return c.CreateImportedKeyWithPolicyOverrides(ctx, name, expiration, payload, encryptedNonce, iv, false, aliases, policy)
|
||||
}
|
||||
|
||||
// CreateImportedStandardKeyWithPolicyOverrides creates a new, extractable key resource with the given key material and with given key policy details
|
||||
func (c *Client) CreateImportedStandardKeyWithPolicyOverrides(ctx context.Context, name string, expiration *time.Time, payload string, aliases []string, policy Policy) (*Key, error) {
|
||||
return c.CreateImportedKeyWithPolicyOverrides(ctx, name, expiration, payload, "", "", true, aliases, policy)
|
||||
}
|
||||
|
||||
// GetKeys retrieves a collection of keys that can be paged through.
|
||||
func (c *Client) GetKeys(ctx context.Context, limit int, offset int) (*Keys, error) {
|
||||
if limit == 0 {
|
||||
|
68
vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/antlrdoc.go
generated
vendored
Normal file
68
vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/antlrdoc.go
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
Package antlr implements the Go version of the ANTLR 4 runtime.
|
||||
|
||||
# The ANTLR Tool
|
||||
|
||||
ANTLR (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing,
|
||||
or translating structured text or binary files. It's widely used to build languages, tools, and frameworks.
|
||||
From a grammar, ANTLR generates a parser that can build parse trees and also generates a listener interface
|
||||
(or visitor) that makes it easy to respond to the recognition of phrases of interest.
|
||||
|
||||
# Code Generation
|
||||
|
||||
ANTLR supports the generation of code in a number of [target languages], and the generated code is supported by a
|
||||
runtime library, written specifically to support the generated code in the target language. This library is the
|
||||
runtime for the Go target.
|
||||
|
||||
To generate code for the go target, it is generally recommended to place the source grammar files in a package of
|
||||
their own, and use the `.sh` script method of generating code, using the go generate directive. In that same directory
|
||||
it is usual, though not required, to place the antlr tool that should be used to generate the code. That does mean
|
||||
that the antlr tool JAR file will be checked in to your source code control though, so you are free to use any other
|
||||
way of specifying the version of the ANTLR tool to use, such as aliasing in `.zshrc` or equivalent, or a profile in
|
||||
your IDE, or configuration in your CI system.
|
||||
|
||||
Here is a general template for an ANTLR based recognizer in Go:
|
||||
|
||||
.
|
||||
├── myproject
|
||||
├── parser
|
||||
│ ├── mygrammar.g4
|
||||
│ ├── antlr-4.12.0-complete.jar
|
||||
│ ├── error_listeners.go
|
||||
│ ├── generate.go
|
||||
│ ├── generate.sh
|
||||
├── go.mod
|
||||
├── go.sum
|
||||
├── main.go
|
||||
└── main_test.go
|
||||
|
||||
Make sure that the package statement in your grammar file(s) reflects the go package they exist in.
|
||||
The generate.go file then looks like this:
|
||||
|
||||
package parser
|
||||
|
||||
//go:generate ./generate.sh
|
||||
|
||||
And the generate.sh file will look similar to this:
|
||||
|
||||
#!/bin/sh
|
||||
|
||||
alias antlr4='java -Xmx500M -cp "./antlr4-4.12.0-complete.jar:$CLASSPATH" org.antlr.v4.Tool'
|
||||
antlr4 -Dlanguage=Go -no-visitor -package parser *.g4
|
||||
|
||||
depending on whether you want visitors or listeners or any other ANTLR options.
|
||||
|
||||
From the command line at the root of your package “myproject” you can then simply issue the command:
|
||||
|
||||
go generate ./...
|
||||
|
||||
# Copyright Notice
|
||||
|
||||
Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
|
||||
Use of this file is governed by the BSD 3-clause license, which can be found in the [LICENSE.txt] file in the project root.
|
||||
|
||||
[target languages]: https://github.com/antlr/antlr4/tree/master/runtime
|
||||
[LICENSE.txt]: https://github.com/antlr/antlr4/blob/master/LICENSE.txt
|
||||
*/
|
||||
package antlr
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -6,11 +6,24 @@ package antlr
|
||||
|
||||
import "sync"
|
||||
|
||||
// ATNInvalidAltNumber is used to represent an ALT number that has yet to be calculated or
|
||||
// which is invalid for a particular struct such as [*antlr.BaseRuleContext]
|
||||
var ATNInvalidAltNumber int
|
||||
|
||||
// ATN represents an “[Augmented Transition Network]”, though general in ANTLR the term
|
||||
// “Augmented Recursive Transition Network” though there are some descriptions of “[Recursive Transition Network]”
|
||||
// in existence.
|
||||
//
|
||||
// ATNs represent the main networks in the system and are serialized by the code generator and support [ALL(*)].
|
||||
//
|
||||
// [Augmented Transition Network]: https://en.wikipedia.org/wiki/Augmented_transition_network
|
||||
// [ALL(*)]: https://www.antlr.org/papers/allstar-techreport.pdf
|
||||
// [Recursive Transition Network]: https://en.wikipedia.org/wiki/Recursive_transition_network
|
||||
type ATN struct {
|
||||
// DecisionToState is the decision points for all rules, subrules, optional
|
||||
// blocks, ()+, ()*, etc. Used to build DFA predictors for them.
|
||||
// blocks, ()+, ()*, etc. Each subrule/rule is a decision point, and we must track them so we
|
||||
// can go back later and build DFA predictors for them. This includes
|
||||
// all the rules, subrules, optional blocks, ()+, ()* etc...
|
||||
DecisionToState []DecisionState
|
||||
|
||||
// grammarType is the ATN type and is used for deserializing ATNs from strings.
|
||||
@ -45,6 +58,8 @@ type ATN struct {
|
||||
edgeMu sync.RWMutex
|
||||
}
|
||||
|
||||
// NewATN returns a new ATN struct representing the given grammarType and is used
|
||||
// for runtime deserialization of ATNs from the code generated by the ANTLR tool
|
||||
func NewATN(grammarType int, maxTokenType int) *ATN {
|
||||
return &ATN{
|
||||
grammarType: grammarType,
|
||||
@ -53,7 +68,7 @@ func NewATN(grammarType int, maxTokenType int) *ATN {
|
||||
}
|
||||
}
|
||||
|
||||
// NextTokensInContext computes the set of valid tokens that can occur starting
|
||||
// NextTokensInContext computes and returns the set of valid tokens that can occur starting
|
||||
// in state s. If ctx is nil, the set of tokens will not include what can follow
|
||||
// the rule surrounding s. In other words, the set will be restricted to tokens
|
||||
// reachable staying within the rule of s.
|
||||
@ -61,8 +76,8 @@ func (a *ATN) NextTokensInContext(s ATNState, ctx RuleContext) *IntervalSet {
|
||||
return NewLL1Analyzer(a).Look(s, nil, ctx)
|
||||
}
|
||||
|
||||
// NextTokensNoContext computes the set of valid tokens that can occur starting
|
||||
// in s and staying in same rule. Token.EPSILON is in set if we reach end of
|
||||
// NextTokensNoContext computes and returns the set of valid tokens that can occur starting
|
||||
// in state s and staying in same rule. [antlr.Token.EPSILON] is in set if we reach end of
|
||||
// rule.
|
||||
func (a *ATN) NextTokensNoContext(s ATNState) *IntervalSet {
|
||||
a.mu.Lock()
|
||||
@ -76,6 +91,8 @@ func (a *ATN) NextTokensNoContext(s ATNState) *IntervalSet {
|
||||
return iset
|
||||
}
|
||||
|
||||
// NextTokens computes and returns the set of valid tokens starting in state s, by
|
||||
// calling either [NextTokensNoContext] (ctx == nil) or [NextTokensInContext] (ctx != nil).
|
||||
func (a *ATN) NextTokens(s ATNState, ctx RuleContext) *IntervalSet {
|
||||
if ctx == nil {
|
||||
return a.NextTokensNoContext(s)
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -8,19 +8,14 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type comparable interface {
|
||||
equals(other interface{}) bool
|
||||
}
|
||||
|
||||
// ATNConfig is a tuple: (ATN state, predicted alt, syntactic, semantic
|
||||
// context). The syntactic context is a graph-structured stack node whose
|
||||
// path(s) to the root is the rule invocation(s) chain used to arrive at the
|
||||
// state. The semantic context is the tree of semantic predicates encountered
|
||||
// before reaching an ATN state.
|
||||
type ATNConfig interface {
|
||||
comparable
|
||||
|
||||
hash() int
|
||||
Equals(o Collectable[ATNConfig]) bool
|
||||
Hash() int
|
||||
|
||||
GetState() ATNState
|
||||
GetAlt() int
|
||||
@ -47,7 +42,7 @@ type BaseATNConfig struct {
|
||||
reachesIntoOuterContext int
|
||||
}
|
||||
|
||||
func NewBaseATNConfig7(old *BaseATNConfig) *BaseATNConfig { // TODO: Dup
|
||||
func NewBaseATNConfig7(old *BaseATNConfig) ATNConfig { // TODO: Dup
|
||||
return &BaseATNConfig{
|
||||
state: old.state,
|
||||
alt: old.alt,
|
||||
@ -135,11 +130,16 @@ func (b *BaseATNConfig) SetReachesIntoOuterContext(v int) {
|
||||
b.reachesIntoOuterContext = v
|
||||
}
|
||||
|
||||
// Equals is the default comparison function for an ATNConfig when no specialist implementation is required
|
||||
// for a collection.
|
||||
//
|
||||
// An ATN configuration is equal to another if both have the same state, they
|
||||
// predict the same alternative, and syntactic/semantic contexts are the same.
|
||||
func (b *BaseATNConfig) equals(o interface{}) bool {
|
||||
func (b *BaseATNConfig) Equals(o Collectable[ATNConfig]) bool {
|
||||
if b == o {
|
||||
return true
|
||||
} else if o == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
var other, ok = o.(*BaseATNConfig)
|
||||
@ -153,30 +153,32 @@ func (b *BaseATNConfig) equals(o interface{}) bool {
|
||||
if b.context == nil {
|
||||
equal = other.context == nil
|
||||
} else {
|
||||
equal = b.context.equals(other.context)
|
||||
equal = b.context.Equals(other.context)
|
||||
}
|
||||
|
||||
var (
|
||||
nums = b.state.GetStateNumber() == other.state.GetStateNumber()
|
||||
alts = b.alt == other.alt
|
||||
cons = b.semanticContext.equals(other.semanticContext)
|
||||
cons = b.semanticContext.Equals(other.semanticContext)
|
||||
sups = b.precedenceFilterSuppressed == other.precedenceFilterSuppressed
|
||||
)
|
||||
|
||||
return nums && alts && cons && sups && equal
|
||||
}
|
||||
|
||||
func (b *BaseATNConfig) hash() int {
|
||||
// Hash is the default hash function for BaseATNConfig, when no specialist hash function
|
||||
// is required for a collection
|
||||
func (b *BaseATNConfig) Hash() int {
|
||||
var c int
|
||||
if b.context != nil {
|
||||
c = b.context.hash()
|
||||
c = b.context.Hash()
|
||||
}
|
||||
|
||||
h := murmurInit(7)
|
||||
h = murmurUpdate(h, b.state.GetStateNumber())
|
||||
h = murmurUpdate(h, b.alt)
|
||||
h = murmurUpdate(h, c)
|
||||
h = murmurUpdate(h, b.semanticContext.hash())
|
||||
h = murmurUpdate(h, b.semanticContext.Hash())
|
||||
return murmurFinish(h, 4)
|
||||
}
|
||||
|
||||
@ -243,7 +245,9 @@ func NewLexerATNConfig1(state ATNState, alt int, context PredictionContext) *Lex
|
||||
return &LexerATNConfig{BaseATNConfig: NewBaseATNConfig5(state, alt, context, SemanticContextNone)}
|
||||
}
|
||||
|
||||
func (l *LexerATNConfig) hash() int {
|
||||
// Hash is the default hash function for LexerATNConfig objects, it can be used directly or via
|
||||
// the default comparator [ObjEqComparator].
|
||||
func (l *LexerATNConfig) Hash() int {
|
||||
var f int
|
||||
if l.passedThroughNonGreedyDecision {
|
||||
f = 1
|
||||
@ -253,15 +257,20 @@ func (l *LexerATNConfig) hash() int {
|
||||
h := murmurInit(7)
|
||||
h = murmurUpdate(h, l.state.GetStateNumber())
|
||||
h = murmurUpdate(h, l.alt)
|
||||
h = murmurUpdate(h, l.context.hash())
|
||||
h = murmurUpdate(h, l.semanticContext.hash())
|
||||
h = murmurUpdate(h, l.context.Hash())
|
||||
h = murmurUpdate(h, l.semanticContext.Hash())
|
||||
h = murmurUpdate(h, f)
|
||||
h = murmurUpdate(h, l.lexerActionExecutor.hash())
|
||||
h = murmurUpdate(h, l.lexerActionExecutor.Hash())
|
||||
h = murmurFinish(h, 6)
|
||||
return h
|
||||
}
|
||||
|
||||
func (l *LexerATNConfig) equals(other interface{}) bool {
|
||||
// Equals is the default comparison function for LexerATNConfig objects, it can be used directly or via
|
||||
// the default comparator [ObjEqComparator].
|
||||
func (l *LexerATNConfig) Equals(other Collectable[ATNConfig]) bool {
|
||||
if l == other {
|
||||
return true
|
||||
}
|
||||
var othert, ok = other.(*LexerATNConfig)
|
||||
|
||||
if l == other {
|
||||
@ -275,7 +284,7 @@ func (l *LexerATNConfig) equals(other interface{}) bool {
|
||||
var b bool
|
||||
|
||||
if l.lexerActionExecutor != nil {
|
||||
b = !l.lexerActionExecutor.equals(othert.lexerActionExecutor)
|
||||
b = !l.lexerActionExecutor.Equals(othert.lexerActionExecutor)
|
||||
} else {
|
||||
b = othert.lexerActionExecutor != nil
|
||||
}
|
||||
@ -284,10 +293,9 @@ func (l *LexerATNConfig) equals(other interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
return l.BaseATNConfig.equals(othert.BaseATNConfig)
|
||||
return l.BaseATNConfig.Equals(othert.BaseATNConfig)
|
||||
}
|
||||
|
||||
|
||||
func checkNonGreedyDecision(source *LexerATNConfig, target ATNState) bool {
|
||||
var ds, ok = target.(DecisionState)
|
||||
|
@ -1,24 +1,25 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
package antlr
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ATNConfigSet interface {
|
||||
hash() int
|
||||
Hash() int
|
||||
Equals(o Collectable[ATNConfig]) bool
|
||||
Add(ATNConfig, *DoubleDict) bool
|
||||
AddAll([]ATNConfig) bool
|
||||
|
||||
GetStates() Set
|
||||
GetStates() *JStore[ATNState, Comparator[ATNState]]
|
||||
GetPredicates() []SemanticContext
|
||||
GetItems() []ATNConfig
|
||||
|
||||
OptimizeConfigs(interpreter *BaseATNSimulator)
|
||||
|
||||
Equals(other interface{}) bool
|
||||
|
||||
Length() int
|
||||
IsEmpty() bool
|
||||
Contains(ATNConfig) bool
|
||||
@ -57,7 +58,7 @@ type BaseATNConfigSet struct {
|
||||
// effectively doubles the number of objects associated with ATNConfigs. All
|
||||
// keys are hashed by (s, i, _, pi), not including the context. Wiped out when
|
||||
// read-only because a set becomes a DFA state.
|
||||
configLookup Set
|
||||
configLookup *JStore[ATNConfig, Comparator[ATNConfig]]
|
||||
|
||||
// configs is the added elements.
|
||||
configs []ATNConfig
|
||||
@ -83,7 +84,7 @@ type BaseATNConfigSet struct {
|
||||
|
||||
// readOnly is whether it is read-only. Do not
|
||||
// allow any code to manipulate the set if true because DFA states will point at
|
||||
// sets and those must not change. It not protect other fields; conflictingAlts
|
||||
// sets and those must not change. It not, protect other fields; conflictingAlts
|
||||
// in particular, which is assigned after readOnly.
|
||||
readOnly bool
|
||||
|
||||
@ -104,7 +105,7 @@ func (b *BaseATNConfigSet) Alts() *BitSet {
|
||||
func NewBaseATNConfigSet(fullCtx bool) *BaseATNConfigSet {
|
||||
return &BaseATNConfigSet{
|
||||
cachedHash: -1,
|
||||
configLookup: newArray2DHashSetWithCap(hashATNConfig, equalATNConfigs, 16, 2),
|
||||
configLookup: NewJStore[ATNConfig, Comparator[ATNConfig]](aConfCompInst),
|
||||
fullCtx: fullCtx,
|
||||
}
|
||||
}
|
||||
@ -126,9 +127,11 @@ func (b *BaseATNConfigSet) Add(config ATNConfig, mergeCache *DoubleDict) bool {
|
||||
b.dipsIntoOuterContext = true
|
||||
}
|
||||
|
||||
existing := b.configLookup.Add(config).(ATNConfig)
|
||||
existing, present := b.configLookup.Put(config)
|
||||
|
||||
if existing == config {
|
||||
// The config was not already in the set
|
||||
//
|
||||
if !present {
|
||||
b.cachedHash = -1
|
||||
b.configs = append(b.configs, config) // Track order here
|
||||
return true
|
||||
@ -154,11 +157,14 @@ func (b *BaseATNConfigSet) Add(config ATNConfig, mergeCache *DoubleDict) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (b *BaseATNConfigSet) GetStates() Set {
|
||||
states := newArray2DHashSet(nil, nil)
|
||||
func (b *BaseATNConfigSet) GetStates() *JStore[ATNState, Comparator[ATNState]] {
|
||||
|
||||
// states uses the standard comparator provided by the ATNState instance
|
||||
//
|
||||
states := NewJStore[ATNState, Comparator[ATNState]](aStateEqInst)
|
||||
|
||||
for i := 0; i < len(b.configs); i++ {
|
||||
states.Add(b.configs[i].GetState())
|
||||
states.Put(b.configs[i].GetState())
|
||||
}
|
||||
|
||||
return states
|
||||
@ -214,7 +220,34 @@ func (b *BaseATNConfigSet) AddAll(coll []ATNConfig) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *BaseATNConfigSet) Equals(other interface{}) bool {
|
||||
// Compare is a hack function just to verify that adding DFAstares to the known
|
||||
// set works, so long as comparison of ATNConfigSet s works. For that to work, we
|
||||
// need to make sure that the set of ATNConfigs in two sets are equivalent. We can't
|
||||
// know the order, so we do this inefficient hack. If this proves the point, then
|
||||
// we can change the config set to a better structure.
|
||||
func (b *BaseATNConfigSet) Compare(bs *BaseATNConfigSet) bool {
|
||||
if len(b.configs) != len(bs.configs) {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, c := range b.configs {
|
||||
found := false
|
||||
for _, c2 := range bs.configs {
|
||||
if c.Equals(c2) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (b *BaseATNConfigSet) Equals(other Collectable[ATNConfig]) bool {
|
||||
if b == other {
|
||||
return true
|
||||
} else if _, ok := other.(*BaseATNConfigSet); !ok {
|
||||
@ -224,15 +257,15 @@ func (b *BaseATNConfigSet) Equals(other interface{}) bool {
|
||||
other2 := other.(*BaseATNConfigSet)
|
||||
|
||||
return b.configs != nil &&
|
||||
// TODO: b.configs.equals(other2.configs) && // TODO: Is b necessary?
|
||||
b.fullCtx == other2.fullCtx &&
|
||||
b.uniqueAlt == other2.uniqueAlt &&
|
||||
b.conflictingAlts == other2.conflictingAlts &&
|
||||
b.hasSemanticContext == other2.hasSemanticContext &&
|
||||
b.dipsIntoOuterContext == other2.dipsIntoOuterContext
|
||||
b.dipsIntoOuterContext == other2.dipsIntoOuterContext &&
|
||||
b.Compare(other2)
|
||||
}
|
||||
|
||||
func (b *BaseATNConfigSet) hash() int {
|
||||
func (b *BaseATNConfigSet) Hash() int {
|
||||
if b.readOnly {
|
||||
if b.cachedHash == -1 {
|
||||
b.cachedHash = b.hashCodeConfigs()
|
||||
@ -247,7 +280,7 @@ func (b *BaseATNConfigSet) hash() int {
|
||||
func (b *BaseATNConfigSet) hashCodeConfigs() int {
|
||||
h := 1
|
||||
for _, config := range b.configs {
|
||||
h = 31*h + config.hash()
|
||||
h = 31*h + config.Hash()
|
||||
}
|
||||
return h
|
||||
}
|
||||
@ -283,7 +316,7 @@ func (b *BaseATNConfigSet) Clear() {
|
||||
|
||||
b.configs = make([]ATNConfig, 0)
|
||||
b.cachedHash = -1
|
||||
b.configLookup = newArray2DHashSet(nil, equalATNConfigs)
|
||||
b.configLookup = NewJStore[ATNConfig, Comparator[ATNConfig]](atnConfCompInst)
|
||||
}
|
||||
|
||||
func (b *BaseATNConfigSet) FullContext() bool {
|
||||
@ -365,7 +398,8 @@ type OrderedATNConfigSet struct {
|
||||
func NewOrderedATNConfigSet() *OrderedATNConfigSet {
|
||||
b := NewBaseATNConfigSet(false)
|
||||
|
||||
b.configLookup = newArray2DHashSet(nil, nil)
|
||||
// This set uses the standard Hash() and Equals() from ATNConfig
|
||||
b.configLookup = NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst)
|
||||
|
||||
return &OrderedATNConfigSet{BaseATNConfigSet: b}
|
||||
}
|
||||
@ -375,7 +409,7 @@ func hashATNConfig(i interface{}) int {
|
||||
hash := 7
|
||||
hash = 31*hash + o.GetState().GetStateNumber()
|
||||
hash = 31*hash + o.GetAlt()
|
||||
hash = 31*hash + o.GetSemanticContext().hash()
|
||||
hash = 31*hash + o.GetSemanticContext().Hash()
|
||||
return hash
|
||||
}
|
||||
|
||||
@ -403,5 +437,5 @@ func equalATNConfigs(a, b interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
return ai.GetSemanticContext().equals(bi.GetSemanticContext())
|
||||
return ai.GetSemanticContext().Equals(bi.GetSemanticContext())
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -49,7 +49,8 @@ type ATNState interface {
|
||||
AddTransition(Transition, int)
|
||||
|
||||
String() string
|
||||
hash() int
|
||||
Hash() int
|
||||
Equals(Collectable[ATNState]) bool
|
||||
}
|
||||
|
||||
type BaseATNState struct {
|
||||
@ -123,7 +124,7 @@ func (as *BaseATNState) SetNextTokenWithinRule(v *IntervalSet) {
|
||||
as.NextTokenWithinRule = v
|
||||
}
|
||||
|
||||
func (as *BaseATNState) hash() int {
|
||||
func (as *BaseATNState) Hash() int {
|
||||
return as.stateNumber
|
||||
}
|
||||
|
||||
@ -131,7 +132,7 @@ func (as *BaseATNState) String() string {
|
||||
return strconv.Itoa(as.stateNumber)
|
||||
}
|
||||
|
||||
func (as *BaseATNState) equals(other interface{}) bool {
|
||||
func (as *BaseATNState) Equals(other Collectable[ATNState]) bool {
|
||||
if ot, ok := other.(ATNState); ok {
|
||||
return as.stateNumber == ot.GetStateNumber()
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -331,10 +331,12 @@ func (c *CommonTokenStream) GetTextFromRuleContext(interval RuleContext) string
|
||||
|
||||
func (c *CommonTokenStream) GetTextFromInterval(interval *Interval) string {
|
||||
c.lazyInit()
|
||||
c.Fill()
|
||||
|
||||
if interval == nil {
|
||||
c.Fill()
|
||||
interval = NewInterval(0, len(c.tokens)-1)
|
||||
} else {
|
||||
c.Sync(interval.Stop)
|
||||
}
|
||||
|
||||
start := interval.Start
|
147
vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/comparators.go
generated
vendored
Normal file
147
vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/comparators.go
generated
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
package antlr
|
||||
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
// This file contains all the implementations of custom comparators used for generic collections when the
|
||||
// Hash() and Equals() funcs supplied by the struct objects themselves need to be overridden. Normally, we would
|
||||
// put the comparators in the source file for the struct themselves, but given the organization of this code is
|
||||
// sorta kinda based upon the Java code, I found it confusing trying to find out which comparator was where and used by
|
||||
// which instantiation of a collection. For instance, an Array2DHashSet in the Java source, when used with ATNConfig
|
||||
// collections requires three different comparators depending on what the collection is being used for. Collecting - pun intended -
|
||||
// all the comparators here, makes it much easier to see which implementation of hash and equals is used by which collection.
|
||||
// It also makes it easy to verify that the Hash() and Equals() functions marry up with the Java implementations.
|
||||
|
||||
// ObjEqComparator is the equivalent of the Java ObjectEqualityComparator, which is the default instance of
|
||||
// Equality comparator. We do not have inheritance in Go, only interfaces, so we use generics to enforce some
|
||||
// type safety and avoid having to implement this for every type that we want to perform comparison on.
|
||||
//
|
||||
// This comparator works by using the standard Hash() and Equals() methods of the type T that is being compared. Which
|
||||
// allows us to use it in any collection instance that does nto require a special hash or equals implementation.
|
||||
type ObjEqComparator[T Collectable[T]] struct{}
|
||||
|
||||
var (
|
||||
aStateEqInst = &ObjEqComparator[ATNState]{}
|
||||
aConfEqInst = &ObjEqComparator[ATNConfig]{}
|
||||
aConfCompInst = &ATNConfigComparator[ATNConfig]{}
|
||||
atnConfCompInst = &BaseATNConfigComparator[ATNConfig]{}
|
||||
dfaStateEqInst = &ObjEqComparator[*DFAState]{}
|
||||
semctxEqInst = &ObjEqComparator[SemanticContext]{}
|
||||
atnAltCfgEqInst = &ATNAltConfigComparator[ATNConfig]{}
|
||||
)
|
||||
|
||||
// Equals2 delegates to the Equals() method of type T
|
||||
func (c *ObjEqComparator[T]) Equals2(o1, o2 T) bool {
|
||||
return o1.Equals(o2)
|
||||
}
|
||||
|
||||
// Hash1 delegates to the Hash() method of type T
|
||||
func (c *ObjEqComparator[T]) Hash1(o T) int {
|
||||
|
||||
return o.Hash()
|
||||
}
|
||||
|
||||
type SemCComparator[T Collectable[T]] struct{}
|
||||
|
||||
// ATNConfigComparator is used as the compartor for the configLookup field of an ATNConfigSet
|
||||
// and has a custom Equals() and Hash() implementation, because equality is not based on the
|
||||
// standard Hash() and Equals() methods of the ATNConfig type.
|
||||
type ATNConfigComparator[T Collectable[T]] struct {
|
||||
}
|
||||
|
||||
// Equals2 is a custom comparator for ATNConfigs specifically for configLookup
|
||||
func (c *ATNConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool {
|
||||
|
||||
// Same pointer, must be equal, even if both nil
|
||||
//
|
||||
if o1 == o2 {
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// If either are nil, but not both, then the result is false
|
||||
//
|
||||
if o1 == nil || o2 == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return o1.GetState().GetStateNumber() == o2.GetState().GetStateNumber() &&
|
||||
o1.GetAlt() == o2.GetAlt() &&
|
||||
o1.GetSemanticContext().Equals(o2.GetSemanticContext())
|
||||
}
|
||||
|
||||
// Hash1 is custom hash implementation for ATNConfigs specifically for configLookup
|
||||
func (c *ATNConfigComparator[T]) Hash1(o ATNConfig) int {
|
||||
hash := 7
|
||||
hash = 31*hash + o.GetState().GetStateNumber()
|
||||
hash = 31*hash + o.GetAlt()
|
||||
hash = 31*hash + o.GetSemanticContext().Hash()
|
||||
return hash
|
||||
}
|
||||
|
||||
// ATNAltConfigComparator is used as the comparator for mapping configs to Alt Bitsets
|
||||
type ATNAltConfigComparator[T Collectable[T]] struct {
|
||||
}
|
||||
|
||||
// Equals2 is a custom comparator for ATNConfigs specifically for configLookup
|
||||
func (c *ATNAltConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool {
|
||||
|
||||
// Same pointer, must be equal, even if both nil
|
||||
//
|
||||
if o1 == o2 {
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// If either are nil, but not both, then the result is false
|
||||
//
|
||||
if o1 == nil || o2 == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return o1.GetState().GetStateNumber() == o2.GetState().GetStateNumber() &&
|
||||
o1.GetContext().Equals(o2.GetContext())
|
||||
}
|
||||
|
||||
// Hash1 is custom hash implementation for ATNConfigs specifically for configLookup
|
||||
func (c *ATNAltConfigComparator[T]) Hash1(o ATNConfig) int {
|
||||
h := murmurInit(7)
|
||||
h = murmurUpdate(h, o.GetState().GetStateNumber())
|
||||
h = murmurUpdate(h, o.GetContext().Hash())
|
||||
return murmurFinish(h, 2)
|
||||
}
|
||||
|
||||
// BaseATNConfigComparator is used as the comparator for the configLookup field of a BaseATNConfigSet
|
||||
// and has a custom Equals() and Hash() implementation, because equality is not based on the
|
||||
// standard Hash() and Equals() methods of the ATNConfig type.
|
||||
type BaseATNConfigComparator[T Collectable[T]] struct {
|
||||
}
|
||||
|
||||
// Equals2 is a custom comparator for ATNConfigs specifically for baseATNConfigSet
|
||||
func (c *BaseATNConfigComparator[T]) Equals2(o1, o2 ATNConfig) bool {
|
||||
|
||||
// Same pointer, must be equal, even if both nil
|
||||
//
|
||||
if o1 == o2 {
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
// If either are nil, but not both, then the result is false
|
||||
//
|
||||
if o1 == nil || o2 == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return o1.GetState().GetStateNumber() == o2.GetState().GetStateNumber() &&
|
||||
o1.GetAlt() == o2.GetAlt() &&
|
||||
o1.GetSemanticContext().Equals(o2.GetSemanticContext())
|
||||
}
|
||||
|
||||
// Hash1 is custom hash implementation for ATNConfigs specifically for configLookup, but in fact just
|
||||
// delegates to the standard Hash() method of the ATNConfig type.
|
||||
func (c *BaseATNConfigComparator[T]) Hash1(o ATNConfig) int {
|
||||
|
||||
return o.Hash()
|
||||
}
|
@ -1,13 +1,9 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
package antlr
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
type DFA struct {
|
||||
// atnStartState is the ATN state in which this was created
|
||||
atnStartState DecisionState
|
||||
@ -15,8 +11,15 @@ type DFA struct {
|
||||
decision int
|
||||
|
||||
// states is all the DFA states. Use Map to get the old state back; Set can only
|
||||
// indicate whether it is there.
|
||||
states map[int]*DFAState
|
||||
// indicate whether it is there. Go maps implement key hash collisions and so on and are very
|
||||
// good, but the DFAState is an object and can't be used directly as the key as it can in say JAva
|
||||
// amd C#, whereby if the hashcode is the same for two objects, then Equals() is called against them
|
||||
// to see if they really are the same object.
|
||||
//
|
||||
//
|
||||
states *JStore[*DFAState, *ObjEqComparator[*DFAState]]
|
||||
|
||||
numstates int
|
||||
|
||||
s0 *DFAState
|
||||
|
||||
@ -29,7 +32,7 @@ func NewDFA(atnStartState DecisionState, decision int) *DFA {
|
||||
dfa := &DFA{
|
||||
atnStartState: atnStartState,
|
||||
decision: decision,
|
||||
states: make(map[int]*DFAState),
|
||||
states: NewJStore[*DFAState, *ObjEqComparator[*DFAState]](dfaStateEqInst),
|
||||
}
|
||||
if s, ok := atnStartState.(*StarLoopEntryState); ok && s.precedenceRuleDecision {
|
||||
dfa.precedenceDfa = true
|
||||
@ -92,7 +95,8 @@ func (d *DFA) getPrecedenceDfa() bool {
|
||||
// true or nil otherwise, and d.precedenceDfa is updated.
|
||||
func (d *DFA) setPrecedenceDfa(precedenceDfa bool) {
|
||||
if d.getPrecedenceDfa() != precedenceDfa {
|
||||
d.setStates(make(map[int]*DFAState))
|
||||
d.states = NewJStore[*DFAState, *ObjEqComparator[*DFAState]](dfaStateEqInst)
|
||||
d.numstates = 0
|
||||
|
||||
if precedenceDfa {
|
||||
precedenceState := NewDFAState(-1, NewBaseATNConfigSet(false))
|
||||
@ -117,38 +121,12 @@ func (d *DFA) setS0(s *DFAState) {
|
||||
d.s0 = s
|
||||
}
|
||||
|
||||
func (d *DFA) getState(hash int) (*DFAState, bool) {
|
||||
s, ok := d.states[hash]
|
||||
return s, ok
|
||||
}
|
||||
|
||||
func (d *DFA) setStates(states map[int]*DFAState) {
|
||||
d.states = states
|
||||
}
|
||||
|
||||
func (d *DFA) setState(hash int, state *DFAState) {
|
||||
d.states[hash] = state
|
||||
}
|
||||
|
||||
func (d *DFA) numStates() int {
|
||||
return len(d.states)
|
||||
}
|
||||
|
||||
type dfaStateList []*DFAState
|
||||
|
||||
func (d dfaStateList) Len() int { return len(d) }
|
||||
func (d dfaStateList) Less(i, j int) bool { return d[i].stateNumber < d[j].stateNumber }
|
||||
func (d dfaStateList) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
|
||||
|
||||
// sortedStates returns the states in d sorted by their state number.
|
||||
func (d *DFA) sortedStates() []*DFAState {
|
||||
vs := make([]*DFAState, 0, len(d.states))
|
||||
|
||||
for _, v := range d.states {
|
||||
vs = append(vs, v)
|
||||
}
|
||||
|
||||
sort.Sort(dfaStateList(vs))
|
||||
vs := d.states.SortedSlice(func(i, j *DFAState) bool {
|
||||
return i.stateNumber < j.stateNumber
|
||||
})
|
||||
|
||||
return vs
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -90,16 +90,16 @@ func NewDFAState(stateNumber int, configs ATNConfigSet) *DFAState {
|
||||
}
|
||||
|
||||
// GetAltSet gets the set of all alts mentioned by all ATN configurations in d.
|
||||
func (d *DFAState) GetAltSet() Set {
|
||||
alts := newArray2DHashSet(nil, nil)
|
||||
func (d *DFAState) GetAltSet() []int {
|
||||
var alts []int
|
||||
|
||||
if d.configs != nil {
|
||||
for _, c := range d.configs.GetItems() {
|
||||
alts.Add(c.GetAlt())
|
||||
alts = append(alts, c.GetAlt())
|
||||
}
|
||||
}
|
||||
|
||||
if alts.Len() == 0 {
|
||||
if len(alts) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -130,27 +130,6 @@ func (d *DFAState) setPrediction(v int) {
|
||||
d.prediction = v
|
||||
}
|
||||
|
||||
// equals returns whether d equals other. Two DFAStates are equal if their ATN
|
||||
// configuration sets are the same. This method is used to see if a state
|
||||
// already exists.
|
||||
//
|
||||
// Because the number of alternatives and number of ATN configurations are
|
||||
// finite, there is a finite number of DFA states that can be processed. This is
|
||||
// necessary to show that the algorithm terminates.
|
||||
//
|
||||
// Cannot test the DFA state numbers here because in
|
||||
// ParserATNSimulator.addDFAState we need to know if any other state exists that
|
||||
// has d exact set of ATN configurations. The stateNumber is irrelevant.
|
||||
func (d *DFAState) equals(other interface{}) bool {
|
||||
if d == other {
|
||||
return true
|
||||
} else if _, ok := other.(*DFAState); !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return d.configs.Equals(other.(*DFAState).configs)
|
||||
}
|
||||
|
||||
func (d *DFAState) String() string {
|
||||
var s string
|
||||
if d.isAcceptState {
|
||||
@ -164,8 +143,27 @@ func (d *DFAState) String() string {
|
||||
return fmt.Sprintf("%d:%s%s", d.stateNumber, fmt.Sprint(d.configs), s)
|
||||
}
|
||||
|
||||
func (d *DFAState) hash() int {
|
||||
func (d *DFAState) Hash() int {
|
||||
h := murmurInit(7)
|
||||
h = murmurUpdate(h, d.configs.hash())
|
||||
h = murmurUpdate(h, d.configs.Hash())
|
||||
return murmurFinish(h, 1)
|
||||
}
|
||||
|
||||
// Equals returns whether d equals other. Two DFAStates are equal if their ATN
|
||||
// configuration sets are the same. This method is used to see if a state
|
||||
// already exists.
|
||||
//
|
||||
// Because the number of alternatives and number of ATN configurations are
|
||||
// finite, there is a finite number of DFA states that can be processed. This is
|
||||
// necessary to show that the algorithm terminates.
|
||||
//
|
||||
// Cannot test the DFA state numbers here because in
|
||||
// ParserATNSimulator.addDFAState we need to know if any other state exists that
|
||||
// has d exact set of ATN configurations. The stateNumber is irrelevant.
|
||||
func (d *DFAState) Equals(o Collectable[*DFAState]) bool {
|
||||
if d == o {
|
||||
return true
|
||||
}
|
||||
|
||||
return d.configs.Equals(o.(*DFAState).configs)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -87,7 +87,6 @@ func (d *DiagnosticErrorListener) getDecisionDescription(recognizer Parser, dfa
|
||||
return strconv.Itoa(decision) + " (" + ruleName + ")"
|
||||
}
|
||||
|
||||
//
|
||||
// Computes the set of conflicting or ambiguous alternatives from a
|
||||
// configuration set, if that information was not already provided by the
|
||||
// parser.
|
||||
@ -97,7 +96,6 @@ func (d *DiagnosticErrorListener) getDecisionDescription(recognizer Parser, dfa
|
||||
// @param configs The conflicting or ambiguous configuration set.
|
||||
// @return Returns {@code ReportedAlts} if it is not {@code nil}, otherwise
|
||||
// returns the set of alternatives represented in {@code configs}.
|
||||
//
|
||||
func (d *DiagnosticErrorListener) getConflictingAlts(ReportedAlts *BitSet, set ATNConfigSet) *BitSet {
|
||||
if ReportedAlts != nil {
|
||||
return ReportedAlts
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -48,12 +48,9 @@ func NewConsoleErrorListener() *ConsoleErrorListener {
|
||||
return new(ConsoleErrorListener)
|
||||
}
|
||||
|
||||
//
|
||||
// Provides a default instance of {@link ConsoleErrorListener}.
|
||||
//
|
||||
var ConsoleErrorListenerINSTANCE = NewConsoleErrorListener()
|
||||
|
||||
//
|
||||
// {@inheritDoc}
|
||||
//
|
||||
// <p>
|
||||
@ -64,7 +61,6 @@ var ConsoleErrorListenerINSTANCE = NewConsoleErrorListener()
|
||||
// <pre>
|
||||
// line <em>line</em>:<em>charPositionInLine</em> <em>msg</em>
|
||||
// </pre>
|
||||
//
|
||||
func (c *ConsoleErrorListener) SyntaxError(recognizer Recognizer, offendingSymbol interface{}, line, column int, msg string, e RecognitionException) {
|
||||
fmt.Fprintln(os.Stderr, "line "+strconv.Itoa(line)+":"+strconv.Itoa(column)+" "+msg)
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -23,7 +23,6 @@ type ErrorStrategy interface {
|
||||
|
||||
// This is the default implementation of {@link ANTLRErrorStrategy} used for
|
||||
// error Reporting and recovery in ANTLR parsers.
|
||||
//
|
||||
type DefaultErrorStrategy struct {
|
||||
errorRecoveryMode bool
|
||||
lastErrorIndex int
|
||||
@ -61,12 +60,10 @@ func (d *DefaultErrorStrategy) reset(recognizer Parser) {
|
||||
d.endErrorCondition(recognizer)
|
||||
}
|
||||
|
||||
//
|
||||
// This method is called to enter error recovery mode when a recognition
|
||||
// exception is Reported.
|
||||
//
|
||||
// @param recognizer the parser instance
|
||||
//
|
||||
func (d *DefaultErrorStrategy) beginErrorCondition(recognizer Parser) {
|
||||
d.errorRecoveryMode = true
|
||||
}
|
||||
@ -75,28 +72,23 @@ func (d *DefaultErrorStrategy) InErrorRecoveryMode(recognizer Parser) bool {
|
||||
return d.errorRecoveryMode
|
||||
}
|
||||
|
||||
//
|
||||
// This method is called to leave error recovery mode after recovering from
|
||||
// a recognition exception.
|
||||
//
|
||||
// @param recognizer
|
||||
//
|
||||
func (d *DefaultErrorStrategy) endErrorCondition(recognizer Parser) {
|
||||
d.errorRecoveryMode = false
|
||||
d.lastErrorStates = nil
|
||||
d.lastErrorIndex = -1
|
||||
}
|
||||
|
||||
//
|
||||
// {@inheritDoc}
|
||||
//
|
||||
// <p>The default implementation simply calls {@link //endErrorCondition}.</p>
|
||||
//
|
||||
func (d *DefaultErrorStrategy) ReportMatch(recognizer Parser) {
|
||||
d.endErrorCondition(recognizer)
|
||||
}
|
||||
|
||||
//
|
||||
// {@inheritDoc}
|
||||
//
|
||||
// <p>The default implementation returns immediately if the handler is already
|
||||
@ -114,7 +106,6 @@ func (d *DefaultErrorStrategy) ReportMatch(recognizer Parser) {
|
||||
// <li>All other types: calls {@link Parser//NotifyErrorListeners} to Report
|
||||
// the exception</li>
|
||||
// </ul>
|
||||
//
|
||||
func (d *DefaultErrorStrategy) ReportError(recognizer Parser, e RecognitionException) {
|
||||
// if we've already Reported an error and have not Matched a token
|
||||
// yet successfully, don't Report any errors.
|
||||
@ -142,7 +133,6 @@ func (d *DefaultErrorStrategy) ReportError(recognizer Parser, e RecognitionExcep
|
||||
// <p>The default implementation reSynchronizes the parser by consuming tokens
|
||||
// until we find one in the reSynchronization set--loosely the set of tokens
|
||||
// that can follow the current rule.</p>
|
||||
//
|
||||
func (d *DefaultErrorStrategy) Recover(recognizer Parser, e RecognitionException) {
|
||||
|
||||
if d.lastErrorIndex == recognizer.GetInputStream().Index() &&
|
||||
@ -206,7 +196,6 @@ func (d *DefaultErrorStrategy) Recover(recognizer Parser, e RecognitionException
|
||||
// compare token set at the start of the loop and at each iteration. If for
|
||||
// some reason speed is suffering for you, you can turn off d
|
||||
// functionality by simply overriding d method as a blank { }.</p>
|
||||
//
|
||||
func (d *DefaultErrorStrategy) Sync(recognizer Parser) {
|
||||
// If already recovering, don't try to Sync
|
||||
if d.InErrorRecoveryMode(recognizer) {
|
||||
@ -247,7 +236,6 @@ func (d *DefaultErrorStrategy) Sync(recognizer Parser) {
|
||||
//
|
||||
// @param recognizer the parser instance
|
||||
// @param e the recognition exception
|
||||
//
|
||||
func (d *DefaultErrorStrategy) ReportNoViableAlternative(recognizer Parser, e *NoViableAltException) {
|
||||
tokens := recognizer.GetTokenStream()
|
||||
var input string
|
||||
@ -264,7 +252,6 @@ func (d *DefaultErrorStrategy) ReportNoViableAlternative(recognizer Parser, e *N
|
||||
recognizer.NotifyErrorListeners(msg, e.offendingToken, e)
|
||||
}
|
||||
|
||||
//
|
||||
// This is called by {@link //ReportError} when the exception is an
|
||||
// {@link InputMisMatchException}.
|
||||
//
|
||||
@ -272,14 +259,12 @@ func (d *DefaultErrorStrategy) ReportNoViableAlternative(recognizer Parser, e *N
|
||||
//
|
||||
// @param recognizer the parser instance
|
||||
// @param e the recognition exception
|
||||
//
|
||||
func (this *DefaultErrorStrategy) ReportInputMisMatch(recognizer Parser, e *InputMisMatchException) {
|
||||
msg := "mismatched input " + this.GetTokenErrorDisplay(e.offendingToken) +
|
||||
" expecting " + e.getExpectedTokens().StringVerbose(recognizer.GetLiteralNames(), recognizer.GetSymbolicNames(), false)
|
||||
recognizer.NotifyErrorListeners(msg, e.offendingToken, e)
|
||||
}
|
||||
|
||||
//
|
||||
// This is called by {@link //ReportError} when the exception is a
|
||||
// {@link FailedPredicateException}.
|
||||
//
|
||||
@ -287,7 +272,6 @@ func (this *DefaultErrorStrategy) ReportInputMisMatch(recognizer Parser, e *Inpu
|
||||
//
|
||||
// @param recognizer the parser instance
|
||||
// @param e the recognition exception
|
||||
//
|
||||
func (d *DefaultErrorStrategy) ReportFailedPredicate(recognizer Parser, e *FailedPredicateException) {
|
||||
ruleName := recognizer.GetRuleNames()[recognizer.GetParserRuleContext().GetRuleIndex()]
|
||||
msg := "rule " + ruleName + " " + e.message
|
||||
@ -310,7 +294,6 @@ func (d *DefaultErrorStrategy) ReportFailedPredicate(recognizer Parser, e *Faile
|
||||
// {@link Parser//NotifyErrorListeners}.</p>
|
||||
//
|
||||
// @param recognizer the parser instance
|
||||
//
|
||||
func (d *DefaultErrorStrategy) ReportUnwantedToken(recognizer Parser) {
|
||||
if d.InErrorRecoveryMode(recognizer) {
|
||||
return
|
||||
@ -339,7 +322,6 @@ func (d *DefaultErrorStrategy) ReportUnwantedToken(recognizer Parser) {
|
||||
// {@link Parser//NotifyErrorListeners}.</p>
|
||||
//
|
||||
// @param recognizer the parser instance
|
||||
//
|
||||
func (d *DefaultErrorStrategy) ReportMissingToken(recognizer Parser) {
|
||||
if d.InErrorRecoveryMode(recognizer) {
|
||||
return
|
||||
@ -392,15 +374,14 @@ func (d *DefaultErrorStrategy) ReportMissingToken(recognizer Parser) {
|
||||
// derivation:
|
||||
//
|
||||
// <pre>
|
||||
// => ID '=' '(' INT ')' ('+' atom)* ''
|
||||
// => ID '=' '(' INT ')' ('+' atom)* ”
|
||||
// ^
|
||||
// </pre>
|
||||
//
|
||||
// The attempt to Match {@code ')'} will fail when it sees {@code ''} and
|
||||
// call {@link //recoverInline}. To recover, it sees that {@code LA(1)==''}
|
||||
// The attempt to Match {@code ')'} will fail when it sees {@code ”} and
|
||||
// call {@link //recoverInline}. To recover, it sees that {@code LA(1)==”}
|
||||
// is in the set of tokens that can follow the {@code ')'} token reference
|
||||
// in rule {@code atom}. It can assume that you forgot the {@code ')'}.
|
||||
//
|
||||
func (d *DefaultErrorStrategy) RecoverInline(recognizer Parser) Token {
|
||||
// SINGLE TOKEN DELETION
|
||||
MatchedSymbol := d.SingleTokenDeletion(recognizer)
|
||||
@ -418,7 +399,6 @@ func (d *DefaultErrorStrategy) RecoverInline(recognizer Parser) Token {
|
||||
panic(NewInputMisMatchException(recognizer))
|
||||
}
|
||||
|
||||
//
|
||||
// This method implements the single-token insertion inline error recovery
|
||||
// strategy. It is called by {@link //recoverInline} if the single-token
|
||||
// deletion strategy fails to recover from the mismatched input. If this
|
||||
@ -434,7 +414,6 @@ func (d *DefaultErrorStrategy) RecoverInline(recognizer Parser) Token {
|
||||
// @param recognizer the parser instance
|
||||
// @return {@code true} if single-token insertion is a viable recovery
|
||||
// strategy for the current mismatched input, otherwise {@code false}
|
||||
//
|
||||
func (d *DefaultErrorStrategy) SingleTokenInsertion(recognizer Parser) bool {
|
||||
currentSymbolType := recognizer.GetTokenStream().LA(1)
|
||||
// if current token is consistent with what could come after current
|
||||
@ -469,7 +448,6 @@ func (d *DefaultErrorStrategy) SingleTokenInsertion(recognizer Parser) bool {
|
||||
// @return the successfully Matched {@link Token} instance if single-token
|
||||
// deletion successfully recovers from the mismatched input, otherwise
|
||||
// {@code nil}
|
||||
//
|
||||
func (d *DefaultErrorStrategy) SingleTokenDeletion(recognizer Parser) Token {
|
||||
NextTokenType := recognizer.GetTokenStream().LA(2)
|
||||
expecting := d.GetExpectedTokens(recognizer)
|
||||
@ -507,7 +485,6 @@ func (d *DefaultErrorStrategy) SingleTokenDeletion(recognizer Parser) Token {
|
||||
// a CommonToken of the appropriate type. The text will be the token.
|
||||
// If you change what tokens must be created by the lexer,
|
||||
// override d method to create the appropriate tokens.
|
||||
//
|
||||
func (d *DefaultErrorStrategy) GetMissingSymbol(recognizer Parser) Token {
|
||||
currentSymbol := recognizer.GetCurrentToken()
|
||||
expecting := d.GetExpectedTokens(recognizer)
|
||||
@ -546,7 +523,6 @@ func (d *DefaultErrorStrategy) GetExpectedTokens(recognizer Parser) *IntervalSet
|
||||
// the token). This is better than forcing you to override a method in
|
||||
// your token objects because you don't have to go modify your lexer
|
||||
// so that it creates a NewJava type.
|
||||
//
|
||||
func (d *DefaultErrorStrategy) GetTokenErrorDisplay(t Token) string {
|
||||
if t == nil {
|
||||
return "<no token>"
|
||||
@ -578,7 +554,7 @@ func (d *DefaultErrorStrategy) escapeWSAndQuote(s string) string {
|
||||
// from within the rule i.e., the FIRST computation done by
|
||||
// ANTLR stops at the end of a rule.
|
||||
//
|
||||
// EXAMPLE
|
||||
// # EXAMPLE
|
||||
//
|
||||
// When you find a "no viable alt exception", the input is not
|
||||
// consistent with any of the alternatives for rule r. The best
|
||||
@ -597,7 +573,6 @@ func (d *DefaultErrorStrategy) escapeWSAndQuote(s string) string {
|
||||
// c : ID
|
||||
// | INT
|
||||
//
|
||||
//
|
||||
// At each rule invocation, the set of tokens that could follow
|
||||
// that rule is pushed on a stack. Here are the various
|
||||
// context-sensitive follow sets:
|
||||
@ -660,7 +635,6 @@ func (d *DefaultErrorStrategy) escapeWSAndQuote(s string) string {
|
||||
//
|
||||
// Like Grosch I implement context-sensitive FOLLOW sets that are combined
|
||||
// at run-time upon error to avoid overhead during parsing.
|
||||
//
|
||||
func (d *DefaultErrorStrategy) getErrorRecoverySet(recognizer Parser) *IntervalSet {
|
||||
atn := recognizer.GetInterpreter().atn
|
||||
ctx := recognizer.GetParserRuleContext()
|
||||
@ -733,7 +707,6 @@ func NewBailErrorStrategy() *BailErrorStrategy {
|
||||
// in a {@link ParseCancellationException} so it is not caught by the
|
||||
// rule func catches. Use {@link Exception//getCause()} to get the
|
||||
// original {@link RecognitionException}.
|
||||
//
|
||||
func (b *BailErrorStrategy) Recover(recognizer Parser, e RecognitionException) {
|
||||
context := recognizer.GetParserRuleContext()
|
||||
for context != nil {
|
||||
@ -749,7 +722,6 @@ func (b *BailErrorStrategy) Recover(recognizer Parser, e RecognitionException) {
|
||||
|
||||
// Make sure we don't attempt to recover inline if the parser
|
||||
// successfully recovers, it won't panic an exception.
|
||||
//
|
||||
func (b *BailErrorStrategy) RecoverInline(recognizer Parser) Token {
|
||||
b.Recover(recognizer, NewInputMisMatchException(recognizer))
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -74,7 +74,6 @@ func (b *BaseRecognitionException) GetInputStream() IntStream {
|
||||
|
||||
// <p>If the state number is not known, b method returns -1.</p>
|
||||
|
||||
//
|
||||
// Gets the set of input symbols which could potentially follow the
|
||||
// previously Matched symbol at the time b exception was panicn.
|
||||
//
|
||||
@ -136,7 +135,6 @@ type NoViableAltException struct {
|
||||
// to take based upon the remaining input. It tracks the starting token
|
||||
// of the offending input and also knows where the parser was
|
||||
// in the various paths when the error. Reported by ReportNoViableAlternative()
|
||||
//
|
||||
func NewNoViableAltException(recognizer Parser, input TokenStream, startToken Token, offendingToken Token, deadEndConfigs ATNConfigSet, ctx ParserRuleContext) *NoViableAltException {
|
||||
|
||||
if ctx == nil {
|
||||
@ -177,7 +175,6 @@ type InputMisMatchException struct {
|
||||
|
||||
// This signifies any kind of mismatched input exceptions such as
|
||||
// when the current input does not Match the expected token.
|
||||
//
|
||||
func NewInputMisMatchException(recognizer Parser) *InputMisMatchException {
|
||||
|
||||
i := new(InputMisMatchException)
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -223,6 +223,10 @@ func (i *IntervalSet) StringVerbose(literalNames []string, symbolicNames []strin
|
||||
return i.toIndexString()
|
||||
}
|
||||
|
||||
func (i *IntervalSet) GetIntervals() []*Interval {
|
||||
return i.intervals
|
||||
}
|
||||
|
||||
func (i *IntervalSet) toCharString() string {
|
||||
names := make([]string, len(i.intervals))
|
||||
|
198
vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/jcollect.go
generated
vendored
Normal file
198
vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/jcollect.go
generated
vendored
Normal file
@ -0,0 +1,198 @@
|
||||
package antlr
|
||||
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Collectable is an interface that a struct should implement if it is to be
|
||||
// usable as a key in these collections.
|
||||
type Collectable[T any] interface {
|
||||
Hash() int
|
||||
Equals(other Collectable[T]) bool
|
||||
}
|
||||
|
||||
type Comparator[T any] interface {
|
||||
Hash1(o T) int
|
||||
Equals2(T, T) bool
|
||||
}
|
||||
|
||||
// JStore implements a container that allows the use of a struct to calculate the key
|
||||
// for a collection of values akin to map. This is not meant to be a full-blown HashMap but just
|
||||
// serve the needs of the ANTLR Go runtime.
|
||||
//
|
||||
// For ease of porting the logic of the runtime from the master target (Java), this collection
|
||||
// operates in a similar way to Java, in that it can use any struct that supplies a Hash() and Equals()
|
||||
// function as the key. The values are stored in a standard go map which internally is a form of hashmap
|
||||
// itself, the key for the go map is the hash supplied by the key object. The collection is able to deal with
|
||||
// hash conflicts by using a simple slice of values associated with the hash code indexed bucket. That isn't
|
||||
// particularly efficient, but it is simple, and it works. As this is specifically for the ANTLR runtime, and
|
||||
// we understand the requirements, then this is fine - this is not a general purpose collection.
|
||||
type JStore[T any, C Comparator[T]] struct {
|
||||
store map[int][]T
|
||||
len int
|
||||
comparator Comparator[T]
|
||||
}
|
||||
|
||||
func NewJStore[T any, C Comparator[T]](comparator Comparator[T]) *JStore[T, C] {
|
||||
|
||||
if comparator == nil {
|
||||
panic("comparator cannot be nil")
|
||||
}
|
||||
|
||||
s := &JStore[T, C]{
|
||||
store: make(map[int][]T, 1),
|
||||
comparator: comparator,
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Put will store given value in the collection. Note that the key for storage is generated from
|
||||
// the value itself - this is specifically because that is what ANTLR needs - this would not be useful
|
||||
// as any kind of general collection.
|
||||
//
|
||||
// If the key has a hash conflict, then the value will be added to the slice of values associated with the
|
||||
// hash, unless the value is already in the slice, in which case the existing value is returned. Value equivalence is
|
||||
// tested by calling the equals() method on the key.
|
||||
//
|
||||
// # If the given value is already present in the store, then the existing value is returned as v and exists is set to true
|
||||
//
|
||||
// If the given value is not present in the store, then the value is added to the store and returned as v and exists is set to false.
|
||||
func (s *JStore[T, C]) Put(value T) (v T, exists bool) { //nolint:ireturn
|
||||
|
||||
kh := s.comparator.Hash1(value)
|
||||
|
||||
for _, v1 := range s.store[kh] {
|
||||
if s.comparator.Equals2(value, v1) {
|
||||
return v1, true
|
||||
}
|
||||
}
|
||||
s.store[kh] = append(s.store[kh], value)
|
||||
s.len++
|
||||
return value, false
|
||||
}
|
||||
|
||||
// Get will return the value associated with the key - the type of the key is the same type as the value
|
||||
// which would not generally be useful, but this is a specific thing for ANTLR where the key is
|
||||
// generated using the object we are going to store.
|
||||
func (s *JStore[T, C]) Get(key T) (T, bool) { //nolint:ireturn
|
||||
|
||||
kh := s.comparator.Hash1(key)
|
||||
|
||||
for _, v := range s.store[kh] {
|
||||
if s.comparator.Equals2(key, v) {
|
||||
return v, true
|
||||
}
|
||||
}
|
||||
return key, false
|
||||
}
|
||||
|
||||
// Contains returns true if the given key is present in the store
|
||||
func (s *JStore[T, C]) Contains(key T) bool { //nolint:ireturn
|
||||
|
||||
_, present := s.Get(key)
|
||||
return present
|
||||
}
|
||||
|
||||
func (s *JStore[T, C]) SortedSlice(less func(i, j T) bool) []T {
|
||||
vs := make([]T, 0, len(s.store))
|
||||
for _, v := range s.store {
|
||||
vs = append(vs, v...)
|
||||
}
|
||||
sort.Slice(vs, func(i, j int) bool {
|
||||
return less(vs[i], vs[j])
|
||||
})
|
||||
|
||||
return vs
|
||||
}
|
||||
|
||||
func (s *JStore[T, C]) Each(f func(T) bool) {
|
||||
for _, e := range s.store {
|
||||
for _, v := range e {
|
||||
f(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *JStore[T, C]) Len() int {
|
||||
return s.len
|
||||
}
|
||||
|
||||
func (s *JStore[T, C]) Values() []T {
|
||||
vs := make([]T, 0, len(s.store))
|
||||
for _, e := range s.store {
|
||||
for _, v := range e {
|
||||
vs = append(vs, v)
|
||||
}
|
||||
}
|
||||
return vs
|
||||
}
|
||||
|
||||
type entry[K, V any] struct {
|
||||
key K
|
||||
val V
|
||||
}
|
||||
|
||||
type JMap[K, V any, C Comparator[K]] struct {
|
||||
store map[int][]*entry[K, V]
|
||||
len int
|
||||
comparator Comparator[K]
|
||||
}
|
||||
|
||||
func NewJMap[K, V any, C Comparator[K]](comparator Comparator[K]) *JMap[K, V, C] {
|
||||
return &JMap[K, V, C]{
|
||||
store: make(map[int][]*entry[K, V], 1),
|
||||
comparator: comparator,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *JMap[K, V, C]) Put(key K, val V) {
|
||||
kh := m.comparator.Hash1(key)
|
||||
|
||||
m.store[kh] = append(m.store[kh], &entry[K, V]{key, val})
|
||||
m.len++
|
||||
}
|
||||
|
||||
func (m *JMap[K, V, C]) Values() []V {
|
||||
vs := make([]V, 0, len(m.store))
|
||||
for _, e := range m.store {
|
||||
for _, v := range e {
|
||||
vs = append(vs, v.val)
|
||||
}
|
||||
}
|
||||
return vs
|
||||
}
|
||||
|
||||
func (m *JMap[K, V, C]) Get(key K) (V, bool) {
|
||||
|
||||
var none V
|
||||
kh := m.comparator.Hash1(key)
|
||||
for _, e := range m.store[kh] {
|
||||
if m.comparator.Equals2(e.key, key) {
|
||||
return e.val, true
|
||||
}
|
||||
}
|
||||
return none, false
|
||||
}
|
||||
|
||||
func (m *JMap[K, V, C]) Len() int {
|
||||
return len(m.store)
|
||||
}
|
||||
|
||||
func (m *JMap[K, V, C]) Delete(key K) {
|
||||
kh := m.comparator.Hash1(key)
|
||||
for i, e := range m.store[kh] {
|
||||
if m.comparator.Equals2(e.key, key) {
|
||||
m.store[kh] = append(m.store[kh][:i], m.store[kh][i+1:]...)
|
||||
m.len--
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *JMap[K, V, C]) Clear() {
|
||||
m.store = make(map[int][]*entry[K, V])
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -232,8 +232,6 @@ func (b *BaseLexer) NextToken() Token {
|
||||
}
|
||||
return b.token
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Instruct the lexer to Skip creating a token for current lexer rule
|
||||
@ -342,7 +340,7 @@ func (b *BaseLexer) GetCharIndex() int {
|
||||
}
|
||||
|
||||
// Return the text Matched so far for the current token or any text override.
|
||||
//Set the complete text of l token it wipes any previous changes to the text.
|
||||
// Set the complete text of l token it wipes any previous changes to the text.
|
||||
func (b *BaseLexer) GetText() string {
|
||||
if b.text != "" {
|
||||
return b.text
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -21,8 +21,8 @@ type LexerAction interface {
|
||||
getActionType() int
|
||||
getIsPositionDependent() bool
|
||||
execute(lexer Lexer)
|
||||
hash() int
|
||||
equals(other LexerAction) bool
|
||||
Hash() int
|
||||
Equals(other LexerAction) bool
|
||||
}
|
||||
|
||||
type BaseLexerAction struct {
|
||||
@ -51,15 +51,14 @@ func (b *BaseLexerAction) getIsPositionDependent() bool {
|
||||
return b.isPositionDependent
|
||||
}
|
||||
|
||||
func (b *BaseLexerAction) hash() int {
|
||||
func (b *BaseLexerAction) Hash() int {
|
||||
return b.actionType
|
||||
}
|
||||
|
||||
func (b *BaseLexerAction) equals(other LexerAction) bool {
|
||||
func (b *BaseLexerAction) Equals(other LexerAction) bool {
|
||||
return b == other
|
||||
}
|
||||
|
||||
//
|
||||
// Implements the {@code Skip} lexer action by calling {@link Lexer//Skip}.
|
||||
//
|
||||
// <p>The {@code Skip} command does not have any parameters, so l action is
|
||||
@ -85,7 +84,8 @@ func (l *LexerSkipAction) String() string {
|
||||
return "skip"
|
||||
}
|
||||
|
||||
// Implements the {@code type} lexer action by calling {@link Lexer//setType}
|
||||
// Implements the {@code type} lexer action by calling {@link Lexer//setType}
|
||||
//
|
||||
// with the assigned type.
|
||||
type LexerTypeAction struct {
|
||||
*BaseLexerAction
|
||||
@ -104,14 +104,14 @@ func (l *LexerTypeAction) execute(lexer Lexer) {
|
||||
lexer.SetType(l.thetype)
|
||||
}
|
||||
|
||||
func (l *LexerTypeAction) hash() int {
|
||||
func (l *LexerTypeAction) Hash() int {
|
||||
h := murmurInit(0)
|
||||
h = murmurUpdate(h, l.actionType)
|
||||
h = murmurUpdate(h, l.thetype)
|
||||
return murmurFinish(h, 2)
|
||||
}
|
||||
|
||||
func (l *LexerTypeAction) equals(other LexerAction) bool {
|
||||
func (l *LexerTypeAction) Equals(other LexerAction) bool {
|
||||
if l == other {
|
||||
return true
|
||||
} else if _, ok := other.(*LexerTypeAction); !ok {
|
||||
@ -148,14 +148,14 @@ func (l *LexerPushModeAction) execute(lexer Lexer) {
|
||||
lexer.PushMode(l.mode)
|
||||
}
|
||||
|
||||
func (l *LexerPushModeAction) hash() int {
|
||||
func (l *LexerPushModeAction) Hash() int {
|
||||
h := murmurInit(0)
|
||||
h = murmurUpdate(h, l.actionType)
|
||||
h = murmurUpdate(h, l.mode)
|
||||
return murmurFinish(h, 2)
|
||||
}
|
||||
|
||||
func (l *LexerPushModeAction) equals(other LexerAction) bool {
|
||||
func (l *LexerPushModeAction) Equals(other LexerAction) bool {
|
||||
if l == other {
|
||||
return true
|
||||
} else if _, ok := other.(*LexerPushModeAction); !ok {
|
||||
@ -245,14 +245,14 @@ func (l *LexerModeAction) execute(lexer Lexer) {
|
||||
lexer.SetMode(l.mode)
|
||||
}
|
||||
|
||||
func (l *LexerModeAction) hash() int {
|
||||
func (l *LexerModeAction) Hash() int {
|
||||
h := murmurInit(0)
|
||||
h = murmurUpdate(h, l.actionType)
|
||||
h = murmurUpdate(h, l.mode)
|
||||
return murmurFinish(h, 2)
|
||||
}
|
||||
|
||||
func (l *LexerModeAction) equals(other LexerAction) bool {
|
||||
func (l *LexerModeAction) Equals(other LexerAction) bool {
|
||||
if l == other {
|
||||
return true
|
||||
} else if _, ok := other.(*LexerModeAction); !ok {
|
||||
@ -303,7 +303,7 @@ func (l *LexerCustomAction) execute(lexer Lexer) {
|
||||
lexer.Action(nil, l.ruleIndex, l.actionIndex)
|
||||
}
|
||||
|
||||
func (l *LexerCustomAction) hash() int {
|
||||
func (l *LexerCustomAction) Hash() int {
|
||||
h := murmurInit(0)
|
||||
h = murmurUpdate(h, l.actionType)
|
||||
h = murmurUpdate(h, l.ruleIndex)
|
||||
@ -311,13 +311,14 @@ func (l *LexerCustomAction) hash() int {
|
||||
return murmurFinish(h, 3)
|
||||
}
|
||||
|
||||
func (l *LexerCustomAction) equals(other LexerAction) bool {
|
||||
func (l *LexerCustomAction) Equals(other LexerAction) bool {
|
||||
if l == other {
|
||||
return true
|
||||
} else if _, ok := other.(*LexerCustomAction); !ok {
|
||||
return false
|
||||
} else {
|
||||
return l.ruleIndex == other.(*LexerCustomAction).ruleIndex && l.actionIndex == other.(*LexerCustomAction).actionIndex
|
||||
return l.ruleIndex == other.(*LexerCustomAction).ruleIndex &&
|
||||
l.actionIndex == other.(*LexerCustomAction).actionIndex
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,14 +345,14 @@ func (l *LexerChannelAction) execute(lexer Lexer) {
|
||||
lexer.SetChannel(l.channel)
|
||||
}
|
||||
|
||||
func (l *LexerChannelAction) hash() int {
|
||||
func (l *LexerChannelAction) Hash() int {
|
||||
h := murmurInit(0)
|
||||
h = murmurUpdate(h, l.actionType)
|
||||
h = murmurUpdate(h, l.channel)
|
||||
return murmurFinish(h, 2)
|
||||
}
|
||||
|
||||
func (l *LexerChannelAction) equals(other LexerAction) bool {
|
||||
func (l *LexerChannelAction) Equals(other LexerAction) bool {
|
||||
if l == other {
|
||||
return true
|
||||
} else if _, ok := other.(*LexerChannelAction); !ok {
|
||||
@ -412,10 +413,10 @@ func (l *LexerIndexedCustomAction) execute(lexer Lexer) {
|
||||
l.lexerAction.execute(lexer)
|
||||
}
|
||||
|
||||
func (l *LexerIndexedCustomAction) hash() int {
|
||||
func (l *LexerIndexedCustomAction) Hash() int {
|
||||
h := murmurInit(0)
|
||||
h = murmurUpdate(h, l.offset)
|
||||
h = murmurUpdate(h, l.lexerAction.hash())
|
||||
h = murmurUpdate(h, l.lexerAction.Hash())
|
||||
return murmurFinish(h, 2)
|
||||
}
|
||||
|
||||
@ -425,6 +426,7 @@ func (l *LexerIndexedCustomAction) equals(other LexerAction) bool {
|
||||
} else if _, ok := other.(*LexerIndexedCustomAction); !ok {
|
||||
return false
|
||||
} else {
|
||||
return l.offset == other.(*LexerIndexedCustomAction).offset && l.lexerAction == other.(*LexerIndexedCustomAction).lexerAction
|
||||
return l.offset == other.(*LexerIndexedCustomAction).offset &&
|
||||
l.lexerAction.Equals(other.(*LexerIndexedCustomAction).lexerAction)
|
||||
}
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
package antlr
|
||||
|
||||
import "golang.org/x/exp/slices"
|
||||
|
||||
// Represents an executor for a sequence of lexer actions which traversed during
|
||||
// the Matching operation of a lexer rule (token).
|
||||
//
|
||||
@ -12,8 +14,8 @@ package antlr
|
||||
// not cause bloating of the {@link DFA} created for the lexer.</p>
|
||||
|
||||
type LexerActionExecutor struct {
|
||||
lexerActions []LexerAction
|
||||
cachedHash int
|
||||
lexerActions []LexerAction
|
||||
cachedHash int
|
||||
}
|
||||
|
||||
func NewLexerActionExecutor(lexerActions []LexerAction) *LexerActionExecutor {
|
||||
@ -30,7 +32,7 @@ func NewLexerActionExecutor(lexerActions []LexerAction) *LexerActionExecutor {
|
||||
// of the performance-critical {@link LexerATNConfig//hashCode} operation.
|
||||
l.cachedHash = murmurInit(57)
|
||||
for _, a := range lexerActions {
|
||||
l.cachedHash = murmurUpdate(l.cachedHash, a.hash())
|
||||
l.cachedHash = murmurUpdate(l.cachedHash, a.Hash())
|
||||
}
|
||||
|
||||
return l
|
||||
@ -151,14 +153,17 @@ func (l *LexerActionExecutor) execute(lexer Lexer, input CharStream, startIndex
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LexerActionExecutor) hash() int {
|
||||
func (l *LexerActionExecutor) Hash() int {
|
||||
if l == nil {
|
||||
// TODO: Why is this here? l should not be nil
|
||||
return 61
|
||||
}
|
||||
|
||||
// TODO: This is created from the action itself when the struct is created - will this be an issue at some point? Java uses the runtime assign hashcode
|
||||
return l.cachedHash
|
||||
}
|
||||
|
||||
func (l *LexerActionExecutor) equals(other interface{}) bool {
|
||||
func (l *LexerActionExecutor) Equals(other interface{}) bool {
|
||||
if l == other {
|
||||
return true
|
||||
}
|
||||
@ -169,5 +174,13 @@ func (l *LexerActionExecutor) equals(other interface{}) bool {
|
||||
if othert == nil {
|
||||
return false
|
||||
}
|
||||
return l.cachedHash == othert.cachedHash && &l.lexerActions == &othert.lexerActions
|
||||
if l.cachedHash != othert.cachedHash {
|
||||
return false
|
||||
}
|
||||
if len(l.lexerActions) != len(othert.lexerActions) {
|
||||
return false
|
||||
}
|
||||
return slices.EqualFunc(l.lexerActions, othert.lexerActions, func(i, j LexerAction) bool {
|
||||
return i.Equals(j)
|
||||
})
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -591,19 +591,24 @@ func (l *LexerATNSimulator) addDFAState(configs ATNConfigSet, suppressEdge bool)
|
||||
proposed.lexerActionExecutor = firstConfigWithRuleStopState.(*LexerATNConfig).lexerActionExecutor
|
||||
proposed.setPrediction(l.atn.ruleToTokenType[firstConfigWithRuleStopState.GetState().GetRuleIndex()])
|
||||
}
|
||||
hash := proposed.hash()
|
||||
dfa := l.decisionToDFA[l.mode]
|
||||
|
||||
l.atn.stateMu.Lock()
|
||||
defer l.atn.stateMu.Unlock()
|
||||
existing, ok := dfa.getState(hash)
|
||||
if ok {
|
||||
existing, present := dfa.states.Get(proposed)
|
||||
if present {
|
||||
|
||||
// This state was already present, so just return it.
|
||||
//
|
||||
proposed = existing
|
||||
} else {
|
||||
proposed.stateNumber = dfa.numStates()
|
||||
|
||||
// We need to add the new state
|
||||
//
|
||||
proposed.stateNumber = dfa.states.Len()
|
||||
configs.SetReadOnly(true)
|
||||
proposed.configs = configs
|
||||
dfa.setState(hash, proposed)
|
||||
dfa.states.Put(proposed)
|
||||
}
|
||||
if !suppressEdge {
|
||||
dfa.setS0(proposed)
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -14,14 +14,15 @@ func NewLL1Analyzer(atn *ATN) *LL1Analyzer {
|
||||
return la
|
||||
}
|
||||
|
||||
//* Special value added to the lookahead sets to indicate that we hit
|
||||
// a predicate during analysis if {@code seeThruPreds==false}.
|
||||
///
|
||||
// - Special value added to the lookahead sets to indicate that we hit
|
||||
// a predicate during analysis if {@code seeThruPreds==false}.
|
||||
//
|
||||
// /
|
||||
const (
|
||||
LL1AnalyzerHitPred = TokenInvalidType
|
||||
)
|
||||
|
||||
//*
|
||||
// *
|
||||
// Calculates the SLL(1) expected lookahead set for each outgoing transition
|
||||
// of an {@link ATNState}. The returned array has one element for each
|
||||
// outgoing transition in {@code s}. If the closure from transition
|
||||
@ -38,7 +39,7 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet {
|
||||
look := make([]*IntervalSet, count)
|
||||
for alt := 0; alt < count; alt++ {
|
||||
look[alt] = NewIntervalSet()
|
||||
lookBusy := newArray2DHashSet(nil, nil)
|
||||
lookBusy := NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst)
|
||||
seeThruPreds := false // fail to get lookahead upon pred
|
||||
la.look1(s.GetTransitions()[alt].getTarget(), nil, BasePredictionContextEMPTY, look[alt], lookBusy, NewBitSet(), seeThruPreds, false)
|
||||
// Wipe out lookahead for la alternative if we found nothing
|
||||
@ -50,7 +51,7 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet {
|
||||
return look
|
||||
}
|
||||
|
||||
//*
|
||||
// *
|
||||
// Compute set of tokens that can follow {@code s} in the ATN in the
|
||||
// specified {@code ctx}.
|
||||
//
|
||||
@ -67,7 +68,7 @@ func (la *LL1Analyzer) getDecisionLookahead(s ATNState) []*IntervalSet {
|
||||
//
|
||||
// @return The set of tokens that can follow {@code s} in the ATN in the
|
||||
// specified {@code ctx}.
|
||||
///
|
||||
// /
|
||||
func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet {
|
||||
r := NewIntervalSet()
|
||||
seeThruPreds := true // ignore preds get all lookahead
|
||||
@ -75,7 +76,7 @@ func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet
|
||||
if ctx != nil {
|
||||
lookContext = predictionContextFromRuleContext(s.GetATN(), ctx)
|
||||
}
|
||||
la.look1(s, stopState, lookContext, r, newArray2DHashSet(nil, nil), NewBitSet(), seeThruPreds, true)
|
||||
la.look1(s, stopState, lookContext, r, NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst), NewBitSet(), seeThruPreds, true)
|
||||
return r
|
||||
}
|
||||
|
||||
@ -109,14 +110,14 @@ func (la *LL1Analyzer) Look(s, stopState ATNState, ctx RuleContext) *IntervalSet
|
||||
// outermost context is reached. This parameter has no effect if {@code ctx}
|
||||
// is {@code nil}.
|
||||
|
||||
func (la *LL1Analyzer) look2(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool, i int) {
|
||||
func (la *LL1Analyzer) look2(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy *JStore[ATNConfig, Comparator[ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool, i int) {
|
||||
|
||||
returnState := la.atn.states[ctx.getReturnState(i)]
|
||||
la.look1(returnState, stopState, ctx.GetParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF)
|
||||
|
||||
}
|
||||
|
||||
func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool) {
|
||||
func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy *JStore[ATNConfig, Comparator[ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool) {
|
||||
|
||||
c := NewBaseATNConfig6(s, 0, ctx)
|
||||
|
||||
@ -124,8 +125,11 @@ func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look
|
||||
return
|
||||
}
|
||||
|
||||
lookBusy.Add(c)
|
||||
_, present := lookBusy.Put(c)
|
||||
if present {
|
||||
return
|
||||
|
||||
}
|
||||
if s == stopState {
|
||||
if ctx == nil {
|
||||
look.addOne(TokenEpsilon)
|
||||
@ -198,7 +202,7 @@ func (la *LL1Analyzer) look1(s, stopState ATNState, ctx PredictionContext, look
|
||||
}
|
||||
}
|
||||
|
||||
func (la *LL1Analyzer) look3(stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy Set, calledRuleStack *BitSet, seeThruPreds, addEOF bool, t1 *RuleTransition) {
|
||||
func (la *LL1Analyzer) look3(stopState ATNState, ctx PredictionContext, look *IntervalSet, lookBusy *JStore[ATNConfig, Comparator[ATNConfig]], calledRuleStack *BitSet, seeThruPreds, addEOF bool, t1 *RuleTransition) {
|
||||
|
||||
newContext := SingletonBasePredictionContextCreate(ctx, t1.followState.GetStateNumber())
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -91,7 +91,6 @@ func NewBaseParser(input TokenStream) *BaseParser {
|
||||
// bypass alternatives.
|
||||
//
|
||||
// @see ATNDeserializationOptions//isGenerateRuleBypassTransitions()
|
||||
//
|
||||
var bypassAltsAtnCache = make(map[string]int)
|
||||
|
||||
// reset the parser's state//
|
||||
@ -230,7 +229,6 @@ func (p *BaseParser) GetParseListeners() []ParseTreeListener {
|
||||
// @param listener the listener to add
|
||||
//
|
||||
// @panics nilPointerException if {@code} listener is {@code nil}
|
||||
//
|
||||
func (p *BaseParser) AddParseListener(listener ParseTreeListener) {
|
||||
if listener == nil {
|
||||
panic("listener")
|
||||
@ -241,13 +239,11 @@ func (p *BaseParser) AddParseListener(listener ParseTreeListener) {
|
||||
p.parseListeners = append(p.parseListeners, listener)
|
||||
}
|
||||
|
||||
//
|
||||
// Remove {@code listener} from the list of parse listeners.
|
||||
//
|
||||
// <p>If {@code listener} is {@code nil} or has not been added as a parse
|
||||
// listener, p.method does nothing.</p>
|
||||
// @param listener the listener to remove
|
||||
//
|
||||
func (p *BaseParser) RemoveParseListener(listener ParseTreeListener) {
|
||||
|
||||
if p.parseListeners != nil {
|
||||
@ -289,11 +285,9 @@ func (p *BaseParser) TriggerEnterRuleEvent() {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Notify any parse listeners of an exit rule event.
|
||||
//
|
||||
// @see //addParseListener
|
||||
//
|
||||
func (p *BaseParser) TriggerExitRuleEvent() {
|
||||
if p.parseListeners != nil {
|
||||
// reverse order walk of listeners
|
||||
@ -330,7 +324,6 @@ func (p *BaseParser) setTokenFactory(factory TokenFactory) {
|
||||
//
|
||||
// @panics UnsupportedOperationException if the current parser does not
|
||||
// implement the {@link //getSerializedATN()} method.
|
||||
//
|
||||
func (p *BaseParser) GetATNWithBypassAlts() {
|
||||
|
||||
// TODO
|
||||
@ -402,7 +395,6 @@ func (p *BaseParser) SetTokenStream(input TokenStream) {
|
||||
|
||||
// Match needs to return the current input symbol, which gets put
|
||||
// into the label for the associated token ref e.g., x=ID.
|
||||
//
|
||||
func (p *BaseParser) GetCurrentToken() Token {
|
||||
return p.input.LT(1)
|
||||
}
|
||||
@ -624,7 +616,6 @@ func (p *BaseParser) IsExpectedToken(symbol int) bool {
|
||||
// respectively.
|
||||
//
|
||||
// @see ATN//getExpectedTokens(int, RuleContext)
|
||||
//
|
||||
func (p *BaseParser) GetExpectedTokens() *IntervalSet {
|
||||
return p.Interpreter.atn.getExpectedTokens(p.state, p.ctx)
|
||||
}
|
||||
@ -686,7 +677,7 @@ func (p *BaseParser) GetDFAStrings() string {
|
||||
func (p *BaseParser) DumpDFA() {
|
||||
seenOne := false
|
||||
for _, dfa := range p.Interpreter.decisionToDFA {
|
||||
if dfa.numStates() > 0 {
|
||||
if dfa.states.Len() > 0 {
|
||||
if seenOne {
|
||||
fmt.Println()
|
||||
}
|
||||
@ -703,7 +694,6 @@ func (p *BaseParser) GetSourceName() string {
|
||||
|
||||
// During a parse is sometimes useful to listen in on the rule entry and exit
|
||||
// events as well as token Matches. p.is for quick and dirty debugging.
|
||||
//
|
||||
func (p *BaseParser) SetTrace(trace *TraceListener) {
|
||||
if trace == nil {
|
||||
p.RemoveParseListener(p.tracer)
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -11,11 +11,11 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ParserATNSimulatorDebug = false
|
||||
ParserATNSimulatorListATNDecisions = false
|
||||
ParserATNSimulatorDFADebug = false
|
||||
ParserATNSimulatorRetryDebug = false
|
||||
TurnOffLRLoopEntryBranchOpt = false
|
||||
ParserATNSimulatorDebug = false
|
||||
ParserATNSimulatorTraceATNSim = false
|
||||
ParserATNSimulatorDFADebug = false
|
||||
ParserATNSimulatorRetryDebug = false
|
||||
TurnOffLRLoopEntryBranchOpt = false
|
||||
)
|
||||
|
||||
type ParserATNSimulator struct {
|
||||
@ -70,8 +70,8 @@ func (p *ParserATNSimulator) reset() {
|
||||
}
|
||||
|
||||
func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, outerContext ParserRuleContext) int {
|
||||
if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions {
|
||||
fmt.Println("AdaptivePredict decision " + strconv.Itoa(decision) +
|
||||
if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim {
|
||||
fmt.Println("adaptivePredict decision " + strconv.Itoa(decision) +
|
||||
" exec LA(1)==" + p.getLookaheadName(input) +
|
||||
" line " + strconv.Itoa(input.LT(1).GetLine()) + ":" +
|
||||
strconv.Itoa(input.LT(1).GetColumn()))
|
||||
@ -111,15 +111,15 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou
|
||||
|
||||
if s0 == nil {
|
||||
if outerContext == nil {
|
||||
outerContext = RuleContextEmpty
|
||||
outerContext = ParserRuleContextEmpty
|
||||
}
|
||||
if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions {
|
||||
if ParserATNSimulatorDebug {
|
||||
fmt.Println("predictATN decision " + strconv.Itoa(dfa.decision) +
|
||||
" exec LA(1)==" + p.getLookaheadName(input) +
|
||||
", outerContext=" + outerContext.String(p.parser.GetRuleNames(), nil))
|
||||
}
|
||||
fullCtx := false
|
||||
s0Closure := p.computeStartState(dfa.atnStartState, RuleContextEmpty, fullCtx)
|
||||
s0Closure := p.computeStartState(dfa.atnStartState, ParserRuleContextEmpty, fullCtx)
|
||||
|
||||
p.atn.stateMu.Lock()
|
||||
if dfa.getPrecedenceDfa() {
|
||||
@ -174,17 +174,18 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou
|
||||
// Reporting insufficient predicates
|
||||
|
||||
// cover these cases:
|
||||
// dead end
|
||||
// single alt
|
||||
// single alt + preds
|
||||
// conflict
|
||||
// conflict + preds
|
||||
//
|
||||
// dead end
|
||||
// single alt
|
||||
// single alt + preds
|
||||
// conflict
|
||||
// conflict + preds
|
||||
func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream, startIndex int, outerContext ParserRuleContext) int {
|
||||
|
||||
if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions {
|
||||
if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim {
|
||||
fmt.Println("execATN decision " + strconv.Itoa(dfa.decision) +
|
||||
" exec LA(1)==" + p.getLookaheadName(input) +
|
||||
", DFA state " + s0.String() +
|
||||
", LA(1)==" + p.getLookaheadName(input) +
|
||||
" line " + strconv.Itoa(input.LT(1).GetLine()) + ":" + strconv.Itoa(input.LT(1).GetColumn()))
|
||||
}
|
||||
|
||||
@ -277,8 +278,6 @@ func (p *ParserATNSimulator) execATN(dfa *DFA, s0 *DFAState, input TokenStream,
|
||||
t = input.LA(1)
|
||||
}
|
||||
}
|
||||
|
||||
panic("Should not have reached p state")
|
||||
}
|
||||
|
||||
// Get an existing target state for an edge in the DFA. If the target state
|
||||
@ -384,7 +383,7 @@ func (p *ParserATNSimulator) predicateDFAState(dfaState *DFAState, decisionState
|
||||
// comes back with reach.uniqueAlt set to a valid alt
|
||||
func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 ATNConfigSet, input TokenStream, startIndex int, outerContext ParserRuleContext) int {
|
||||
|
||||
if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions {
|
||||
if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim {
|
||||
fmt.Println("execATNWithFullContext " + s0.String())
|
||||
}
|
||||
|
||||
@ -492,9 +491,6 @@ func (p *ParserATNSimulator) execATNWithFullContext(dfa *DFA, D *DFAState, s0 AT
|
||||
}
|
||||
|
||||
func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCtx bool) ATNConfigSet {
|
||||
if ParserATNSimulatorDebug {
|
||||
fmt.Println("in computeReachSet, starting closure: " + closure.String())
|
||||
}
|
||||
if p.mergeCache == nil {
|
||||
p.mergeCache = NewDoubleDict()
|
||||
}
|
||||
@ -570,7 +566,7 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt
|
||||
//
|
||||
if reach == nil {
|
||||
reach = NewBaseATNConfigSet(fullCtx)
|
||||
closureBusy := newArray2DHashSet(nil, nil)
|
||||
closureBusy := NewJStore[ATNConfig, Comparator[ATNConfig]](aConfEqInst)
|
||||
treatEOFAsEpsilon := t == TokenEOF
|
||||
amount := len(intermediate.configs)
|
||||
for k := 0; k < amount; k++ {
|
||||
@ -610,6 +606,11 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt
|
||||
reach.Add(skippedStopStates[l], p.mergeCache)
|
||||
}
|
||||
}
|
||||
|
||||
if ParserATNSimulatorTraceATNSim {
|
||||
fmt.Println("computeReachSet " + closure.String() + " -> " + reach.String())
|
||||
}
|
||||
|
||||
if len(reach.GetItems()) == 0 {
|
||||
return nil
|
||||
}
|
||||
@ -617,7 +618,6 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt
|
||||
return reach
|
||||
}
|
||||
|
||||
//
|
||||
// Return a configuration set containing only the configurations from
|
||||
// {@code configs} which are in a {@link RuleStopState}. If all
|
||||
// configurations in {@code configs} are already in a rule stop state, p
|
||||
@ -636,7 +636,6 @@ func (p *ParserATNSimulator) computeReachSet(closure ATNConfigSet, t int, fullCt
|
||||
// @return {@code configs} if all configurations in {@code configs} are in a
|
||||
// rule stop state, otherwise return a Newconfiguration set containing only
|
||||
// the configurations from {@code configs} which are in a rule stop state
|
||||
//
|
||||
func (p *ParserATNSimulator) removeAllConfigsNotInRuleStopState(configs ATNConfigSet, lookToEndOfRule bool) ATNConfigSet {
|
||||
if PredictionModeallConfigsInRuleStopStates(configs) {
|
||||
return configs
|
||||
@ -662,16 +661,20 @@ func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, full
|
||||
// always at least the implicit call to start rule
|
||||
initialContext := predictionContextFromRuleContext(p.atn, ctx)
|
||||
configs := NewBaseATNConfigSet(fullCtx)
|
||||
if ParserATNSimulatorDebug || ParserATNSimulatorTraceATNSim {
|
||||
fmt.Println("computeStartState from ATN state " + a.String() +
|
||||
" initialContext=" + initialContext.String())
|
||||
}
|
||||
|
||||
for i := 0; i < len(a.GetTransitions()); i++ {
|
||||
target := a.GetTransitions()[i].getTarget()
|
||||
c := NewBaseATNConfig6(target, i+1, initialContext)
|
||||
closureBusy := newArray2DHashSet(nil, nil)
|
||||
closureBusy := NewJStore[ATNConfig, Comparator[ATNConfig]](atnConfCompInst)
|
||||
p.closure(c, configs, closureBusy, true, fullCtx, false)
|
||||
}
|
||||
return configs
|
||||
}
|
||||
|
||||
//
|
||||
// This method transforms the start state computed by
|
||||
// {@link //computeStartState} to the special start state used by a
|
||||
// precedence DFA for a particular precedence value. The transformation
|
||||
@ -726,7 +729,6 @@ func (p *ParserATNSimulator) computeStartState(a ATNState, ctx RuleContext, full
|
||||
// @return The transformed configuration set representing the start state
|
||||
// for a precedence DFA at a particular precedence level (determined by
|
||||
// calling {@link Parser//getPrecedence}).
|
||||
//
|
||||
func (p *ParserATNSimulator) applyPrecedenceFilter(configs ATNConfigSet) ATNConfigSet {
|
||||
|
||||
statesFromAlt1 := make(map[int]PredictionContext)
|
||||
@ -760,7 +762,7 @@ func (p *ParserATNSimulator) applyPrecedenceFilter(configs ATNConfigSet) ATNConf
|
||||
// (basically a graph subtraction algorithm).
|
||||
if !config.getPrecedenceFilterSuppressed() {
|
||||
context := statesFromAlt1[config.GetState().GetStateNumber()]
|
||||
if context != nil && context.equals(config.GetContext()) {
|
||||
if context != nil && context.Equals(config.GetContext()) {
|
||||
// eliminated
|
||||
continue
|
||||
}
|
||||
@ -824,7 +826,6 @@ func (p *ParserATNSimulator) getPredicatePredictions(ambigAlts *BitSet, altToPre
|
||||
return pairs
|
||||
}
|
||||
|
||||
//
|
||||
// This method is used to improve the localization of error messages by
|
||||
// choosing an alternative rather than panicing a
|
||||
// {@link NoViableAltException} in particular prediction scenarios where the
|
||||
@ -869,7 +870,6 @@ func (p *ParserATNSimulator) getPredicatePredictions(ambigAlts *BitSet, altToPre
|
||||
// @return The value to return from {@link //AdaptivePredict}, or
|
||||
// {@link ATN//INVALID_ALT_NUMBER} if a suitable alternative was not
|
||||
// identified and {@link //AdaptivePredict} should Report an error instead.
|
||||
//
|
||||
func (p *ParserATNSimulator) getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(configs ATNConfigSet, outerContext ParserRuleContext) int {
|
||||
cfgs := p.splitAccordingToSemanticValidity(configs, outerContext)
|
||||
semValidConfigs := cfgs[0]
|
||||
@ -938,11 +938,11 @@ func (p *ParserATNSimulator) splitAccordingToSemanticValidity(configs ATNConfigS
|
||||
}
|
||||
|
||||
// Look through a list of predicate/alt pairs, returning alts for the
|
||||
// pairs that win. A {@code NONE} predicate indicates an alt containing an
|
||||
// unpredicated config which behaves as "always true." If !complete
|
||||
// then we stop at the first predicate that evaluates to true. This
|
||||
// includes pairs with nil predicates.
|
||||
//
|
||||
// pairs that win. A {@code NONE} predicate indicates an alt containing an
|
||||
// unpredicated config which behaves as "always true." If !complete
|
||||
// then we stop at the first predicate that evaluates to true. This
|
||||
// includes pairs with nil predicates.
|
||||
func (p *ParserATNSimulator) evalSemanticContext(predPredictions []*PredPrediction, outerContext ParserRuleContext, complete bool) *BitSet {
|
||||
predictions := NewBitSet()
|
||||
for i := 0; i < len(predPredictions); i++ {
|
||||
@ -972,16 +972,16 @@ func (p *ParserATNSimulator) evalSemanticContext(predPredictions []*PredPredicti
|
||||
return predictions
|
||||
}
|
||||
|
||||
func (p *ParserATNSimulator) closure(config ATNConfig, configs ATNConfigSet, closureBusy Set, collectPredicates, fullCtx, treatEOFAsEpsilon bool) {
|
||||
func (p *ParserATNSimulator) closure(config ATNConfig, configs ATNConfigSet, closureBusy *JStore[ATNConfig, Comparator[ATNConfig]], collectPredicates, fullCtx, treatEOFAsEpsilon bool) {
|
||||
initialDepth := 0
|
||||
p.closureCheckingStopState(config, configs, closureBusy, collectPredicates,
|
||||
fullCtx, initialDepth, treatEOFAsEpsilon)
|
||||
}
|
||||
|
||||
func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs ATNConfigSet, closureBusy Set, collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) {
|
||||
if ParserATNSimulatorDebug {
|
||||
func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs ATNConfigSet, closureBusy *JStore[ATNConfig, Comparator[ATNConfig]], collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) {
|
||||
if ParserATNSimulatorTraceATNSim {
|
||||
fmt.Println("closure(" + config.String() + ")")
|
||||
fmt.Println("configs(" + configs.String() + ")")
|
||||
//fmt.Println("configs(" + configs.String() + ")")
|
||||
if config.GetReachesIntoOuterContext() > 50 {
|
||||
panic("problem")
|
||||
}
|
||||
@ -1031,7 +1031,7 @@ func (p *ParserATNSimulator) closureCheckingStopState(config ATNConfig, configs
|
||||
}
|
||||
|
||||
// Do the actual work of walking epsilon edges//
|
||||
func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, closureBusy Set, collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) {
|
||||
func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet, closureBusy *JStore[ATNConfig, Comparator[ATNConfig]], collectPredicates, fullCtx bool, depth int, treatEOFAsEpsilon bool) {
|
||||
state := config.GetState()
|
||||
// optimization
|
||||
if !state.GetEpsilonOnlyTransitions() {
|
||||
@ -1066,7 +1066,8 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet,
|
||||
|
||||
c.SetReachesIntoOuterContext(c.GetReachesIntoOuterContext() + 1)
|
||||
|
||||
if closureBusy.Add(c) != c {
|
||||
_, present := closureBusy.Put(c)
|
||||
if present {
|
||||
// avoid infinite recursion for right-recursive rules
|
||||
continue
|
||||
}
|
||||
@ -1077,9 +1078,13 @@ func (p *ParserATNSimulator) closureWork(config ATNConfig, configs ATNConfigSet,
|
||||
fmt.Println("dips into outer ctx: " + c.String())
|
||||
}
|
||||
} else {
|
||||
if !t.getIsEpsilon() && closureBusy.Add(c) != c {
|
||||
// avoid infinite recursion for EOF* and EOF+
|
||||
continue
|
||||
|
||||
if !t.getIsEpsilon() {
|
||||
_, present := closureBusy.Put(c)
|
||||
if present {
|
||||
// avoid infinite recursion for EOF* and EOF+
|
||||
continue
|
||||
}
|
||||
}
|
||||
if _, ok := t.(*RuleTransition); ok {
|
||||
// latch when newDepth goes negative - once we step out of the entry context we can't return
|
||||
@ -1104,7 +1109,16 @@ func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config ATNC
|
||||
// left-recursion elimination. For efficiency, also check if
|
||||
// the context has an empty stack case. If so, it would mean
|
||||
// global FOLLOW so we can't perform optimization
|
||||
if startLoop, ok := _p.(StarLoopEntryState); !ok || !startLoop.precedenceRuleDecision || config.GetContext().isEmpty() || config.GetContext().hasEmptyPath() {
|
||||
if _p.GetStateType() != ATNStateStarLoopEntry {
|
||||
return false
|
||||
}
|
||||
startLoop, ok := _p.(*StarLoopEntryState)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if !startLoop.precedenceRuleDecision ||
|
||||
config.GetContext().isEmpty() ||
|
||||
config.GetContext().hasEmptyPath() {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -1117,8 +1131,8 @@ func (p *ParserATNSimulator) canDropLoopEntryEdgeInLeftRecursiveRule(config ATNC
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
decisionStartState := _p.(BlockStartState).GetTransitions()[0].getTarget().(BlockStartState)
|
||||
x := _p.GetTransitions()[0].getTarget()
|
||||
decisionStartState := x.(BlockStartState)
|
||||
blockEndStateNum := decisionStartState.getEndState().stateNumber
|
||||
blockEndState := p.atn.states[blockEndStateNum].(*BlockEndState)
|
||||
|
||||
@ -1355,13 +1369,12 @@ func (p *ParserATNSimulator) GetTokenName(t int) string {
|
||||
return "EOF"
|
||||
}
|
||||
|
||||
if p.parser != nil && p.parser.GetLiteralNames() != nil {
|
||||
if t >= len(p.parser.GetLiteralNames()) {
|
||||
fmt.Println(strconv.Itoa(t) + " ttype out of range: " + strings.Join(p.parser.GetLiteralNames(), ","))
|
||||
// fmt.Println(p.parser.GetInputStream().(TokenStream).GetAllText()) // p seems incorrect
|
||||
} else {
|
||||
return p.parser.GetLiteralNames()[t] + "<" + strconv.Itoa(t) + ">"
|
||||
}
|
||||
if p.parser != nil && p.parser.GetLiteralNames() != nil && t < len(p.parser.GetLiteralNames()) {
|
||||
return p.parser.GetLiteralNames()[t] + "<" + strconv.Itoa(t) + ">"
|
||||
}
|
||||
|
||||
if p.parser != nil && p.parser.GetLiteralNames() != nil && t < len(p.parser.GetSymbolicNames()) {
|
||||
return p.parser.GetSymbolicNames()[t] + "<" + strconv.Itoa(t) + ">"
|
||||
}
|
||||
|
||||
return strconv.Itoa(t)
|
||||
@ -1372,9 +1385,9 @@ func (p *ParserATNSimulator) getLookaheadName(input TokenStream) string {
|
||||
}
|
||||
|
||||
// Used for debugging in AdaptivePredict around execATN but I cut
|
||||
// it out for clarity now that alg. works well. We can leave p
|
||||
// "dead" code for a bit.
|
||||
//
|
||||
// it out for clarity now that alg. works well. We can leave p
|
||||
// "dead" code for a bit.
|
||||
func (p *ParserATNSimulator) dumpDeadEndConfigs(nvae *NoViableAltException) {
|
||||
|
||||
panic("Not implemented")
|
||||
@ -1421,7 +1434,6 @@ func (p *ParserATNSimulator) getUniqueAlt(configs ATNConfigSet) int {
|
||||
return alt
|
||||
}
|
||||
|
||||
//
|
||||
// Add an edge to the DFA, if possible. This method calls
|
||||
// {@link //addDFAState} to ensure the {@code to} state is present in the
|
||||
// DFA. If {@code from} is {@code nil}, or if {@code t} is outside the
|
||||
@ -1440,7 +1452,6 @@ func (p *ParserATNSimulator) getUniqueAlt(configs ATNConfigSet) int {
|
||||
// @return If {@code to} is {@code nil}, p method returns {@code nil}
|
||||
// otherwise p method returns the result of calling {@link //addDFAState}
|
||||
// on {@code to}
|
||||
//
|
||||
func (p *ParserATNSimulator) addDFAEdge(dfa *DFA, from *DFAState, t int, to *DFAState) *DFAState {
|
||||
if ParserATNSimulatorDebug {
|
||||
fmt.Println("EDGE " + from.String() + " -> " + to.String() + " upon " + p.GetTokenName(t))
|
||||
@ -1472,7 +1483,6 @@ func (p *ParserATNSimulator) addDFAEdge(dfa *DFA, from *DFAState, t int, to *DFA
|
||||
return to
|
||||
}
|
||||
|
||||
//
|
||||
// Add state {@code D} to the DFA if it is not already present, and return
|
||||
// the actual instance stored in the DFA. If a state equivalent to {@code D}
|
||||
// is already in the DFA, the existing state is returned. Otherwise p
|
||||
@ -1486,25 +1496,30 @@ func (p *ParserATNSimulator) addDFAEdge(dfa *DFA, from *DFAState, t int, to *DFA
|
||||
// @return The state stored in the DFA. This will be either the existing
|
||||
// state if {@code D} is already in the DFA, or {@code D} itself if the
|
||||
// state was not already present.
|
||||
//
|
||||
func (p *ParserATNSimulator) addDFAState(dfa *DFA, d *DFAState) *DFAState {
|
||||
if d == ATNSimulatorError {
|
||||
return d
|
||||
}
|
||||
hash := d.hash()
|
||||
existing, ok := dfa.getState(hash)
|
||||
if ok {
|
||||
existing, present := dfa.states.Get(d)
|
||||
if present {
|
||||
if ParserATNSimulatorTraceATNSim {
|
||||
fmt.Print("addDFAState " + d.String() + " exists")
|
||||
}
|
||||
return existing
|
||||
}
|
||||
d.stateNumber = dfa.numStates()
|
||||
|
||||
// The state was not present, so update it with configs
|
||||
//
|
||||
d.stateNumber = dfa.states.Len()
|
||||
if !d.configs.ReadOnly() {
|
||||
d.configs.OptimizeConfigs(p.BaseATNSimulator)
|
||||
d.configs.SetReadOnly(true)
|
||||
}
|
||||
dfa.setState(hash, d)
|
||||
if ParserATNSimulatorDebug {
|
||||
fmt.Println("adding NewDFA state: " + d.String())
|
||||
dfa.states.Put(d)
|
||||
if ParserATNSimulatorTraceATNSim {
|
||||
fmt.Println("addDFAState new " + d.String())
|
||||
}
|
||||
|
||||
return d
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -340,7 +340,7 @@ func (prc *BaseParserRuleContext) String(ruleNames []string, stop RuleContext) s
|
||||
return s
|
||||
}
|
||||
|
||||
var RuleContextEmpty = NewBaseParserRuleContext(nil, -1)
|
||||
var ParserRuleContextEmpty = NewBaseParserRuleContext(nil, -1)
|
||||
|
||||
type InterpreterRuleContext interface {
|
||||
ParserRuleContext
|
@ -1,10 +1,12 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
package antlr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"golang.org/x/exp/slices"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@ -26,10 +28,10 @@ var (
|
||||
)
|
||||
|
||||
type PredictionContext interface {
|
||||
hash() int
|
||||
Hash() int
|
||||
Equals(interface{}) bool
|
||||
GetParent(int) PredictionContext
|
||||
getReturnState(int) int
|
||||
equals(PredictionContext) bool
|
||||
length() int
|
||||
isEmpty() bool
|
||||
hasEmptyPath() bool
|
||||
@ -53,7 +55,7 @@ func (b *BasePredictionContext) isEmpty() bool {
|
||||
|
||||
func calculateHash(parent PredictionContext, returnState int) int {
|
||||
h := murmurInit(1)
|
||||
h = murmurUpdate(h, parent.hash())
|
||||
h = murmurUpdate(h, parent.Hash())
|
||||
h = murmurUpdate(h, returnState)
|
||||
return murmurFinish(h, 2)
|
||||
}
|
||||
@ -86,7 +88,6 @@ func NewPredictionContextCache() *PredictionContextCache {
|
||||
// Add a context to the cache and return it. If the context already exists,
|
||||
// return that one instead and do not add a Newcontext to the cache.
|
||||
// Protect shared cache from unsafe thread access.
|
||||
//
|
||||
func (p *PredictionContextCache) add(ctx PredictionContext) PredictionContext {
|
||||
if ctx == BasePredictionContextEMPTY {
|
||||
return BasePredictionContextEMPTY
|
||||
@ -160,28 +161,28 @@ func (b *BaseSingletonPredictionContext) hasEmptyPath() bool {
|
||||
return b.returnState == BasePredictionContextEmptyReturnState
|
||||
}
|
||||
|
||||
func (b *BaseSingletonPredictionContext) equals(other PredictionContext) bool {
|
||||
func (b *BaseSingletonPredictionContext) Hash() int {
|
||||
return b.cachedHash
|
||||
}
|
||||
|
||||
func (b *BaseSingletonPredictionContext) Equals(other interface{}) bool {
|
||||
if b == other {
|
||||
return true
|
||||
} else if _, ok := other.(*BaseSingletonPredictionContext); !ok {
|
||||
}
|
||||
if _, ok := other.(*BaseSingletonPredictionContext); !ok {
|
||||
return false
|
||||
} else if b.hash() != other.hash() {
|
||||
return false // can't be same if hash is different
|
||||
}
|
||||
|
||||
otherP := other.(*BaseSingletonPredictionContext)
|
||||
|
||||
if b.returnState != other.getReturnState(0) {
|
||||
if b.returnState != otherP.getReturnState(0) {
|
||||
return false
|
||||
} else if b.parentCtx == nil {
|
||||
}
|
||||
if b.parentCtx == nil {
|
||||
return otherP.parentCtx == nil
|
||||
}
|
||||
|
||||
return b.parentCtx.equals(otherP.parentCtx)
|
||||
}
|
||||
|
||||
func (b *BaseSingletonPredictionContext) hash() int {
|
||||
return b.cachedHash
|
||||
return b.parentCtx.Equals(otherP.parentCtx)
|
||||
}
|
||||
|
||||
func (b *BaseSingletonPredictionContext) String() string {
|
||||
@ -215,7 +216,7 @@ func NewEmptyPredictionContext() *EmptyPredictionContext {
|
||||
p := new(EmptyPredictionContext)
|
||||
|
||||
p.BaseSingletonPredictionContext = NewBaseSingletonPredictionContext(nil, BasePredictionContextEmptyReturnState)
|
||||
|
||||
p.cachedHash = calculateEmptyHash()
|
||||
return p
|
||||
}
|
||||
|
||||
@ -231,7 +232,11 @@ func (e *EmptyPredictionContext) getReturnState(index int) int {
|
||||
return e.returnState
|
||||
}
|
||||
|
||||
func (e *EmptyPredictionContext) equals(other PredictionContext) bool {
|
||||
func (e *EmptyPredictionContext) Hash() int {
|
||||
return e.cachedHash
|
||||
}
|
||||
|
||||
func (e *EmptyPredictionContext) Equals(other interface{}) bool {
|
||||
return e == other
|
||||
}
|
||||
|
||||
@ -254,7 +259,7 @@ func NewArrayPredictionContext(parents []PredictionContext, returnStates []int)
|
||||
hash := murmurInit(1)
|
||||
|
||||
for _, parent := range parents {
|
||||
hash = murmurUpdate(hash, parent.hash())
|
||||
hash = murmurUpdate(hash, parent.Hash())
|
||||
}
|
||||
|
||||
for _, returnState := range returnStates {
|
||||
@ -298,18 +303,31 @@ func (a *ArrayPredictionContext) getReturnState(index int) int {
|
||||
return a.returnStates[index]
|
||||
}
|
||||
|
||||
func (a *ArrayPredictionContext) equals(other PredictionContext) bool {
|
||||
if _, ok := other.(*ArrayPredictionContext); !ok {
|
||||
return false
|
||||
} else if a.cachedHash != other.hash() {
|
||||
return false // can't be same if hash is different
|
||||
} else {
|
||||
otherP := other.(*ArrayPredictionContext)
|
||||
return &a.returnStates == &otherP.returnStates && &a.parents == &otherP.parents
|
||||
// Equals is the default comparison function for ArrayPredictionContext when no specialized
|
||||
// implementation is needed for a collection
|
||||
func (a *ArrayPredictionContext) Equals(o interface{}) bool {
|
||||
if a == o {
|
||||
return true
|
||||
}
|
||||
other, ok := o.(*ArrayPredictionContext)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if a.cachedHash != other.Hash() {
|
||||
return false // can't be same if hash is different
|
||||
}
|
||||
|
||||
// Must compare the actual array elements and not just the array address
|
||||
//
|
||||
return slices.Equal(a.returnStates, other.returnStates) &&
|
||||
slices.EqualFunc(a.parents, other.parents, func(x, y PredictionContext) bool {
|
||||
return x.Equals(y)
|
||||
})
|
||||
}
|
||||
|
||||
func (a *ArrayPredictionContext) hash() int {
|
||||
// Hash is the default hash function for ArrayPredictionContext when no specialized
|
||||
// implementation is needed for a collection
|
||||
func (a *ArrayPredictionContext) Hash() int {
|
||||
return a.BasePredictionContext.cachedHash
|
||||
}
|
||||
|
||||
@ -343,11 +361,11 @@ func (a *ArrayPredictionContext) String() string {
|
||||
// /
|
||||
func predictionContextFromRuleContext(a *ATN, outerContext RuleContext) PredictionContext {
|
||||
if outerContext == nil {
|
||||
outerContext = RuleContextEmpty
|
||||
outerContext = ParserRuleContextEmpty
|
||||
}
|
||||
// if we are in RuleContext of start rule, s, then BasePredictionContext
|
||||
// is EMPTY. Nobody called us. (if we are empty, return empty)
|
||||
if outerContext.GetParent() == nil || outerContext == RuleContextEmpty {
|
||||
if outerContext.GetParent() == nil || outerContext == ParserRuleContextEmpty {
|
||||
return BasePredictionContextEMPTY
|
||||
}
|
||||
// If we have a parent, convert it to a BasePredictionContext graph
|
||||
@ -359,11 +377,20 @@ func predictionContextFromRuleContext(a *ATN, outerContext RuleContext) Predicti
|
||||
}
|
||||
|
||||
func merge(a, b PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext {
|
||||
// share same graph if both same
|
||||
if a == b {
|
||||
|
||||
// Share same graph if both same
|
||||
//
|
||||
if a == b || a.Equals(b) {
|
||||
return a
|
||||
}
|
||||
|
||||
// In Java, EmptyPredictionContext inherits from SingletonPredictionContext, and so the test
|
||||
// in java for SingletonPredictionContext will succeed and a new ArrayPredictionContext will be created
|
||||
// from it.
|
||||
// In go, EmptyPredictionContext does not equate to SingletonPredictionContext and so that conversion
|
||||
// will fail. We need to test for both Empty and Singleton and create an ArrayPredictionContext from
|
||||
// either of them.
|
||||
|
||||
ac, ok1 := a.(*BaseSingletonPredictionContext)
|
||||
bc, ok2 := b.(*BaseSingletonPredictionContext)
|
||||
|
||||
@ -380,17 +407,32 @@ func merge(a, b PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict)
|
||||
return b
|
||||
}
|
||||
}
|
||||
// convert singleton so both are arrays to normalize
|
||||
if _, ok := a.(*BaseSingletonPredictionContext); ok {
|
||||
a = NewArrayPredictionContext([]PredictionContext{a.GetParent(0)}, []int{a.getReturnState(0)})
|
||||
|
||||
// Convert Singleton or Empty so both are arrays to normalize - We should not use the existing parameters
|
||||
// here.
|
||||
//
|
||||
// TODO: I think that maybe the Prediction Context structs should be redone as there is a chance we will see this mess again - maybe redo the logic here
|
||||
|
||||
var arp, arb *ArrayPredictionContext
|
||||
var ok bool
|
||||
if arp, ok = a.(*ArrayPredictionContext); ok {
|
||||
} else if _, ok = a.(*BaseSingletonPredictionContext); ok {
|
||||
arp = NewArrayPredictionContext([]PredictionContext{a.GetParent(0)}, []int{a.getReturnState(0)})
|
||||
} else if _, ok = a.(*EmptyPredictionContext); ok {
|
||||
arp = NewArrayPredictionContext([]PredictionContext{}, []int{})
|
||||
}
|
||||
if _, ok := b.(*BaseSingletonPredictionContext); ok {
|
||||
b = NewArrayPredictionContext([]PredictionContext{b.GetParent(0)}, []int{b.getReturnState(0)})
|
||||
|
||||
if arb, ok = b.(*ArrayPredictionContext); ok {
|
||||
} else if _, ok = b.(*BaseSingletonPredictionContext); ok {
|
||||
arb = NewArrayPredictionContext([]PredictionContext{b.GetParent(0)}, []int{b.getReturnState(0)})
|
||||
} else if _, ok = b.(*EmptyPredictionContext); ok {
|
||||
arb = NewArrayPredictionContext([]PredictionContext{}, []int{})
|
||||
}
|
||||
return mergeArrays(a.(*ArrayPredictionContext), b.(*ArrayPredictionContext), rootIsWildcard, mergeCache)
|
||||
|
||||
// Both arp and arb
|
||||
return mergeArrays(arp, arb, rootIsWildcard, mergeCache)
|
||||
}
|
||||
|
||||
//
|
||||
// Merge two {@link SingletonBasePredictionContext} instances.
|
||||
//
|
||||
// <p>Stack tops equal, parents merge is same return left graph.<br>
|
||||
@ -423,11 +465,11 @@ func merge(a, b PredictionContext, rootIsWildcard bool, mergeCache *DoubleDict)
|
||||
// /
|
||||
func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext {
|
||||
if mergeCache != nil {
|
||||
previous := mergeCache.Get(a.hash(), b.hash())
|
||||
previous := mergeCache.Get(a.Hash(), b.Hash())
|
||||
if previous != nil {
|
||||
return previous.(PredictionContext)
|
||||
}
|
||||
previous = mergeCache.Get(b.hash(), a.hash())
|
||||
previous = mergeCache.Get(b.Hash(), a.Hash())
|
||||
if previous != nil {
|
||||
return previous.(PredictionContext)
|
||||
}
|
||||
@ -436,7 +478,7 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool,
|
||||
rootMerge := mergeRoot(a, b, rootIsWildcard)
|
||||
if rootMerge != nil {
|
||||
if mergeCache != nil {
|
||||
mergeCache.set(a.hash(), b.hash(), rootMerge)
|
||||
mergeCache.set(a.Hash(), b.Hash(), rootMerge)
|
||||
}
|
||||
return rootMerge
|
||||
}
|
||||
@ -456,7 +498,7 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool,
|
||||
// Newjoined parent so create Newsingleton pointing to it, a'
|
||||
spc := SingletonBasePredictionContextCreate(parent, a.returnState)
|
||||
if mergeCache != nil {
|
||||
mergeCache.set(a.hash(), b.hash(), spc)
|
||||
mergeCache.set(a.Hash(), b.Hash(), spc)
|
||||
}
|
||||
return spc
|
||||
}
|
||||
@ -478,7 +520,7 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool,
|
||||
parents := []PredictionContext{singleParent, singleParent}
|
||||
apc := NewArrayPredictionContext(parents, payloads)
|
||||
if mergeCache != nil {
|
||||
mergeCache.set(a.hash(), b.hash(), apc)
|
||||
mergeCache.set(a.Hash(), b.Hash(), apc)
|
||||
}
|
||||
return apc
|
||||
}
|
||||
@ -494,12 +536,11 @@ func mergeSingletons(a, b *BaseSingletonPredictionContext, rootIsWildcard bool,
|
||||
}
|
||||
apc := NewArrayPredictionContext(parents, payloads)
|
||||
if mergeCache != nil {
|
||||
mergeCache.set(a.hash(), b.hash(), apc)
|
||||
mergeCache.set(a.Hash(), b.Hash(), apc)
|
||||
}
|
||||
return apc
|
||||
}
|
||||
|
||||
//
|
||||
// Handle case where at least one of {@code a} or {@code b} is
|
||||
// {@link //EMPTY}. In the following diagrams, the symbol {@code $} is used
|
||||
// to represent {@link //EMPTY}.
|
||||
@ -561,7 +602,6 @@ func mergeRoot(a, b SingletonPredictionContext, rootIsWildcard bool) PredictionC
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// Merge two {@link ArrayBasePredictionContext} instances.
|
||||
//
|
||||
// <p>Different tops, different parents.<br>
|
||||
@ -583,12 +623,18 @@ func mergeRoot(a, b SingletonPredictionContext, rootIsWildcard bool) PredictionC
|
||||
// /
|
||||
func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache *DoubleDict) PredictionContext {
|
||||
if mergeCache != nil {
|
||||
previous := mergeCache.Get(a.hash(), b.hash())
|
||||
previous := mergeCache.Get(a.Hash(), b.Hash())
|
||||
if previous != nil {
|
||||
if ParserATNSimulatorTraceATNSim {
|
||||
fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> previous")
|
||||
}
|
||||
return previous.(PredictionContext)
|
||||
}
|
||||
previous = mergeCache.Get(b.hash(), a.hash())
|
||||
previous = mergeCache.Get(b.Hash(), a.Hash())
|
||||
if previous != nil {
|
||||
if ParserATNSimulatorTraceATNSim {
|
||||
fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> previous")
|
||||
}
|
||||
return previous.(PredictionContext)
|
||||
}
|
||||
}
|
||||
@ -608,7 +654,7 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache *
|
||||
payload := a.returnStates[i]
|
||||
// $+$ = $
|
||||
bothDollars := payload == BasePredictionContextEmptyReturnState && aParent == nil && bParent == nil
|
||||
axAX := (aParent != nil && bParent != nil && aParent == bParent) // ax+ax
|
||||
axAX := aParent != nil && bParent != nil && aParent == bParent // ax+ax
|
||||
// ->
|
||||
// ax
|
||||
if bothDollars || axAX {
|
||||
@ -651,7 +697,7 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache *
|
||||
if k == 1 { // for just one merged element, return singleton top
|
||||
pc := SingletonBasePredictionContextCreate(mergedParents[0], mergedReturnStates[0])
|
||||
if mergeCache != nil {
|
||||
mergeCache.set(a.hash(), b.hash(), pc)
|
||||
mergeCache.set(a.Hash(), b.Hash(), pc)
|
||||
}
|
||||
return pc
|
||||
}
|
||||
@ -663,27 +709,36 @@ func mergeArrays(a, b *ArrayPredictionContext, rootIsWildcard bool, mergeCache *
|
||||
|
||||
// if we created same array as a or b, return that instead
|
||||
// TODO: track whether this is possible above during merge sort for speed
|
||||
// TODO: In go, I do not think we can just do M == xx as M is a brand new allocation. This could be causing allocation problems
|
||||
if M == a {
|
||||
if mergeCache != nil {
|
||||
mergeCache.set(a.hash(), b.hash(), a)
|
||||
mergeCache.set(a.Hash(), b.Hash(), a)
|
||||
}
|
||||
if ParserATNSimulatorTraceATNSim {
|
||||
fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> a")
|
||||
}
|
||||
return a
|
||||
}
|
||||
if M == b {
|
||||
if mergeCache != nil {
|
||||
mergeCache.set(a.hash(), b.hash(), b)
|
||||
mergeCache.set(a.Hash(), b.Hash(), b)
|
||||
}
|
||||
if ParserATNSimulatorTraceATNSim {
|
||||
fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> b")
|
||||
}
|
||||
return b
|
||||
}
|
||||
combineCommonParents(mergedParents)
|
||||
|
||||
if mergeCache != nil {
|
||||
mergeCache.set(a.hash(), b.hash(), M)
|
||||
mergeCache.set(a.Hash(), b.Hash(), M)
|
||||
}
|
||||
if ParserATNSimulatorTraceATNSim {
|
||||
fmt.Println("mergeArrays a=" + a.String() + ",b=" + b.String() + " -> " + M.String())
|
||||
}
|
||||
return M
|
||||
}
|
||||
|
||||
//
|
||||
// Make pass over all <em>M</em> {@code parents} merge any {@code equals()}
|
||||
// ones.
|
||||
// /
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -70,7 +70,6 @@ const (
|
||||
PredictionModeLLExactAmbigDetection = 2
|
||||
)
|
||||
|
||||
//
|
||||
// Computes the SLL prediction termination condition.
|
||||
//
|
||||
// <p>
|
||||
@ -108,9 +107,9 @@ const (
|
||||
// The single-alt-state thing lets prediction continue upon rules like
|
||||
// (otherwise, it would admit defeat too soon):</p>
|
||||
//
|
||||
// <p>{@code [12|1|[], 6|2|[], 12|2|[]]. s : (ID | ID ID?) '' }</p>
|
||||
// <p>{@code [12|1|[], 6|2|[], 12|2|[]]. s : (ID | ID ID?) ” }</p>
|
||||
//
|
||||
// <p>When the ATN simulation reaches the state before {@code ''}, it has a
|
||||
// <p>When the ATN simulation reaches the state before {@code ”}, it has a
|
||||
// DFA state that looks like: {@code [12|1|[], 6|2|[], 12|2|[]]}. Naturally
|
||||
// {@code 12|1|[]} and {@code 12|2|[]} conflict, but we cannot stop
|
||||
// processing this node because alternative to has another way to continue,
|
||||
@ -152,16 +151,15 @@ const (
|
||||
//
|
||||
// <p>Before testing these configurations against others, we have to merge
|
||||
// {@code x} and {@code x'} (without modifying the existing configurations).
|
||||
// For example, we test {@code (x+x')==x''} when looking for conflicts in
|
||||
// For example, we test {@code (x+x')==x”} when looking for conflicts in
|
||||
// the following configurations.</p>
|
||||
//
|
||||
// <p>{@code (s, 1, x, {}), (s, 1, x', {p}), (s, 2, x'', {})}</p>
|
||||
// <p>{@code (s, 1, x, {}), (s, 1, x', {p}), (s, 2, x”, {})}</p>
|
||||
//
|
||||
// <p>If the configuration set has predicates (as indicated by
|
||||
// {@link ATNConfigSet//hasSemanticContext}), this algorithm makes a copy of
|
||||
// the configurations to strip out all of the predicates so that a standard
|
||||
// {@link ATNConfigSet} will merge everything ignoring predicates.</p>
|
||||
//
|
||||
func PredictionModehasSLLConflictTerminatingPrediction(mode int, configs ATNConfigSet) bool {
|
||||
// Configs in rule stop states indicate reaching the end of the decision
|
||||
// rule (local context) or end of start rule (full context). If all
|
||||
@ -229,7 +227,6 @@ func PredictionModeallConfigsInRuleStopStates(configs ATNConfigSet) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
//
|
||||
// Full LL prediction termination.
|
||||
//
|
||||
// <p>Can we stop looking ahead during ATN simulation or is there some
|
||||
@ -334,7 +331,7 @@ func PredictionModeallConfigsInRuleStopStates(configs ATNConfigSet) bool {
|
||||
// </li>
|
||||
//
|
||||
// <li>{@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 1, y)},
|
||||
// {@code (s', 2, y)}, {@code (s'', 1, z)} yields non-conflicting set
|
||||
// {@code (s', 2, y)}, {@code (s”, 1, z)} yields non-conflicting set
|
||||
// {@code {1}} U conflicting sets {@code min({1,2})} U {@code min({1,2})} =
|
||||
// {@code {1}} => stop and predict 1</li>
|
||||
//
|
||||
@ -369,31 +366,26 @@ func PredictionModeallConfigsInRuleStopStates(configs ATNConfigSet) bool {
|
||||
// two or one and three so we keep going. We can only stop prediction when
|
||||
// we need exact ambiguity detection when the sets look like
|
||||
// {@code A={{1,2}}} or {@code {{1,2},{1,2}}}, etc...</p>
|
||||
//
|
||||
func PredictionModeresolvesToJustOneViableAlt(altsets []*BitSet) int {
|
||||
return PredictionModegetSingleViableAlt(altsets)
|
||||
}
|
||||
|
||||
//
|
||||
// Determines if every alternative subset in {@code altsets} contains more
|
||||
// than one alternative.
|
||||
//
|
||||
// @param altsets a collection of alternative subsets
|
||||
// @return {@code true} if every {@link BitSet} in {@code altsets} has
|
||||
// {@link BitSet//cardinality cardinality} > 1, otherwise {@code false}
|
||||
//
|
||||
func PredictionModeallSubsetsConflict(altsets []*BitSet) bool {
|
||||
return !PredictionModehasNonConflictingAltSet(altsets)
|
||||
}
|
||||
|
||||
//
|
||||
// Determines if any single alternative subset in {@code altsets} contains
|
||||
// exactly one alternative.
|
||||
//
|
||||
// @param altsets a collection of alternative subsets
|
||||
// @return {@code true} if {@code altsets} contains a {@link BitSet} with
|
||||
// {@link BitSet//cardinality cardinality} 1, otherwise {@code false}
|
||||
//
|
||||
func PredictionModehasNonConflictingAltSet(altsets []*BitSet) bool {
|
||||
for i := 0; i < len(altsets); i++ {
|
||||
alts := altsets[i]
|
||||
@ -404,14 +396,12 @@ func PredictionModehasNonConflictingAltSet(altsets []*BitSet) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
//
|
||||
// Determines if any single alternative subset in {@code altsets} contains
|
||||
// more than one alternative.
|
||||
//
|
||||
// @param altsets a collection of alternative subsets
|
||||
// @return {@code true} if {@code altsets} contains a {@link BitSet} with
|
||||
// {@link BitSet//cardinality cardinality} > 1, otherwise {@code false}
|
||||
//
|
||||
func PredictionModehasConflictingAltSet(altsets []*BitSet) bool {
|
||||
for i := 0; i < len(altsets); i++ {
|
||||
alts := altsets[i]
|
||||
@ -422,13 +412,11 @@ func PredictionModehasConflictingAltSet(altsets []*BitSet) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
//
|
||||
// Determines if every alternative subset in {@code altsets} is equivalent.
|
||||
//
|
||||
// @param altsets a collection of alternative subsets
|
||||
// @return {@code true} if every member of {@code altsets} is equal to the
|
||||
// others, otherwise {@code false}
|
||||
//
|
||||
func PredictionModeallSubsetsEqual(altsets []*BitSet) bool {
|
||||
var first *BitSet
|
||||
|
||||
@ -444,13 +432,11 @@ func PredictionModeallSubsetsEqual(altsets []*BitSet) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
//
|
||||
// Returns the unique alternative predicted by all alternative subsets in
|
||||
// {@code altsets}. If no such alternative exists, this method returns
|
||||
// {@link ATN//INVALID_ALT_NUMBER}.
|
||||
//
|
||||
// @param altsets a collection of alternative subsets
|
||||
//
|
||||
func PredictionModegetUniqueAlt(altsets []*BitSet) int {
|
||||
all := PredictionModeGetAlts(altsets)
|
||||
if all.length() == 1 {
|
||||
@ -466,7 +452,6 @@ func PredictionModegetUniqueAlt(altsets []*BitSet) int {
|
||||
//
|
||||
// @param altsets a collection of alternative subsets
|
||||
// @return the set of represented alternatives in {@code altsets}
|
||||
//
|
||||
func PredictionModeGetAlts(altsets []*BitSet) *BitSet {
|
||||
all := NewBitSet()
|
||||
for _, alts := range altsets {
|
||||
@ -475,44 +460,35 @@ func PredictionModeGetAlts(altsets []*BitSet) *BitSet {
|
||||
return all
|
||||
}
|
||||
|
||||
//
|
||||
// This func gets the conflicting alt subsets from a configuration set.
|
||||
// PredictionModegetConflictingAltSubsets gets the conflicting alt subsets from a configuration set.
|
||||
// For each configuration {@code c} in {@code configs}:
|
||||
//
|
||||
// <pre>
|
||||
// map[c] U= c.{@link ATNConfig//alt alt} // map hash/equals uses s and x, not
|
||||
// alt and not pred
|
||||
// </pre>
|
||||
//
|
||||
func PredictionModegetConflictingAltSubsets(configs ATNConfigSet) []*BitSet {
|
||||
configToAlts := make(map[int]*BitSet)
|
||||
configToAlts := NewJMap[ATNConfig, *BitSet, *ATNAltConfigComparator[ATNConfig]](atnAltCfgEqInst)
|
||||
|
||||
for _, c := range configs.GetItems() {
|
||||
key := 31 * c.GetState().GetStateNumber() + c.GetContext().hash()
|
||||
|
||||
alts, ok := configToAlts[key]
|
||||
alts, ok := configToAlts.Get(c)
|
||||
if !ok {
|
||||
alts = NewBitSet()
|
||||
configToAlts[key] = alts
|
||||
configToAlts.Put(c, alts)
|
||||
}
|
||||
alts.add(c.GetAlt())
|
||||
}
|
||||
|
||||
values := make([]*BitSet, 0, 10)
|
||||
for _, v := range configToAlts {
|
||||
values = append(values, v)
|
||||
}
|
||||
return values
|
||||
return configToAlts.Values()
|
||||
}
|
||||
|
||||
//
|
||||
// Get a map from state to alt subset from a configuration set. For each
|
||||
// PredictionModeGetStateToAltMap gets a map from state to alt subset from a configuration set. For each
|
||||
// configuration {@code c} in {@code configs}:
|
||||
//
|
||||
// <pre>
|
||||
// map[c.{@link ATNConfig//state state}] U= c.{@link ATNConfig//alt alt}
|
||||
// </pre>
|
||||
//
|
||||
func PredictionModeGetStateToAltMap(configs ATNConfigSet) *AltDict {
|
||||
m := NewAltDict()
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -49,7 +49,7 @@ var tokenTypeMapCache = make(map[string]int)
|
||||
var ruleIndexMapCache = make(map[string]int)
|
||||
|
||||
func (b *BaseRecognizer) checkVersion(toolVersion string) {
|
||||
runtimeVersion := "4.10.1"
|
||||
runtimeVersion := "4.12.0"
|
||||
if runtimeVersion != toolVersion {
|
||||
fmt.Println("ANTLR runtime and generated code versions disagree: " + runtimeVersion + "!=" + toolVersion)
|
||||
}
|
||||
@ -108,7 +108,6 @@ func (b *BaseRecognizer) SetState(v int) {
|
||||
// Get a map from rule names to rule indexes.
|
||||
//
|
||||
// <p>Used for XPath and tree pattern compilation.</p>
|
||||
//
|
||||
func (b *BaseRecognizer) GetRuleIndexMap() map[string]int {
|
||||
|
||||
panic("Method not defined!")
|
||||
@ -171,18 +170,18 @@ func (b *BaseRecognizer) GetErrorHeader(e RecognitionException) string {
|
||||
}
|
||||
|
||||
// How should a token be displayed in an error message? The default
|
||||
// is to display just the text, but during development you might
|
||||
// want to have a lot of information spit out. Override in that case
|
||||
// to use t.String() (which, for CommonToken, dumps everything about
|
||||
// the token). This is better than forcing you to override a method in
|
||||
// your token objects because you don't have to go modify your lexer
|
||||
// so that it creates a NewJava type.
|
||||
//
|
||||
// is to display just the text, but during development you might
|
||||
// want to have a lot of information spit out. Override in that case
|
||||
// to use t.String() (which, for CommonToken, dumps everything about
|
||||
// the token). This is better than forcing you to override a method in
|
||||
// your token objects because you don't have to go modify your lexer
|
||||
// so that it creates a NewJava type.
|
||||
//
|
||||
// @deprecated This method is not called by the ANTLR 4 Runtime. Specific
|
||||
// implementations of {@link ANTLRErrorStrategy} may provide a similar
|
||||
// feature when necessary. For example, see
|
||||
// {@link DefaultErrorStrategy//GetTokenErrorDisplay}.
|
||||
//
|
||||
func (b *BaseRecognizer) GetTokenErrorDisplay(t Token) string {
|
||||
if t == nil {
|
||||
return "<no token>"
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -18,12 +18,12 @@ import (
|
||||
//
|
||||
|
||||
type SemanticContext interface {
|
||||
comparable
|
||||
Equals(other Collectable[SemanticContext]) bool
|
||||
Hash() int
|
||||
|
||||
evaluate(parser Recognizer, outerContext RuleContext) bool
|
||||
evalPrecedence(parser Recognizer, outerContext RuleContext) SemanticContext
|
||||
|
||||
hash() int
|
||||
String() string
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ func NewPredicate(ruleIndex, predIndex int, isCtxDependent bool) *Predicate {
|
||||
//The default {@link SemanticContext}, which is semantically equivalent to
|
||||
//a predicate of the form {@code {true}?}.
|
||||
|
||||
var SemanticContextNone SemanticContext = NewPredicate(-1, -1, false)
|
||||
var SemanticContextNone = NewPredicate(-1, -1, false)
|
||||
|
||||
func (p *Predicate) evalPrecedence(parser Recognizer, outerContext RuleContext) SemanticContext {
|
||||
return p
|
||||
@ -95,7 +95,7 @@ func (p *Predicate) evaluate(parser Recognizer, outerContext RuleContext) bool {
|
||||
return parser.Sempred(localctx, p.ruleIndex, p.predIndex)
|
||||
}
|
||||
|
||||
func (p *Predicate) equals(other interface{}) bool {
|
||||
func (p *Predicate) Equals(other Collectable[SemanticContext]) bool {
|
||||
if p == other {
|
||||
return true
|
||||
} else if _, ok := other.(*Predicate); !ok {
|
||||
@ -107,7 +107,7 @@ func (p *Predicate) equals(other interface{}) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Predicate) hash() int {
|
||||
func (p *Predicate) Hash() int {
|
||||
h := murmurInit(0)
|
||||
h = murmurUpdate(h, p.ruleIndex)
|
||||
h = murmurUpdate(h, p.predIndex)
|
||||
@ -151,17 +151,22 @@ func (p *PrecedencePredicate) compareTo(other *PrecedencePredicate) int {
|
||||
return p.precedence - other.precedence
|
||||
}
|
||||
|
||||
func (p *PrecedencePredicate) equals(other interface{}) bool {
|
||||
if p == other {
|
||||
return true
|
||||
} else if _, ok := other.(*PrecedencePredicate); !ok {
|
||||
func (p *PrecedencePredicate) Equals(other Collectable[SemanticContext]) bool {
|
||||
|
||||
var op *PrecedencePredicate
|
||||
var ok bool
|
||||
if op, ok = other.(*PrecedencePredicate); !ok {
|
||||
return false
|
||||
} else {
|
||||
return p.precedence == other.(*PrecedencePredicate).precedence
|
||||
}
|
||||
|
||||
if p == op {
|
||||
return true
|
||||
}
|
||||
|
||||
return p.precedence == other.(*PrecedencePredicate).precedence
|
||||
}
|
||||
|
||||
func (p *PrecedencePredicate) hash() int {
|
||||
func (p *PrecedencePredicate) Hash() int {
|
||||
h := uint32(1)
|
||||
h = 31*h + uint32(p.precedence)
|
||||
return int(h)
|
||||
@ -171,10 +176,10 @@ func (p *PrecedencePredicate) String() string {
|
||||
return "{" + strconv.Itoa(p.precedence) + ">=prec}?"
|
||||
}
|
||||
|
||||
func PrecedencePredicatefilterPrecedencePredicates(set Set) []*PrecedencePredicate {
|
||||
func PrecedencePredicatefilterPrecedencePredicates(set *JStore[SemanticContext, Comparator[SemanticContext]]) []*PrecedencePredicate {
|
||||
result := make([]*PrecedencePredicate, 0)
|
||||
|
||||
set.Each(func(v interface{}) bool {
|
||||
set.Each(func(v SemanticContext) bool {
|
||||
if c2, ok := v.(*PrecedencePredicate); ok {
|
||||
result = append(result, c2)
|
||||
}
|
||||
@ -193,21 +198,21 @@ type AND struct {
|
||||
|
||||
func NewAND(a, b SemanticContext) *AND {
|
||||
|
||||
operands := newArray2DHashSet(nil, nil)
|
||||
operands := NewJStore[SemanticContext, Comparator[SemanticContext]](semctxEqInst)
|
||||
if aa, ok := a.(*AND); ok {
|
||||
for _, o := range aa.opnds {
|
||||
operands.Add(o)
|
||||
operands.Put(o)
|
||||
}
|
||||
} else {
|
||||
operands.Add(a)
|
||||
operands.Put(a)
|
||||
}
|
||||
|
||||
if ba, ok := b.(*AND); ok {
|
||||
for _, o := range ba.opnds {
|
||||
operands.Add(o)
|
||||
operands.Put(o)
|
||||
}
|
||||
} else {
|
||||
operands.Add(b)
|
||||
operands.Put(b)
|
||||
}
|
||||
precedencePredicates := PrecedencePredicatefilterPrecedencePredicates(operands)
|
||||
if len(precedencePredicates) > 0 {
|
||||
@ -220,7 +225,7 @@ func NewAND(a, b SemanticContext) *AND {
|
||||
}
|
||||
}
|
||||
|
||||
operands.Add(reduced)
|
||||
operands.Put(reduced)
|
||||
}
|
||||
|
||||
vs := operands.Values()
|
||||
@ -235,14 +240,15 @@ func NewAND(a, b SemanticContext) *AND {
|
||||
return and
|
||||
}
|
||||
|
||||
func (a *AND) equals(other interface{}) bool {
|
||||
func (a *AND) Equals(other Collectable[SemanticContext]) bool {
|
||||
if a == other {
|
||||
return true
|
||||
} else if _, ok := other.(*AND); !ok {
|
||||
}
|
||||
if _, ok := other.(*AND); !ok {
|
||||
return false
|
||||
} else {
|
||||
for i, v := range other.(*AND).opnds {
|
||||
if !a.opnds[i].equals(v) {
|
||||
if !a.opnds[i].Equals(v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -250,13 +256,11 @@ func (a *AND) equals(other interface{}) bool {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// {@inheritDoc}
|
||||
//
|
||||
// <p>
|
||||
// The evaluation of predicates by a context is short-circuiting, but
|
||||
// unordered.</p>
|
||||
//
|
||||
func (a *AND) evaluate(parser Recognizer, outerContext RuleContext) bool {
|
||||
for i := 0; i < len(a.opnds); i++ {
|
||||
if !a.opnds[i].evaluate(parser, outerContext) {
|
||||
@ -304,18 +308,18 @@ func (a *AND) evalPrecedence(parser Recognizer, outerContext RuleContext) Semant
|
||||
return result
|
||||
}
|
||||
|
||||
func (a *AND) hash() int {
|
||||
func (a *AND) Hash() int {
|
||||
h := murmurInit(37) // Init with a value different from OR
|
||||
for _, op := range a.opnds {
|
||||
h = murmurUpdate(h, op.hash())
|
||||
h = murmurUpdate(h, op.Hash())
|
||||
}
|
||||
return murmurFinish(h, len(a.opnds))
|
||||
}
|
||||
|
||||
func (a *OR) hash() int {
|
||||
func (a *OR) Hash() int {
|
||||
h := murmurInit(41) // Init with a value different from AND
|
||||
for _, op := range a.opnds {
|
||||
h = murmurUpdate(h, op.hash())
|
||||
h = murmurUpdate(h, op.Hash())
|
||||
}
|
||||
return murmurFinish(h, len(a.opnds))
|
||||
}
|
||||
@ -345,21 +349,21 @@ type OR struct {
|
||||
|
||||
func NewOR(a, b SemanticContext) *OR {
|
||||
|
||||
operands := newArray2DHashSet(nil, nil)
|
||||
operands := NewJStore[SemanticContext, Comparator[SemanticContext]](semctxEqInst)
|
||||
if aa, ok := a.(*OR); ok {
|
||||
for _, o := range aa.opnds {
|
||||
operands.Add(o)
|
||||
operands.Put(o)
|
||||
}
|
||||
} else {
|
||||
operands.Add(a)
|
||||
operands.Put(a)
|
||||
}
|
||||
|
||||
if ba, ok := b.(*OR); ok {
|
||||
for _, o := range ba.opnds {
|
||||
operands.Add(o)
|
||||
operands.Put(o)
|
||||
}
|
||||
} else {
|
||||
operands.Add(b)
|
||||
operands.Put(b)
|
||||
}
|
||||
precedencePredicates := PrecedencePredicatefilterPrecedencePredicates(operands)
|
||||
if len(precedencePredicates) > 0 {
|
||||
@ -372,7 +376,7 @@ func NewOR(a, b SemanticContext) *OR {
|
||||
}
|
||||
}
|
||||
|
||||
operands.Add(reduced)
|
||||
operands.Put(reduced)
|
||||
}
|
||||
|
||||
vs := operands.Values()
|
||||
@ -388,14 +392,14 @@ func NewOR(a, b SemanticContext) *OR {
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *OR) equals(other interface{}) bool {
|
||||
func (o *OR) Equals(other Collectable[SemanticContext]) bool {
|
||||
if o == other {
|
||||
return true
|
||||
} else if _, ok := other.(*OR); !ok {
|
||||
return false
|
||||
} else {
|
||||
for i, v := range other.(*OR).opnds {
|
||||
if !o.opnds[i].equals(v) {
|
||||
if !o.opnds[i].Equals(v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -406,7 +410,6 @@ func (o *OR) equals(other interface{}) bool {
|
||||
// <p>
|
||||
// The evaluation of predicates by o context is short-circuiting, but
|
||||
// unordered.</p>
|
||||
//
|
||||
func (o *OR) evaluate(parser Recognizer, outerContext RuleContext) bool {
|
||||
for i := 0; i < len(o.opnds); i++ {
|
||||
if o.opnds[i].evaluate(parser, outerContext) {
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -158,7 +158,6 @@ func NewCommonToken(source *TokenSourceCharStreamPair, tokenType, channel, start
|
||||
// {@link Token//GetInputStream}.</p>
|
||||
//
|
||||
// @param oldToken The token to copy.
|
||||
//
|
||||
func (c *CommonToken) clone() *CommonToken {
|
||||
t := NewCommonToken(c.source, c.tokenType, c.channel, c.start, c.stop)
|
||||
t.tokenIndex = c.GetTokenIndex()
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,14 +1,14 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
package antlr
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
|
||||
//
|
||||
// Useful for rewriting out a buffered input token stream after doing some
|
||||
// augmentation or other manipulations on it.
|
||||
@ -85,12 +85,10 @@ import (
|
||||
// If you don't use named rewrite streams, a "default" stream is used as the
|
||||
// first example shows.</p>
|
||||
|
||||
|
||||
|
||||
const(
|
||||
const (
|
||||
Default_Program_Name = "default"
|
||||
Program_Init_Size = 100
|
||||
Min_Token_Index = 0
|
||||
Program_Init_Size = 100
|
||||
Min_Token_Index = 0
|
||||
)
|
||||
|
||||
// Define the rewrite operation hierarchy
|
||||
@ -98,13 +96,13 @@ const(
|
||||
type RewriteOperation interface {
|
||||
// Execute the rewrite operation by possibly adding to the buffer.
|
||||
// Return the index of the next token to operate on.
|
||||
Execute(buffer *bytes.Buffer) int
|
||||
String() string
|
||||
GetInstructionIndex() int
|
||||
GetIndex() int
|
||||
GetText() string
|
||||
GetOpName() string
|
||||
GetTokens() TokenStream
|
||||
Execute(buffer *bytes.Buffer) int
|
||||
String() string
|
||||
GetInstructionIndex() int
|
||||
GetIndex() int
|
||||
GetText() string
|
||||
GetOpName() string
|
||||
GetTokens() TokenStream
|
||||
SetInstructionIndex(val int)
|
||||
SetIndex(int)
|
||||
SetText(string)
|
||||
@ -114,63 +112,62 @@ type RewriteOperation interface {
|
||||
|
||||
type BaseRewriteOperation struct {
|
||||
//Current index of rewrites list
|
||||
instruction_index int
|
||||
instruction_index int
|
||||
//Token buffer index
|
||||
index int
|
||||
index int
|
||||
//Substitution text
|
||||
text string
|
||||
text string
|
||||
//Actual operation name
|
||||
op_name string
|
||||
op_name string
|
||||
//Pointer to token steam
|
||||
tokens TokenStream
|
||||
tokens TokenStream
|
||||
}
|
||||
|
||||
func (op *BaseRewriteOperation)GetInstructionIndex() int{
|
||||
func (op *BaseRewriteOperation) GetInstructionIndex() int {
|
||||
return op.instruction_index
|
||||
}
|
||||
|
||||
func (op *BaseRewriteOperation)GetIndex() int{
|
||||
func (op *BaseRewriteOperation) GetIndex() int {
|
||||
return op.index
|
||||
}
|
||||
|
||||
func (op *BaseRewriteOperation)GetText() string{
|
||||
func (op *BaseRewriteOperation) GetText() string {
|
||||
return op.text
|
||||
}
|
||||
|
||||
func (op *BaseRewriteOperation)GetOpName() string{
|
||||
func (op *BaseRewriteOperation) GetOpName() string {
|
||||
return op.op_name
|
||||
}
|
||||
|
||||
func (op *BaseRewriteOperation)GetTokens() TokenStream{
|
||||
func (op *BaseRewriteOperation) GetTokens() TokenStream {
|
||||
return op.tokens
|
||||
}
|
||||
|
||||
func (op *BaseRewriteOperation)SetInstructionIndex(val int){
|
||||
func (op *BaseRewriteOperation) SetInstructionIndex(val int) {
|
||||
op.instruction_index = val
|
||||
}
|
||||
|
||||
func (op *BaseRewriteOperation)SetIndex(val int) {
|
||||
func (op *BaseRewriteOperation) SetIndex(val int) {
|
||||
op.index = val
|
||||
}
|
||||
|
||||
func (op *BaseRewriteOperation)SetText(val string){
|
||||
func (op *BaseRewriteOperation) SetText(val string) {
|
||||
op.text = val
|
||||
}
|
||||
|
||||
func (op *BaseRewriteOperation)SetOpName(val string){
|
||||
func (op *BaseRewriteOperation) SetOpName(val string) {
|
||||
op.op_name = val
|
||||
}
|
||||
|
||||
func (op *BaseRewriteOperation)SetTokens(val TokenStream) {
|
||||
func (op *BaseRewriteOperation) SetTokens(val TokenStream) {
|
||||
op.tokens = val
|
||||
}
|
||||
|
||||
|
||||
func (op *BaseRewriteOperation) Execute(buffer *bytes.Buffer) int{
|
||||
func (op *BaseRewriteOperation) Execute(buffer *bytes.Buffer) int {
|
||||
return op.index
|
||||
}
|
||||
|
||||
func (op *BaseRewriteOperation) String() string {
|
||||
func (op *BaseRewriteOperation) String() string {
|
||||
return fmt.Sprintf("<%s@%d:\"%s\">",
|
||||
op.op_name,
|
||||
op.tokens.Get(op.GetIndex()),
|
||||
@ -179,26 +176,25 @@ func (op *BaseRewriteOperation) String() string {
|
||||
|
||||
}
|
||||
|
||||
|
||||
type InsertBeforeOp struct {
|
||||
BaseRewriteOperation
|
||||
}
|
||||
|
||||
func NewInsertBeforeOp(index int, text string, stream TokenStream) *InsertBeforeOp{
|
||||
return &InsertBeforeOp{BaseRewriteOperation:BaseRewriteOperation{
|
||||
index:index,
|
||||
text:text,
|
||||
op_name:"InsertBeforeOp",
|
||||
tokens:stream,
|
||||
func NewInsertBeforeOp(index int, text string, stream TokenStream) *InsertBeforeOp {
|
||||
return &InsertBeforeOp{BaseRewriteOperation: BaseRewriteOperation{
|
||||
index: index,
|
||||
text: text,
|
||||
op_name: "InsertBeforeOp",
|
||||
tokens: stream,
|
||||
}}
|
||||
}
|
||||
|
||||
func (op *InsertBeforeOp) Execute(buffer *bytes.Buffer) int{
|
||||
func (op *InsertBeforeOp) Execute(buffer *bytes.Buffer) int {
|
||||
buffer.WriteString(op.text)
|
||||
if op.tokens.Get(op.index).GetTokenType() != TokenEOF{
|
||||
if op.tokens.Get(op.index).GetTokenType() != TokenEOF {
|
||||
buffer.WriteString(op.tokens.Get(op.index).GetText())
|
||||
}
|
||||
return op.index+1
|
||||
return op.index + 1
|
||||
}
|
||||
|
||||
func (op *InsertBeforeOp) String() string {
|
||||
@ -213,20 +209,20 @@ type InsertAfterOp struct {
|
||||
BaseRewriteOperation
|
||||
}
|
||||
|
||||
func NewInsertAfterOp(index int, text string, stream TokenStream) *InsertAfterOp{
|
||||
return &InsertAfterOp{BaseRewriteOperation:BaseRewriteOperation{
|
||||
index:index+1,
|
||||
text:text,
|
||||
tokens:stream,
|
||||
func NewInsertAfterOp(index int, text string, stream TokenStream) *InsertAfterOp {
|
||||
return &InsertAfterOp{BaseRewriteOperation: BaseRewriteOperation{
|
||||
index: index + 1,
|
||||
text: text,
|
||||
tokens: stream,
|
||||
}}
|
||||
}
|
||||
|
||||
func (op *InsertAfterOp) Execute(buffer *bytes.Buffer) int {
|
||||
buffer.WriteString(op.text)
|
||||
if op.tokens.Get(op.index).GetTokenType() != TokenEOF{
|
||||
if op.tokens.Get(op.index).GetTokenType() != TokenEOF {
|
||||
buffer.WriteString(op.tokens.Get(op.index).GetText())
|
||||
}
|
||||
return op.index+1
|
||||
return op.index + 1
|
||||
}
|
||||
|
||||
func (op *InsertAfterOp) String() string {
|
||||
@ -235,28 +231,28 @@ func (op *InsertAfterOp) String() string {
|
||||
|
||||
// I'm going to try replacing range from x..y with (y-x)+1 ReplaceOp
|
||||
// instructions.
|
||||
type ReplaceOp struct{
|
||||
type ReplaceOp struct {
|
||||
BaseRewriteOperation
|
||||
LastIndex int
|
||||
}
|
||||
|
||||
func NewReplaceOp(from, to int, text string, stream TokenStream)*ReplaceOp {
|
||||
func NewReplaceOp(from, to int, text string, stream TokenStream) *ReplaceOp {
|
||||
return &ReplaceOp{
|
||||
BaseRewriteOperation:BaseRewriteOperation{
|
||||
index:from,
|
||||
text:text,
|
||||
op_name:"ReplaceOp",
|
||||
tokens:stream,
|
||||
BaseRewriteOperation: BaseRewriteOperation{
|
||||
index: from,
|
||||
text: text,
|
||||
op_name: "ReplaceOp",
|
||||
tokens: stream,
|
||||
},
|
||||
LastIndex:to,
|
||||
LastIndex: to,
|
||||
}
|
||||
}
|
||||
|
||||
func (op *ReplaceOp)Execute(buffer *bytes.Buffer) int{
|
||||
if op.text != ""{
|
||||
func (op *ReplaceOp) Execute(buffer *bytes.Buffer) int {
|
||||
if op.text != "" {
|
||||
buffer.WriteString(op.text)
|
||||
}
|
||||
return op.LastIndex +1
|
||||
return op.LastIndex + 1
|
||||
}
|
||||
|
||||
func (op *ReplaceOp) String() string {
|
||||
@ -268,54 +264,54 @@ func (op *ReplaceOp) String() string {
|
||||
op.tokens.Get(op.index), op.tokens.Get(op.LastIndex), op.text)
|
||||
}
|
||||
|
||||
|
||||
type TokenStreamRewriter struct {
|
||||
//Our source stream
|
||||
tokens TokenStream
|
||||
tokens TokenStream
|
||||
// You may have multiple, named streams of rewrite operations.
|
||||
// I'm calling these things "programs."
|
||||
// Maps String (name) → rewrite (List)
|
||||
programs map[string][]RewriteOperation
|
||||
last_rewrite_token_indexes map[string]int
|
||||
programs map[string][]RewriteOperation
|
||||
last_rewrite_token_indexes map[string]int
|
||||
}
|
||||
|
||||
func NewTokenStreamRewriter(tokens TokenStream) *TokenStreamRewriter{
|
||||
func NewTokenStreamRewriter(tokens TokenStream) *TokenStreamRewriter {
|
||||
return &TokenStreamRewriter{
|
||||
tokens: tokens,
|
||||
programs: map[string][]RewriteOperation{
|
||||
Default_Program_Name:make([]RewriteOperation,0, Program_Init_Size),
|
||||
tokens: tokens,
|
||||
programs: map[string][]RewriteOperation{
|
||||
Default_Program_Name: make([]RewriteOperation, 0, Program_Init_Size),
|
||||
},
|
||||
last_rewrite_token_indexes: map[string]int{},
|
||||
last_rewrite_token_indexes: map[string]int{},
|
||||
}
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter) GetTokenStream() TokenStream{
|
||||
func (tsr *TokenStreamRewriter) GetTokenStream() TokenStream {
|
||||
return tsr.tokens
|
||||
}
|
||||
|
||||
// Rollback the instruction stream for a program so that
|
||||
// the indicated instruction (via instructionIndex) is no
|
||||
// longer in the stream. UNTESTED!
|
||||
func (tsr *TokenStreamRewriter) Rollback(program_name string, instruction_index int){
|
||||
is, ok := tsr.programs[program_name]
|
||||
if ok{
|
||||
// Rollback the instruction stream for a program so that
|
||||
// the indicated instruction (via instructionIndex) is no
|
||||
// longer in the stream. UNTESTED!
|
||||
func (tsr *TokenStreamRewriter) Rollback(program_name string, instruction_index int) {
|
||||
is, ok := tsr.programs[program_name]
|
||||
if ok {
|
||||
tsr.programs[program_name] = is[Min_Token_Index:instruction_index]
|
||||
}
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter) RollbackDefault(instruction_index int){
|
||||
func (tsr *TokenStreamRewriter) RollbackDefault(instruction_index int) {
|
||||
tsr.Rollback(Default_Program_Name, instruction_index)
|
||||
}
|
||||
//Reset the program so that no instructions exist
|
||||
func (tsr *TokenStreamRewriter) DeleteProgram(program_name string){
|
||||
|
||||
// Reset the program so that no instructions exist
|
||||
func (tsr *TokenStreamRewriter) DeleteProgram(program_name string) {
|
||||
tsr.Rollback(program_name, Min_Token_Index) //TODO: double test on that cause lower bound is not included
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter) DeleteProgramDefault(){
|
||||
func (tsr *TokenStreamRewriter) DeleteProgramDefault() {
|
||||
tsr.DeleteProgram(Default_Program_Name)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter) InsertAfter(program_name string, index int, text string){
|
||||
func (tsr *TokenStreamRewriter) InsertAfter(program_name string, index int, text string) {
|
||||
// to insert after, just insert before next index (even if past end)
|
||||
var op RewriteOperation = NewInsertAfterOp(index, text, tsr.tokens)
|
||||
rewrites := tsr.GetProgram(program_name)
|
||||
@ -323,31 +319,31 @@ func (tsr *TokenStreamRewriter) InsertAfter(program_name string, index int, text
|
||||
tsr.AddToProgram(program_name, op)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter) InsertAfterDefault(index int, text string){
|
||||
func (tsr *TokenStreamRewriter) InsertAfterDefault(index int, text string) {
|
||||
tsr.InsertAfter(Default_Program_Name, index, text)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter) InsertAfterToken(program_name string, token Token, text string){
|
||||
func (tsr *TokenStreamRewriter) InsertAfterToken(program_name string, token Token, text string) {
|
||||
tsr.InsertAfter(program_name, token.GetTokenIndex(), text)
|
||||
}
|
||||
|
||||
func (tsr* TokenStreamRewriter) InsertBefore(program_name string, index int, text string){
|
||||
func (tsr *TokenStreamRewriter) InsertBefore(program_name string, index int, text string) {
|
||||
var op RewriteOperation = NewInsertBeforeOp(index, text, tsr.tokens)
|
||||
rewrites := tsr.GetProgram(program_name)
|
||||
op.SetInstructionIndex(len(rewrites))
|
||||
tsr.AddToProgram(program_name, op)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter) InsertBeforeDefault(index int, text string){
|
||||
func (tsr *TokenStreamRewriter) InsertBeforeDefault(index int, text string) {
|
||||
tsr.InsertBefore(Default_Program_Name, index, text)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter) InsertBeforeToken(program_name string,token Token, text string){
|
||||
func (tsr *TokenStreamRewriter) InsertBeforeToken(program_name string, token Token, text string) {
|
||||
tsr.InsertBefore(program_name, token.GetTokenIndex(), text)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter) Replace(program_name string, from, to int, text string){
|
||||
if from > to || from < 0 || to < 0 || to >= tsr.tokens.Size(){
|
||||
func (tsr *TokenStreamRewriter) Replace(program_name string, from, to int, text string) {
|
||||
if from > to || from < 0 || to < 0 || to >= tsr.tokens.Size() {
|
||||
panic(fmt.Sprintf("replace: range invalid: %d..%d(size=%d)",
|
||||
from, to, tsr.tokens.Size()))
|
||||
}
|
||||
@ -357,207 +353,216 @@ func (tsr *TokenStreamRewriter) Replace(program_name string, from, to int, text
|
||||
tsr.AddToProgram(program_name, op)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)ReplaceDefault(from, to int, text string) {
|
||||
func (tsr *TokenStreamRewriter) ReplaceDefault(from, to int, text string) {
|
||||
tsr.Replace(Default_Program_Name, from, to, text)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)ReplaceDefaultPos(index int, text string){
|
||||
func (tsr *TokenStreamRewriter) ReplaceDefaultPos(index int, text string) {
|
||||
tsr.ReplaceDefault(index, index, text)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)ReplaceToken(program_name string, from, to Token, text string){
|
||||
func (tsr *TokenStreamRewriter) ReplaceToken(program_name string, from, to Token, text string) {
|
||||
tsr.Replace(program_name, from.GetTokenIndex(), to.GetTokenIndex(), text)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)ReplaceTokenDefault(from, to Token, text string){
|
||||
func (tsr *TokenStreamRewriter) ReplaceTokenDefault(from, to Token, text string) {
|
||||
tsr.ReplaceToken(Default_Program_Name, from, to, text)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)ReplaceTokenDefaultPos(index Token, text string){
|
||||
func (tsr *TokenStreamRewriter) ReplaceTokenDefaultPos(index Token, text string) {
|
||||
tsr.ReplaceTokenDefault(index, index, text)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)Delete(program_name string, from, to int){
|
||||
tsr.Replace(program_name, from, to, "" )
|
||||
func (tsr *TokenStreamRewriter) Delete(program_name string, from, to int) {
|
||||
tsr.Replace(program_name, from, to, "")
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)DeleteDefault(from, to int){
|
||||
func (tsr *TokenStreamRewriter) DeleteDefault(from, to int) {
|
||||
tsr.Delete(Default_Program_Name, from, to)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)DeleteDefaultPos(index int){
|
||||
tsr.DeleteDefault(index,index)
|
||||
func (tsr *TokenStreamRewriter) DeleteDefaultPos(index int) {
|
||||
tsr.DeleteDefault(index, index)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)DeleteToken(program_name string, from, to Token) {
|
||||
func (tsr *TokenStreamRewriter) DeleteToken(program_name string, from, to Token) {
|
||||
tsr.ReplaceToken(program_name, from, to, "")
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)DeleteTokenDefault(from,to Token){
|
||||
func (tsr *TokenStreamRewriter) DeleteTokenDefault(from, to Token) {
|
||||
tsr.DeleteToken(Default_Program_Name, from, to)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)GetLastRewriteTokenIndex(program_name string)int {
|
||||
func (tsr *TokenStreamRewriter) GetLastRewriteTokenIndex(program_name string) int {
|
||||
i, ok := tsr.last_rewrite_token_indexes[program_name]
|
||||
if !ok{
|
||||
if !ok {
|
||||
return -1
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)GetLastRewriteTokenIndexDefault()int{
|
||||
func (tsr *TokenStreamRewriter) GetLastRewriteTokenIndexDefault() int {
|
||||
return tsr.GetLastRewriteTokenIndex(Default_Program_Name)
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)SetLastRewriteTokenIndex(program_name string, i int){
|
||||
func (tsr *TokenStreamRewriter) SetLastRewriteTokenIndex(program_name string, i int) {
|
||||
tsr.last_rewrite_token_indexes[program_name] = i
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)InitializeProgram(name string)[]RewriteOperation{
|
||||
func (tsr *TokenStreamRewriter) InitializeProgram(name string) []RewriteOperation {
|
||||
is := make([]RewriteOperation, 0, Program_Init_Size)
|
||||
tsr.programs[name] = is
|
||||
return is
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)AddToProgram(name string, op RewriteOperation){
|
||||
func (tsr *TokenStreamRewriter) AddToProgram(name string, op RewriteOperation) {
|
||||
is := tsr.GetProgram(name)
|
||||
is = append(is, op)
|
||||
tsr.programs[name] = is
|
||||
}
|
||||
|
||||
func (tsr *TokenStreamRewriter)GetProgram(name string) []RewriteOperation {
|
||||
func (tsr *TokenStreamRewriter) GetProgram(name string) []RewriteOperation {
|
||||
is, ok := tsr.programs[name]
|
||||
if !ok{
|
||||
if !ok {
|
||||
is = tsr.InitializeProgram(name)
|
||||
}
|
||||
return is
|
||||
}
|
||||
// Return the text from the original tokens altered per the
|
||||
// instructions given to this rewriter.
|
||||
func (tsr *TokenStreamRewriter)GetTextDefault() string{
|
||||
|
||||
// Return the text from the original tokens altered per the
|
||||
// instructions given to this rewriter.
|
||||
func (tsr *TokenStreamRewriter) GetTextDefault() string {
|
||||
return tsr.GetText(
|
||||
Default_Program_Name,
|
||||
NewInterval(0, tsr.tokens.Size()-1))
|
||||
}
|
||||
// Return the text from the original tokens altered per the
|
||||
// instructions given to this rewriter.
|
||||
func (tsr *TokenStreamRewriter)GetText(program_name string, interval *Interval) string {
|
||||
|
||||
// Return the text from the original tokens altered per the
|
||||
// instructions given to this rewriter.
|
||||
func (tsr *TokenStreamRewriter) GetText(program_name string, interval *Interval) string {
|
||||
rewrites := tsr.programs[program_name]
|
||||
start := interval.Start
|
||||
stop := interval.Stop
|
||||
stop := interval.Stop
|
||||
// ensure start/end are in range
|
||||
stop = min(stop, tsr.tokens.Size()-1)
|
||||
start = max(start,0)
|
||||
if rewrites == nil || len(rewrites) == 0{
|
||||
start = max(start, 0)
|
||||
if rewrites == nil || len(rewrites) == 0 {
|
||||
return tsr.tokens.GetTextFromInterval(interval) // no instructions to execute
|
||||
}
|
||||
buf := bytes.Buffer{}
|
||||
// First, optimize instruction stream
|
||||
indexToOp := reduceToSingleOperationPerIndex(rewrites)
|
||||
// Walk buffer, executing instructions and emitting tokens
|
||||
for i:=start; i<=stop && i<tsr.tokens.Size();{
|
||||
for i := start; i <= stop && i < tsr.tokens.Size(); {
|
||||
op := indexToOp[i]
|
||||
delete(indexToOp, i)// remove so any left have index size-1
|
||||
delete(indexToOp, i) // remove so any left have index size-1
|
||||
t := tsr.tokens.Get(i)
|
||||
if op == nil{
|
||||
if op == nil {
|
||||
// no operation at that index, just dump token
|
||||
if t.GetTokenType() != TokenEOF {buf.WriteString(t.GetText())}
|
||||
if t.GetTokenType() != TokenEOF {
|
||||
buf.WriteString(t.GetText())
|
||||
}
|
||||
i++ // move to next token
|
||||
}else {
|
||||
i = op.Execute(&buf)// execute operation and skip
|
||||
} else {
|
||||
i = op.Execute(&buf) // execute operation and skip
|
||||
}
|
||||
}
|
||||
// include stuff after end if it's last index in buffer
|
||||
// So, if they did an insertAfter(lastValidIndex, "foo"), include
|
||||
// foo if end==lastValidIndex.
|
||||
if stop == tsr.tokens.Size()-1{
|
||||
if stop == tsr.tokens.Size()-1 {
|
||||
// Scan any remaining operations after last token
|
||||
// should be included (they will be inserts).
|
||||
for _, op := range indexToOp{
|
||||
if op.GetIndex() >= tsr.tokens.Size()-1 {buf.WriteString(op.GetText())}
|
||||
for _, op := range indexToOp {
|
||||
if op.GetIndex() >= tsr.tokens.Size()-1 {
|
||||
buf.WriteString(op.GetText())
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// We need to combine operations and report invalid operations (like
|
||||
// overlapping replaces that are not completed nested). Inserts to
|
||||
// same index need to be combined etc... Here are the cases:
|
||||
// We need to combine operations and report invalid operations (like
|
||||
// overlapping replaces that are not completed nested). Inserts to
|
||||
// same index need to be combined etc... Here are the cases:
|
||||
//
|
||||
// I.i.u I.j.v leave alone, nonoverlapping
|
||||
// I.i.u I.i.v combine: Iivu
|
||||
// I.i.u I.j.v leave alone, nonoverlapping
|
||||
// I.i.u I.i.v combine: Iivu
|
||||
//
|
||||
// R.i-j.u R.x-y.v | i-j in x-y delete first R
|
||||
// R.i-j.u R.i-j.v delete first R
|
||||
// R.i-j.u R.x-y.v | x-y in i-j ERROR
|
||||
// R.i-j.u R.x-y.v | boundaries overlap ERROR
|
||||
// R.i-j.u R.x-y.v | i-j in x-y delete first R
|
||||
// R.i-j.u R.i-j.v delete first R
|
||||
// R.i-j.u R.x-y.v | x-y in i-j ERROR
|
||||
// R.i-j.u R.x-y.v | boundaries overlap ERROR
|
||||
//
|
||||
// Delete special case of replace (text==null):
|
||||
// D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right)
|
||||
// Delete special case of replace (text==null):
|
||||
// D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right)
|
||||
//
|
||||
// I.i.u R.x-y.v | i in (x+1)-y delete I (since insert before
|
||||
// we're not deleting i)
|
||||
// I.i.u R.x-y.v | i not in (x+1)-y leave alone, nonoverlapping
|
||||
// R.x-y.v I.i.u | i in x-y ERROR
|
||||
// R.x-y.v I.x.u R.x-y.uv (combine, delete I)
|
||||
// R.x-y.v I.i.u | i not in x-y leave alone, nonoverlapping
|
||||
// I.i.u R.x-y.v | i in (x+1)-y delete I (since insert before
|
||||
// we're not deleting i)
|
||||
// I.i.u R.x-y.v | i not in (x+1)-y leave alone, nonoverlapping
|
||||
// R.x-y.v I.i.u | i in x-y ERROR
|
||||
// R.x-y.v I.x.u R.x-y.uv (combine, delete I)
|
||||
// R.x-y.v I.i.u | i not in x-y leave alone, nonoverlapping
|
||||
//
|
||||
// I.i.u = insert u before op @ index i
|
||||
// R.x-y.u = replace x-y indexed tokens with u
|
||||
// I.i.u = insert u before op @ index i
|
||||
// R.x-y.u = replace x-y indexed tokens with u
|
||||
//
|
||||
// First we need to examine replaces. For any replace op:
|
||||
// First we need to examine replaces. For any replace op:
|
||||
//
|
||||
// 1. wipe out any insertions before op within that range.
|
||||
// 2. Drop any replace op before that is contained completely within
|
||||
// that range.
|
||||
// 3. Throw exception upon boundary overlap with any previous replace.
|
||||
// 1. wipe out any insertions before op within that range.
|
||||
// 2. Drop any replace op before that is contained completely within
|
||||
// that range.
|
||||
// 3. Throw exception upon boundary overlap with any previous replace.
|
||||
//
|
||||
// Then we can deal with inserts:
|
||||
// Then we can deal with inserts:
|
||||
//
|
||||
// 1. for any inserts to same index, combine even if not adjacent.
|
||||
// 2. for any prior replace with same left boundary, combine this
|
||||
// insert with replace and delete this replace.
|
||||
// 3. throw exception if index in same range as previous replace
|
||||
// 1. for any inserts to same index, combine even if not adjacent.
|
||||
// 2. for any prior replace with same left boundary, combine this
|
||||
// insert with replace and delete this replace.
|
||||
// 3. throw exception if index in same range as previous replace
|
||||
//
|
||||
// Don't actually delete; make op null in list. Easier to walk list.
|
||||
// Later we can throw as we add to index → op map.
|
||||
// Don't actually delete; make op null in list. Easier to walk list.
|
||||
// Later we can throw as we add to index → op map.
|
||||
//
|
||||
// Note that I.2 R.2-2 will wipe out I.2 even though, technically, the
|
||||
// inserted stuff would be before the replace range. But, if you
|
||||
// add tokens in front of a method body '{' and then delete the method
|
||||
// body, I think the stuff before the '{' you added should disappear too.
|
||||
// Note that I.2 R.2-2 will wipe out I.2 even though, technically, the
|
||||
// inserted stuff would be before the replace range. But, if you
|
||||
// add tokens in front of a method body '{' and then delete the method
|
||||
// body, I think the stuff before the '{' you added should disappear too.
|
||||
//
|
||||
// Return a map from token index to operation.
|
||||
//
|
||||
func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]RewriteOperation{
|
||||
// Return a map from token index to operation.
|
||||
func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]RewriteOperation {
|
||||
// WALK REPLACES
|
||||
for i:=0; i < len(rewrites); i++{
|
||||
for i := 0; i < len(rewrites); i++ {
|
||||
op := rewrites[i]
|
||||
if op == nil{continue}
|
||||
if op == nil {
|
||||
continue
|
||||
}
|
||||
rop, ok := op.(*ReplaceOp)
|
||||
if !ok{continue}
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
// Wipe prior inserts within range
|
||||
for j:=0; j<i && j < len(rewrites); j++{
|
||||
if iop, ok := rewrites[j].(*InsertBeforeOp);ok{
|
||||
if iop.index == rop.index{
|
||||
for j := 0; j < i && j < len(rewrites); j++ {
|
||||
if iop, ok := rewrites[j].(*InsertBeforeOp); ok {
|
||||
if iop.index == rop.index {
|
||||
// E.g., insert before 2, delete 2..2; update replace
|
||||
// text to include insert before, kill insert
|
||||
rewrites[iop.instruction_index] = nil
|
||||
if rop.text != ""{
|
||||
if rop.text != "" {
|
||||
rop.text = iop.text + rop.text
|
||||
}else{
|
||||
} else {
|
||||
rop.text = iop.text
|
||||
}
|
||||
}else if iop.index > rop.index && iop.index <=rop.LastIndex{
|
||||
} else if iop.index > rop.index && iop.index <= rop.LastIndex {
|
||||
// delete insert as it's a no-op.
|
||||
rewrites[iop.instruction_index] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
// Drop any prior replaces contained within
|
||||
for j:=0; j<i && j < len(rewrites); j++{
|
||||
if prevop, ok := rewrites[j].(*ReplaceOp);ok{
|
||||
if prevop.index>=rop.index && prevop.LastIndex <= rop.LastIndex{
|
||||
for j := 0; j < i && j < len(rewrites); j++ {
|
||||
if prevop, ok := rewrites[j].(*ReplaceOp); ok {
|
||||
if prevop.index >= rop.index && prevop.LastIndex <= rop.LastIndex {
|
||||
// delete replace as it's a no-op.
|
||||
rewrites[prevop.instruction_index] = nil
|
||||
continue
|
||||
@ -566,61 +571,67 @@ func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]Rewrit
|
||||
disjoint := prevop.LastIndex < rop.index || prevop.index > rop.LastIndex
|
||||
// Delete special case of replace (text==null):
|
||||
// D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right)
|
||||
if prevop.text == "" && rop.text == "" && !disjoint{
|
||||
if prevop.text == "" && rop.text == "" && !disjoint {
|
||||
rewrites[prevop.instruction_index] = nil
|
||||
rop.index = min(prevop.index, rop.index)
|
||||
rop.LastIndex = max(prevop.LastIndex, rop.LastIndex)
|
||||
println("new rop" + rop.String()) //TODO: remove console write, taken from Java version
|
||||
}else if !disjoint{
|
||||
} else if !disjoint {
|
||||
panic("replace op boundaries of " + rop.String() + " overlap with previous " + prevop.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// WALK INSERTS
|
||||
for i:=0; i < len(rewrites); i++ {
|
||||
for i := 0; i < len(rewrites); i++ {
|
||||
op := rewrites[i]
|
||||
if op == nil{continue}
|
||||
if op == nil {
|
||||
continue
|
||||
}
|
||||
//hack to replicate inheritance in composition
|
||||
_, iok := rewrites[i].(*InsertBeforeOp)
|
||||
_, aok := rewrites[i].(*InsertAfterOp)
|
||||
if !iok && !aok{continue}
|
||||
if !iok && !aok {
|
||||
continue
|
||||
}
|
||||
iop := rewrites[i]
|
||||
// combine current insert with prior if any at same index
|
||||
// deviating a bit from TokenStreamRewriter.java - hard to incorporate inheritance logic
|
||||
for j:=0; j<i && j < len(rewrites); j++{
|
||||
if nextIop, ok := rewrites[j].(*InsertAfterOp); ok{
|
||||
if nextIop.index == iop.GetIndex(){
|
||||
for j := 0; j < i && j < len(rewrites); j++ {
|
||||
if nextIop, ok := rewrites[j].(*InsertAfterOp); ok {
|
||||
if nextIop.index == iop.GetIndex() {
|
||||
iop.SetText(nextIop.text + iop.GetText())
|
||||
rewrites[j] = nil
|
||||
}
|
||||
}
|
||||
if prevIop, ok := rewrites[j].(*InsertBeforeOp); ok{
|
||||
if prevIop.index == iop.GetIndex(){
|
||||
if prevIop, ok := rewrites[j].(*InsertBeforeOp); ok {
|
||||
if prevIop.index == iop.GetIndex() {
|
||||
iop.SetText(iop.GetText() + prevIop.text)
|
||||
rewrites[prevIop.instruction_index] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
// look for replaces where iop.index is in range; error
|
||||
for j:=0; j<i && j < len(rewrites); j++{
|
||||
if rop,ok := rewrites[j].(*ReplaceOp); ok{
|
||||
if iop.GetIndex() == rop.index{
|
||||
for j := 0; j < i && j < len(rewrites); j++ {
|
||||
if rop, ok := rewrites[j].(*ReplaceOp); ok {
|
||||
if iop.GetIndex() == rop.index {
|
||||
rop.text = iop.GetText() + rop.text
|
||||
rewrites[i] = nil
|
||||
continue
|
||||
}
|
||||
if iop.GetIndex() >= rop.index && iop.GetIndex() <= rop.LastIndex{
|
||||
panic("insert op "+iop.String()+" within boundaries of previous "+rop.String())
|
||||
if iop.GetIndex() >= rop.index && iop.GetIndex() <= rop.LastIndex {
|
||||
panic("insert op " + iop.String() + " within boundaries of previous " + rop.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m := map[int]RewriteOperation{}
|
||||
for i:=0; i < len(rewrites); i++{
|
||||
for i := 0; i < len(rewrites); i++ {
|
||||
op := rewrites[i]
|
||||
if op == nil {continue}
|
||||
if _, ok := m[op.GetIndex()]; ok{
|
||||
if op == nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := m[op.GetIndex()]; ok {
|
||||
panic("should only be one op per index")
|
||||
}
|
||||
m[op.GetIndex()] = op
|
||||
@ -628,22 +639,21 @@ func reduceToSingleOperationPerIndex(rewrites []RewriteOperation) map[int]Rewrit
|
||||
return m
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Quick fixing Go lack of overloads
|
||||
*/
|
||||
*/
|
||||
|
||||
func max(a,b int)int{
|
||||
if a>b{
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}else {
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
||||
func min(a,b int)int{
|
||||
if a<b{
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}else {
|
||||
} else {
|
||||
return b
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -234,10 +234,8 @@ func (p *ParseTreeWalker) Walk(listener ParseTreeListener, t Tree) {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Enters a grammar rule by first triggering the generic event {@link ParseTreeListener//EnterEveryRule}
|
||||
// then by triggering the event specific to the given parse tree node
|
||||
//
|
||||
func (p *ParseTreeWalker) EnterRule(listener ParseTreeListener, r RuleNode) {
|
||||
ctx := r.GetRuleContext().(ParserRuleContext)
|
||||
listener.EnterEveryRule(ctx)
|
||||
@ -246,7 +244,6 @@ func (p *ParseTreeWalker) EnterRule(listener ParseTreeListener, r RuleNode) {
|
||||
|
||||
// Exits a grammar rule by first triggering the event specific to the given parse tree node
|
||||
// then by triggering the generic event {@link ParseTreeListener//ExitEveryRule}
|
||||
//
|
||||
func (p *ParseTreeWalker) ExitRule(listener ParseTreeListener, r RuleNode) {
|
||||
ctx := r.GetRuleContext().(ParserRuleContext)
|
||||
ctx.ExitRule(listener)
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -9,8 +9,9 @@ import "fmt"
|
||||
/** A set of utility routines useful for all kinds of ANTLR trees. */
|
||||
|
||||
// Print out a whole tree in LISP form. {@link //getNodeText} is used on the
|
||||
// node payloads to get the text for the nodes. Detect
|
||||
// parse trees and extract data appropriately.
|
||||
//
|
||||
// node payloads to get the text for the nodes. Detect
|
||||
// parse trees and extract data appropriately.
|
||||
func TreesStringTree(tree Tree, ruleNames []string, recog Recognizer) string {
|
||||
|
||||
if recog != nil {
|
||||
@ -80,8 +81,8 @@ func TreesGetChildren(t Tree) []Tree {
|
||||
}
|
||||
|
||||
// Return a list of all ancestors of this node. The first node of
|
||||
// list is the root and the last is the parent of this node.
|
||||
//
|
||||
// list is the root and the last is the parent of this node.
|
||||
func TreesgetAncestors(t Tree) []Tree {
|
||||
ancestors := make([]Tree, 0)
|
||||
t = t.GetParent()
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
||||
// Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
|
||||
// Use of this file is governed by the BSD 3-clause license that
|
||||
// can be found in the LICENSE.txt file in the project root.
|
||||
|
||||
@ -47,28 +47,25 @@ func (s *IntStack) Push(e int) {
|
||||
*s = append(*s, e)
|
||||
}
|
||||
|
||||
func standardEqualsFunction(a interface{}, b interface{}) bool {
|
||||
type comparable interface {
|
||||
Equals(other Collectable[any]) bool
|
||||
}
|
||||
|
||||
ac, oka := a.(comparable)
|
||||
bc, okb := b.(comparable)
|
||||
func standardEqualsFunction(a Collectable[any], b Collectable[any]) bool {
|
||||
|
||||
if !oka || !okb {
|
||||
panic("Not Comparable")
|
||||
}
|
||||
|
||||
return ac.equals(bc)
|
||||
return a.Equals(b)
|
||||
}
|
||||
|
||||
func standardHashFunction(a interface{}) int {
|
||||
if h, ok := a.(hasher); ok {
|
||||
return h.hash()
|
||||
return h.Hash()
|
||||
}
|
||||
|
||||
panic("Not Hasher")
|
||||
}
|
||||
|
||||
type hasher interface {
|
||||
hash() int
|
||||
Hash() int
|
||||
}
|
||||
|
||||
const bitsPerWord = 64
|
||||
@ -171,7 +168,7 @@ func (b *BitSet) equals(other interface{}) bool {
|
||||
|
||||
// We only compare set bits, so we cannot rely on the two slices having the same size. Its
|
||||
// possible for two BitSets to have different slice lengths but the same set bits. So we only
|
||||
// compare the relavent words and ignore the trailing zeros.
|
||||
// compare the relevant words and ignore the trailing zeros.
|
||||
bLen := b.minLen()
|
||||
otherLen := otherBitSet.minLen()
|
||||
|
@ -8,8 +8,6 @@ const (
|
||||
_loadFactor = 0.75
|
||||
)
|
||||
|
||||
var _ Set = (*array2DHashSet)(nil)
|
||||
|
||||
type Set interface {
|
||||
Add(value interface{}) (added interface{})
|
||||
Len() int
|
||||
@ -20,9 +18,9 @@ type Set interface {
|
||||
}
|
||||
|
||||
type array2DHashSet struct {
|
||||
buckets [][]interface{}
|
||||
buckets [][]Collectable[any]
|
||||
hashcodeFunction func(interface{}) int
|
||||
equalsFunction func(interface{}, interface{}) bool
|
||||
equalsFunction func(Collectable[any], Collectable[any]) bool
|
||||
|
||||
n int // How many elements in set
|
||||
threshold int // when to expand
|
||||
@ -61,11 +59,11 @@ func (as *array2DHashSet) Values() []interface{} {
|
||||
return values
|
||||
}
|
||||
|
||||
func (as *array2DHashSet) Contains(value interface{}) bool {
|
||||
func (as *array2DHashSet) Contains(value Collectable[any]) bool {
|
||||
return as.Get(value) != nil
|
||||
}
|
||||
|
||||
func (as *array2DHashSet) Add(value interface{}) interface{} {
|
||||
func (as *array2DHashSet) Add(value Collectable[any]) interface{} {
|
||||
if as.n > as.threshold {
|
||||
as.expand()
|
||||
}
|
||||
@ -98,7 +96,7 @@ func (as *array2DHashSet) expand() {
|
||||
|
||||
b := as.getBuckets(o)
|
||||
bucketLength := newBucketLengths[b]
|
||||
var newBucket []interface{}
|
||||
var newBucket []Collectable[any]
|
||||
if bucketLength == 0 {
|
||||
// new bucket
|
||||
newBucket = as.createBucket(as.initialBucketCapacity)
|
||||
@ -107,7 +105,7 @@ func (as *array2DHashSet) expand() {
|
||||
newBucket = newTable[b]
|
||||
if bucketLength == len(newBucket) {
|
||||
// expand
|
||||
newBucketCopy := make([]interface{}, len(newBucket)<<1)
|
||||
newBucketCopy := make([]Collectable[any], len(newBucket)<<1)
|
||||
copy(newBucketCopy[:bucketLength], newBucket)
|
||||
newBucket = newBucketCopy
|
||||
newTable[b] = newBucket
|
||||
@ -124,7 +122,7 @@ func (as *array2DHashSet) Len() int {
|
||||
return as.n
|
||||
}
|
||||
|
||||
func (as *array2DHashSet) Get(o interface{}) interface{} {
|
||||
func (as *array2DHashSet) Get(o Collectable[any]) interface{} {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
@ -147,7 +145,7 @@ func (as *array2DHashSet) Get(o interface{}) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (as *array2DHashSet) innerAdd(o interface{}) interface{} {
|
||||
func (as *array2DHashSet) innerAdd(o Collectable[any]) interface{} {
|
||||
b := as.getBuckets(o)
|
||||
|
||||
bucket := as.buckets[b]
|
||||
@ -178,7 +176,7 @@ func (as *array2DHashSet) innerAdd(o interface{}) interface{} {
|
||||
|
||||
// full bucket, expand and add to end
|
||||
oldLength := len(bucket)
|
||||
bucketCopy := make([]interface{}, oldLength<<1)
|
||||
bucketCopy := make([]Collectable[any], oldLength<<1)
|
||||
copy(bucketCopy[:oldLength], bucket)
|
||||
bucket = bucketCopy
|
||||
as.buckets[b] = bucket
|
||||
@ -187,22 +185,22 @@ func (as *array2DHashSet) innerAdd(o interface{}) interface{} {
|
||||
return o
|
||||
}
|
||||
|
||||
func (as *array2DHashSet) getBuckets(value interface{}) int {
|
||||
func (as *array2DHashSet) getBuckets(value Collectable[any]) int {
|
||||
hash := as.hashcodeFunction(value)
|
||||
return hash & (len(as.buckets) - 1)
|
||||
}
|
||||
|
||||
func (as *array2DHashSet) createBuckets(cap int) [][]interface{} {
|
||||
return make([][]interface{}, cap)
|
||||
func (as *array2DHashSet) createBuckets(cap int) [][]Collectable[any] {
|
||||
return make([][]Collectable[any], cap)
|
||||
}
|
||||
|
||||
func (as *array2DHashSet) createBucket(cap int) []interface{} {
|
||||
return make([]interface{}, cap)
|
||||
func (as *array2DHashSet) createBucket(cap int) []Collectable[any] {
|
||||
return make([]Collectable[any], cap)
|
||||
}
|
||||
|
||||
func newArray2DHashSetWithCap(
|
||||
hashcodeFunction func(interface{}) int,
|
||||
equalsFunction func(interface{}, interface{}) bool,
|
||||
equalsFunction func(Collectable[any], Collectable[any]) bool,
|
||||
initCap int,
|
||||
initBucketCap int,
|
||||
) *array2DHashSet {
|
||||
@ -231,7 +229,7 @@ func newArray2DHashSetWithCap(
|
||||
|
||||
func newArray2DHashSet(
|
||||
hashcodeFunction func(interface{}) int,
|
||||
equalsFunction func(interface{}, interface{}) bool,
|
||||
equalsFunction func(Collectable[any], Collectable[any]) bool,
|
||||
) *array2DHashSet {
|
||||
return newArray2DHashSetWithCap(hashcodeFunction, equalsFunction, _initalCapacity, _initalBucketCapacity)
|
||||
}
|
2
vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go
generated
vendored
@ -3,4 +3,4 @@
|
||||
package aws
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.20.0"
|
||||
const goModuleVersion = "1.21.0"
|
||||
|
13
vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/object.go
generated
vendored
13
vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/object.go
generated
vendored
@ -41,6 +41,12 @@ func (o *Object) Key(name string) Value {
|
||||
return o.key(name, false)
|
||||
}
|
||||
|
||||
// KeyWithValues adds the given named key to the Query object.
|
||||
// Returns a Value encoder that should be used to encode a Query list of values.
|
||||
func (o *Object) KeyWithValues(name string) Value {
|
||||
return o.keyWithValues(name, false)
|
||||
}
|
||||
|
||||
// FlatKey adds the given named key to the Query object.
|
||||
// Returns a Value encoder that should be used to encode a Query value type. The
|
||||
// value will be flattened if it is a map or array.
|
||||
@ -54,3 +60,10 @@ func (o *Object) key(name string, flatValue bool) Value {
|
||||
}
|
||||
return newValue(o.values, name, flatValue)
|
||||
}
|
||||
|
||||
func (o *Object) keyWithValues(name string, flatValue bool) Value {
|
||||
if o.prefix != "" {
|
||||
return newAppendValue(o.values, fmt.Sprintf("%s.%s", o.prefix, name), flatValue)
|
||||
}
|
||||
return newAppendValue(o.values, name, flatValue)
|
||||
}
|
||||
|
9
vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/value.go
generated
vendored
9
vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/value.go
generated
vendored
@ -27,6 +27,15 @@ func newValue(values url.Values, key string, flat bool) Value {
|
||||
}
|
||||
}
|
||||
|
||||
func newAppendValue(values url.Values, key string, flat bool) Value {
|
||||
return Value{
|
||||
values: values,
|
||||
key: key,
|
||||
flat: flat,
|
||||
queryValue: httpbinding.NewQueryValue(values, key, true),
|
||||
}
|
||||
}
|
||||
|
||||
func newBaseValue(values url.Values) Value {
|
||||
return Value{
|
||||
values: values,
|
||||
|
1
vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/headers.go
generated
vendored
1
vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/headers.go
generated
vendored
@ -48,6 +48,7 @@ var RequiredSignedHeaders = Rules{
|
||||
"X-Amz-Request-Payer": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Context": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Customer-Key": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
||||
|
16
vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md
generated
vendored
16
vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md
generated
vendored
@ -1,3 +1,19 @@
|
||||
# v1.1.41 (2023-08-21)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.1.40 (2023-08-18)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.1.39 (2023-08-17)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.1.38 (2023-08-07)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.1.37 (2023-07-31)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
2
vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go
generated
vendored
@ -3,4 +3,4 @@
|
||||
package configsources
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.1.37"
|
||||
const goModuleVersion = "1.1.41"
|
||||
|
5
vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json
generated
vendored
5
vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json
generated
vendored
@ -8,7 +8,7 @@
|
||||
"supportsDualStack" : true,
|
||||
"supportsFIPS" : true
|
||||
},
|
||||
"regionRegex" : "^(us|eu|ap|sa|ca|me|af)\\-\\w+\\-\\d+$",
|
||||
"regionRegex" : "^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$",
|
||||
"regions" : {
|
||||
"af-south-1" : {
|
||||
"description" : "Africa (Cape Town)"
|
||||
@ -73,6 +73,9 @@
|
||||
"eu-west-3" : {
|
||||
"description" : "Europe (Paris)"
|
||||
},
|
||||
"il-central-1" : {
|
||||
"description" : "Israel (Tel Aviv)"
|
||||
},
|
||||
"me-central-1" : {
|
||||
"description" : "Middle East (UAE)"
|
||||
},
|
||||
|
16
vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md
generated
vendored
16
vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md
generated
vendored
@ -1,3 +1,19 @@
|
||||
# v2.4.35 (2023-08-21)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v2.4.34 (2023-08-18)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v2.4.33 (2023-08-17)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v2.4.32 (2023-08-07)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v2.4.31 (2023-07-31)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
2
vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go
generated
vendored
@ -3,4 +3,4 @@
|
||||
package endpoints
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "2.4.31"
|
||||
const goModuleVersion = "2.4.35"
|
||||
|
16
vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md
generated
vendored
16
vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md
generated
vendored
@ -1,3 +1,19 @@
|
||||
# v1.9.35 (2023-08-21)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.9.34 (2023-08-18)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.9.33 (2023-08-17)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.9.32 (2023-08-07)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.9.31 (2023-07-31)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
@ -3,4 +3,4 @@
|
||||
package presignedurl
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.9.31"
|
||||
const goModuleVersion = "1.9.35"
|
||||
|
20
vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md
generated
vendored
20
vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md
generated
vendored
@ -1,3 +1,23 @@
|
||||
# v1.21.5 (2023-08-21)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.21.4 (2023-08-18)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.21.3 (2023-08-17)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.21.2 (2023-08-07)
|
||||
|
||||
* **Dependency Update**: Updated to the latest SDK module versions
|
||||
|
||||
# v1.21.1 (2023-08-01)
|
||||
|
||||
* No change notes available for this release.
|
||||
|
||||
# v1.21.0 (2023-07-31)
|
||||
|
||||
* **Feature**: Adds support for smithy-modeled endpoint resolution. A new rules-based endpoint resolution will be added to the SDK which will supercede and deprecate existing endpoint resolution. Specifically, EndpointResolver will be deprecated while BaseEndpoint and EndpointResolverV2 will take its place. For more information, please see the Endpoints section in our Developer Guide.
|
||||
|
2
vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go
generated
vendored
@ -3,4 +3,4 @@
|
||||
package sts
|
||||
|
||||
// goModuleVersion is the tagged release for this module
|
||||
const goModuleVersion = "1.21.0"
|
||||
const goModuleVersion = "1.21.5"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user